Groovy/Jenkins:变量何时为null,何时为空字符串,何时缺失?
我试图探索Groovy/Jenkinsfiles/declarative语法中围绕变量的规则 通用webhook触发器捕获HTTP POST内容,并将其作为变量提供给文件。例如:Groovy/Jenkins:变量何时为null,何时为空字符串,何时缺失?,jenkins,groovy,jenkins-pipeline,jenkins-declarative-pipeline,Jenkins,Groovy,Jenkins Pipeline,Jenkins Declarative Pipeline,我试图探索Groovy/Jenkinsfiles/declarative语法中围绕变量的规则 通用webhook触发器捕获HTTP POST内容,并将其作为变量提供给文件。例如: pipeline { agent any triggers { GenericTrigger ( genericVariables: [ [ key: "POST_actor_name", value: "\$.actor.name"
pipeline {
agent any
triggers {
GenericTrigger (
genericVariables: [
[ key: "POST_actor_name", value: "\$.actor.name" ]
],
token: "foo"
)
}
stages {
stage( "Set up" ) {
steps {
script {
echo "env var ${env.actor_name}"
echo "global var ${actor_name}"
}
}
}
}
如果HTTP POST内容包含一个JSON对象,该对象的actor\u name
字段值为“foo”,则会打印:
env var foo
global var foo
如果HTTP POST内容不包含JSON字段actor\u name
,则打印此字段
env var null
…然后以无此类属性的错误断言/中止
Jenkins jobs还有一个“this project is parameterized”设置,它似乎引入了另一种将变量注入Jenkins文件的方法。以下文件打印已填充的参数化生成变量、未填充的生成变量和有意不存在的变量:
pipeline {
agent any
stages {
stage( "Set up" ) {
steps {
script {
echo "1 [${env.populated_var}]"
echo "2 [${env.unpopulated_var}]"
echo "3 [${env.dontexist}]"
echo "4 [${params.populated_var}]"
echo "5 [${params.unpopulated_var}]"
echo "6 [${params.dontexist}]"
echo "7 [${populated_var}]"
echo "8 [${unpopulated_var}]"
echo "9 [${dontexist}]"
}
}
}
}
}
结果是:
1 [foo]
2 []
3 [null]
4 [foo]
5 []
6 [null]
7 [foo]
8 []
…然后以无此类属性的错误断言/中止
我可以确定的模式是:
env.
-如果作用域变量来自未填充的HTTP POST内容,则这些变量将为NULL
env.
-如果作用域变量来自未填充的参数化生成变量,则它们将是空字符串
env.
-如果参数化生成变量中不存在作用域变量,则作用域变量将为NULL
如果全局作用域变量来自未填充的HTTP POST内容,则引用这些变量将进行断言
如果引用的全局范围变量来自未填充的参数化生成变量,则它们将是空字符串
参数。
-如果在参数化生成变量中不存在作用域变量,则作用域变量将为NULL
params.
-如果作用域变量来自未填充的参数化生成变量,则它们将是空字符串
关于这一点,我有几个问题——我认为它们有一定的关联,所以我将它们包括在这篇文章中:
当变量为NULL和空字符串时,其背后的基本模式/逻辑是什么?
为什么变量在不同的“作用域”中可用:env.
、params.
和全局,它们之间的关系是什么(为什么不总是1:1)?
有没有办法使参数化构建中的未填充值成为Jenkins文件中的空值变量,而不是空字符串?
上下文:在我的第一个Jenkinsfile项目中,我使用了由httppost内容填充的变量。通过这一点,我将值的缺失与相应的.env
变量的空值相关联。现在,我正在处理来自参数化构建值的变量,当一个值没有填充时,相应的.env
变量不是null——它是一个空字符串。因此,我想了解这些变量是null还是空的时间和原因,这样我就可以编写可靠而简单的代码来处理HTTP POST内容和参数化构建值中的值缺失/未填充。答案有点复杂
对于1和2:
首先,管道、阶段、步骤。。。是groovy类。其中的所有内容都定义为对象/变量
env是一个几乎可以容纳所有东西的对象
params保存所有参数;)
它们都是映射,如果访问空值,则为空;如果访问不存在的值,则为空
全局变量本身就是变量,如果试图访问不存在的变量,编译器会抱怨
对于3:
您可以定义“默认”参数:
pipeline {
agent any
stages {
stage( "Set up" ) {
steps {
script {
params = setConfig(params);
}
}
}
}
}
def merge(Map lhs, Map rhs) {
return rhs.inject(lhs.clone()) { map, entry ->
if (map[entry.key] instanceof Map && entry.value instanceof Map) {
map[entry.key] = merge(map[entry.key], entry.value)
} else {
map[entry.key] = entry.value
}
return map
}
}
def setConfig(givenConfig = [:]) {
def defaultConfig = [
"populated_var": "",
"unpopulated_var": "",
"dontexist": ""
];
effectiveConfig = merge(defaultConfig, givenConfig);
return effectiveConfig
}
很好,全面的回答,谢谢。但是,您知道为什么吗:如果一个变量是从HTTP POST内容填充的,但该变量在HTTP POST中完全不存在,那么相应的env.
变量为空,但是如果同一个变量是从构建参数填充的,并且构建参数为空,那么env.
变量是空字符串?我试图理解为什么“变量未填充”的一个“路径”导致一个空变量,而另一个“路径”导致一个空变量。我不确定。但这可能与GenericTrigger插件有关。在这两种情况下,这都是一个设计决策。插件和参数(很可能)是由不同的人开发的,即使不是,在这两种情况下的决定都是不同的。我认为参数是用“”初始化的,而在GenericTrigger插件中不是。