Groovy/Jenkins:变量什么时候为null,什么时候为空字符串,什么时候缺失?
Groovy/Jenkins: when are variables null, when are they empty strings, and when are they missing?
我正在尝试理解 Groovy/Jenkinsfiles/declarative 语法中变量的规则。
通用 webhook 触发器捕获 HTTP POST 内容,并将它们作为可用变量提供给您的 Jenkinsfile。例如:
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_name
字段值为“foo”,则打印:
env var foo
global var foo
如果 HTTP POST 内容不包含 JSON 字段 actor_name
,则打印
env var null
...然后 asserts/aborts 出现 No such property
错误。
Jenkins 作业也有一个“此项目已参数化”设置,这似乎引入了另一种将变量注入 Jenkinsfile 的方法。以下 Jenkinsfile 打印一个已填充的参数化构建变量、一个未填充的变量和一个故意不存在的变量:
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 []
...然后 asserts/aborts 出现 No such property
错误。
我可以确定的模式是:
如果 env.
范围内的变量来自未填充的 HTTP POST 内容,则它们将为 NULL。
如果 env.
-scoped 变量来自未填充的参数化构建变量,则它们将为空字符串。
env.
如果在参数化构建变量中不存在,范围变量将为 NULL。
- 如果引用全局范围的变量来自未填充的 HTTP POST 内容,则它们将断言。
- 如果引用全局范围的变量来自未填充的参数化构建变量,则它们将是空字符串。
params.
-scoped 变量如果在参数化构建变量中不存在,则它们将为 NULL。
如果 params.
-scoped 变量来自未填充的参数化构建变量,则它们将为空字符串。
关于这个我有几个问题 - 我相信它们是合理相关的,所以我将它们包括在这个问题中 post:
- 变量为NULL和空字符串时pattern/logic背后的底层是什么?
- 为什么变量在不同的“范围”可用:
env.
、params.
和全局,它们之间的关系是什么(为什么它们不总是1:1)?
- 有没有办法让参数化构建中未填充的值成为 Jenkinsfile 中的空值变量而不是空字符串?
上下文:在我的第一个 Jenkinsfile 项目中,我使用了由 HTTP POST 内容填充的变量。通过这个,我开始将值的缺失与相应的 .env
变量的空性相关联。现在,我正在处理来自参数化构建值的变量,当未填充值时,相应的 .env
变量不为空——它是一个空字符串。因此,我想了解这些变量何时以及为何为空与空背后的模式,以便我可以编写可靠而简单的代码来处理来自 HTTP POST 内容和参数化构建值的 absence/non-population 值.
答案有点复杂
对于 1 和 2:
首先管道、阶段、步骤...是groovy类。那里的一切都被定义为 object/variable.
env 是一个包含几乎所有内容的对象,
params 包含所有参数 ;)
它们都是一个Map,如果你访问一个空值它就是空的,如果你访问一个不存在的它就是null。
全局变量本身就是变量,如果您尝试访问不存在的变量,编译器会报错。
对于 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
}
我正在尝试理解 Groovy/Jenkinsfiles/declarative 语法中变量的规则。
通用 webhook 触发器捕获 HTTP POST 内容,并将它们作为可用变量提供给您的 Jenkinsfile。例如:
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_name
字段值为“foo”,则打印:
env var foo
global var foo
如果 HTTP POST 内容不包含 JSON 字段 actor_name
,则打印
env var null
...然后 asserts/aborts 出现 No such property
错误。
Jenkins 作业也有一个“此项目已参数化”设置,这似乎引入了另一种将变量注入 Jenkinsfile 的方法。以下 Jenkinsfile 打印一个已填充的参数化构建变量、一个未填充的变量和一个故意不存在的变量:
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 []
...然后 asserts/aborts 出现 No such property
错误。
我可以确定的模式是:
-
如果
env.
范围内的变量来自未填充的 HTTP POST 内容,则它们将为 NULL。
如果 env.
-scoped 变量来自未填充的参数化构建变量,则它们将为空字符串。env.
如果在参数化构建变量中不存在,范围变量将为 NULL。- 如果引用全局范围的变量来自未填充的 HTTP POST 内容,则它们将断言。
- 如果引用全局范围的变量来自未填充的参数化构建变量,则它们将是空字符串。
params.
-scoped 变量如果在参数化构建变量中不存在,则它们将为 NULL。
如果 params.
-scoped 变量来自未填充的参数化构建变量,则它们将为空字符串。
关于这个我有几个问题 - 我相信它们是合理相关的,所以我将它们包括在这个问题中 post:
- 变量为NULL和空字符串时pattern/logic背后的底层是什么?
- 为什么变量在不同的“范围”可用:
env.
、params.
和全局,它们之间的关系是什么(为什么它们不总是1:1)? - 有没有办法让参数化构建中未填充的值成为 Jenkinsfile 中的空值变量而不是空字符串?
上下文:在我的第一个 Jenkinsfile 项目中,我使用了由 HTTP POST 内容填充的变量。通过这个,我开始将值的缺失与相应的 .env
变量的空性相关联。现在,我正在处理来自参数化构建值的变量,当未填充值时,相应的 .env
变量不为空——它是一个空字符串。因此,我想了解这些变量何时以及为何为空与空背后的模式,以便我可以编写可靠而简单的代码来处理来自 HTTP POST 内容和参数化构建值的 absence/non-population 值.
答案有点复杂
对于 1 和 2:
首先管道、阶段、步骤...是groovy类。那里的一切都被定义为 object/variable.
env 是一个包含几乎所有内容的对象,
params 包含所有参数 ;)
它们都是一个Map,如果你访问一个空值它就是空的,如果你访问一个不存在的它就是null。
全局变量本身就是变量,如果您尝试访问不存在的变量,编译器会报错。
对于 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
}