Groovy中使用Jenkins Pipeline文件的字符串插值不起作用

时间:2019-05-12 17:56:45

标签: groovy jenkins-pipeline string-interpolation

因此,我有一个Jenkins Pipeline,它使用Jenkins Pipeline提供的readFile方法读取文本文件(JSON)。文本文件app.JSON具有多个变量,这些变量已经在Jenkins管道中定义。

虽然readFile确实读取了文件并将其转换为字符串,但它并未对这些变量进行插值。除了简单的字符串替换(我要避免的地方)之外,我还有哪些选项可以插值这些变量

我知道我可以使用readJSON或JSON解析器,但我希望将输出以字符串形式显示,这样我就可以更轻松地将其作为字符串读取并传递。

我尝试使用Gstrings,$ {-> variable}和.toString()方法。对我没有任何帮助。

Jenkins管道代码

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}"
}

1 个答案:

答案 0 :(得分:5)

您假设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 { ... }负责),因此模板引擎不会抱怨没有给定名称的属性。在这种情况下,默认方法返回一个变量“ as is”,但是您可以返回一个空字符串或一个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