Чтобы объяснить , почему такое происходит, лучше всего обратиться к исходному коду Jenkins.
Имя глобальной переменной - env
, что приводит нас к * 1007.*.Это связывает значение со сценарием, который в данном случае является конвейером.
Исходный код :
@Override public EnvActionImpl getValue(CpsScript script) throws Exception {
Run<?,?> run = script.$build();
if (run != null) {
return EnvActionImpl.forRun(run);
} else {
throw new IllegalStateException("no associated build");
}
}
EnvActionImpl
расширяет тип Groovy GroovyObjectSupport
(исходный код) .GroovyObjectSupport
имеет это в своей документации:
Полезный базовый класс для объектов Java, желающих быть объектами Groovy
Итак, это Дженкинс позволяет реализации JavaПозвольте ему установить его поведение для Groovy.Методы, которые вы используете, это public java.lang.Object getProperty(java.lang.String property)
и public void setProperty(java.lang.String property, java.lang.Object newValue)
, поэтому мы рассмотрим подробнее их реализацию EnvActionImpl
.
Для setProperty
реализация здесь :
@Override public void setProperty(String propertyName, Object newValue) {
env.put(propertyName, String.valueOf(newValue));
try {
owner.save();
} catch (IOException x) {
throw new RuntimeException(x);
}
}
Взглянув вверх в классе, мы видим объявление env
: private final Map<String,String> env;
.В качестве ключа используется имя правильного имени (list
в вашем примере), а значением является String.valueOf
возвращаемое значение newValue
, которое в вашем случае является строковым ["abc","def"]
.
Взгляд на setProperty
:
@Override public String getProperty(String propertyName) {
try {
CpsThread t = CpsThread.current();
return EnvironmentExpander.getEffectiveEnvironment(getEnvironment(), t.getContextVariable(EnvVars.class), t.getContextVariable(EnvironmentExpander.class)).get(propertyName);
} catch (Exception x) {
LOGGER.log(Level.WARNING, null, x);
return null;
}
}
Это может быть больше для понимания механики EnvironmentExpander
и CpsThread
, но самый быстрый способ - просто проверить подпись - public String
.
Это объясняет, что Дженкинс делает под капотом с переменной env
в конвейерных скриптах, и почему ваша итерация происходит по символам String
, а не по списку, как вы могли ожидать.Если вы создали свою собственную переменную и попробовали ее самостоятельно, вы увидите разницу в поведении, например, Map
и типа EnvActionImpl
.
final myVar = [:]
myVar.list = ["abc","def"]
env.list = ["abc","def"]
echo "${myVar.list.getClass()}"
echo "${env.list.getClass()}"