TL; DR
- переменные, определенные с
def
в основном теле скрипта, недоступны из других методов. - переменные определены без
def
можно получить доступ любым способом, даже из разных скриптов.Это плохая практика. - переменные, определенные с
def
и @Field
, могут быть доступны напрямую из методов, определенных в той же самойscript.
Объяснение
Когда groovy компилирует этот скрипт, он фактически перемещает все в класс, который примерно выглядит примерно так
class Script1 {
def pr() {
def another_var = "another " + some_var
echo "${another_var}"
}
def run() {
def some_var = "some value"
pipeline {
agent any
stages {
stage ("Run") {
steps {
pr()
}
}
}
}
}
}
Вы можете видеть, что some_var
явно выходит за рамки pr()
, потому что это локальная переменная в другом методе.
Когда вы определяете переменную без def
, вы на самом делепоместите эту переменную в Binding скрипта (так называемые Binding переменные ).Поэтому, когда groovy выполняет метод pr()
, сначала он пытается найти локальную переменную с именем some_var
, а если она не существует, он пытается найти эту переменную в привязке (которая существует, потому что вы определили ее без def
).
Переменные привязки считаются плохой практикой, поскольку при загрузке нескольких сценариев (шаг load
) переменные привязки будут доступны во всех этих сценариях, поскольку Jenkins использует одну и ту же привязку для всех сценариев.Гораздо лучшая альтернатива - использовать аннотацию @Field
.Таким образом, вы можете сделать переменную доступной во всех методах внутри одного скрипта, не подвергая ее другим скриптам.
import groovy.transform.Field
@Field
def some_var = "some value"
def pr() {
def another_var = "another " + some_var
echo "${another_var}"
}
//your pipeline
Когда groovy компилирует этот скрипт в класс, он будет выглядеть примерно так
class Script1 {
def some_var = "some value"
def pr() {
def another_var = "another " + some_var
echo "${another_var}"
}
def run() {
//your pipeline
}
}