我在groovy中有一个列表,定义为
env.list = ["abc","def"]
如果我尝试在for循环中使用它
for (letters in env.list) {
print("Letter is $letters")
}
它将遍历每个字母并打印以下内容-
Letter is [
Letter is "
Letter is a
.....
如果我将列表定义如下-
list = ["abc","def"]
它将视为一个列表。 for循环将显示以下内容。
Letter is abc
Letter is def
使用groovy运行我的Jenkins管道。
答案 0 :(得分:3)
在詹金斯管道中,env
-是保存环境变量列表的变量:
https://jenkins.io/doc/book/pipeline/jenkinsfile/#using-environment-variables
并且环境变量只能包含一个字符串
因此,当您尝试为环境变量分配一个列表时-它会自动转换为字符串
env.list = ["abc","def"]
等同于
env.list = ["abc","def"].toString()
然后按字符迭代字符串...
答案 1 :(得分:0)
要解释为什么会发生这种现象,最好转向Jenkins源代码。
全局变量名称为env
,将我们带到org.jenkinsci.plugins.workflow.cps.EnvActionImpl.Binder
。它将值绑定到脚本(在本例中为管道)。
@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
(source code)。 GroovyObjectSupport
在其文档中有此内容:
对于希望成为Groovy对象的Java对象的有用基类
因此,这是Jenkins允许Java实现,使其可以为Groovy设置其行为。您使用的方法是public java.lang.Object getProperty(java.lang.String property)
和public void setProperty(java.lang.String property, java.lang.Object newValue)
,因此我们将更详细地研究EnvActionImpl
的实现。
对于setProperty
,实现为here:
@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
的{{1}}返回,在您的情况下为字符串化的newValue
。 / p>
["abc","def"]
了解@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