Groovy 中的字符串插值与 Jenkins 管道文件不起作用
String Interpolation in Groovy with Jenkins Pipeline file not working
所以我有一个 Jenkins Pipeline,它使用 Jenkins Pipeline 提供的 readFile 方法读取文本文件 (JSON)。文本文件 app.JSON 有多个已在 Jenkins 管道中定义的变量。
虽然 readFile 确实读取文件并将其转换为字符串,但它不会插入这些变量。除了简单的字符串替换(我想避免)之外,我还有哪些选项可以插入这些变量
我知道我可以使用 readJSON 或 JSON 解析器,但我希望以字符串形式输出,这样我就可以更轻松地将其作为字符串读取并传递。
我尝试过使用 Gstrings、${-> variable} 和 .toString() 方法。对我没有任何作用。
詹金斯管道代码
appServerName = 'gaga'
def appMachine = readFile file: 'util-silo-create-v2/app.json'
println appMachine
app.json
{
"name":"${appServerName}",
"fqdn":"${appServerName}"
}
我要替换的管道和 app.json 中有不止一个变量
问题出在 Jenkins Pipeline 提供的 readFile 方法上。虽然它非常整洁且易于使用,但它不会插入字符串。
我预计低于输出
println appMachine
{
"name":"gaga",
"fqdn":"gaga"
}
我得到的输出
{
"name":"${appServerName}",
"fqdn":"${appServerName}"
}
您假设 readFile
步骤 (或任何其他从文本文件读取内容的方法) 应该绑定当前作用域中的变量并在其中插入变量占位符原始文本是错误的。但是,您可以使用 Groovy 模板引擎来调用类似于 GString 变量插值的东西。考虑以下示例:
import groovy.text.SimpleTemplateEngine
def jsonText = '''{
"name":"${appServerName}",
"fqdn":"${appServerName}"
}'''
@NonCPS
def parseJsonWithVariables(String json, Map variables) {
def template = new SimpleTemplateEngine()
return template.createTemplate(json).make(variables.withDefault { it -> "${$it}" }).toString()
}
node {
stage("Test") {
def parsed = parseJsonWithVariables(jsonText, [
appServerName: "gaga"
])
echo parsed
}
}
方法 parseJsonWithVariables
可以达到您的预期效果。使此方法 @NonCPS
至关重要,因为 SimpleTemplateEngine
以及使用 withDefault()
创建的映射不可序列化。它需要先前从文件中读取的 JSON(在本例中,为简单起见,我使用变量代替)和参数映射。它将此映射转换为具有默认值的映射(variables.withDefault { ... }
部分负责),因此模板引擎不会抱怨没有具有给定名称的 属性。在这种情况下,默认方法 return 是一个变量 "as is",但您可以 return 空字符串或 null
值代替。什么对你更有效。
当你 运行 它时你会是这样的:
[Pipeline] Start of Pipeline (hide)
[Pipeline] node
[Pipeline] {
[Pipeline] stage
[Pipeline] { (Test)
[Pipeline] echo
{
"name":"gaga",
"fqdn":"gaga"
}
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
Finished: SUCCESS
所以我有一个 Jenkins Pipeline,它使用 Jenkins Pipeline 提供的 readFile 方法读取文本文件 (JSON)。文本文件 app.JSON 有多个已在 Jenkins 管道中定义的变量。
虽然 readFile 确实读取文件并将其转换为字符串,但它不会插入这些变量。除了简单的字符串替换(我想避免)之外,我还有哪些选项可以插入这些变量
我知道我可以使用 readJSON 或 JSON 解析器,但我希望以字符串形式输出,这样我就可以更轻松地将其作为字符串读取并传递。
我尝试过使用 Gstrings、${-> variable} 和 .toString() 方法。对我没有任何作用。
詹金斯管道代码
appServerName = 'gaga'
def appMachine = readFile file: 'util-silo-create-v2/app.json'
println appMachine
app.json
{
"name":"${appServerName}",
"fqdn":"${appServerName}"
}
我要替换的管道和 app.json 中有不止一个变量
问题出在 Jenkins Pipeline 提供的 readFile 方法上。虽然它非常整洁且易于使用,但它不会插入字符串。
我预计低于输出
println appMachine
{
"name":"gaga",
"fqdn":"gaga"
}
我得到的输出
{
"name":"${appServerName}",
"fqdn":"${appServerName}"
}
您假设 readFile
步骤 (或任何其他从文本文件读取内容的方法) 应该绑定当前作用域中的变量并在其中插入变量占位符原始文本是错误的。但是,您可以使用 Groovy 模板引擎来调用类似于 GString 变量插值的东西。考虑以下示例:
import groovy.text.SimpleTemplateEngine
def jsonText = '''{
"name":"${appServerName}",
"fqdn":"${appServerName}"
}'''
@NonCPS
def parseJsonWithVariables(String json, Map variables) {
def template = new SimpleTemplateEngine()
return template.createTemplate(json).make(variables.withDefault { it -> "${$it}" }).toString()
}
node {
stage("Test") {
def parsed = parseJsonWithVariables(jsonText, [
appServerName: "gaga"
])
echo parsed
}
}
方法 parseJsonWithVariables
可以达到您的预期效果。使此方法 @NonCPS
至关重要,因为 SimpleTemplateEngine
以及使用 withDefault()
创建的映射不可序列化。它需要先前从文件中读取的 JSON(在本例中,为简单起见,我使用变量代替)和参数映射。它将此映射转换为具有默认值的映射(variables.withDefault { ... }
部分负责),因此模板引擎不会抱怨没有具有给定名称的 属性。在这种情况下,默认方法 return 是一个变量 "as is",但您可以 return 空字符串或 null
值代替。什么对你更有效。
当你 运行 它时你会是这样的:
[Pipeline] Start of Pipeline (hide)
[Pipeline] node
[Pipeline] {
[Pipeline] stage
[Pipeline] { (Test)
[Pipeline] echo
{
"name":"gaga",
"fqdn":"gaga"
}
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
Finished: SUCCESS