Интерполяция строк в Groovy с файлом Jenkins Pipeline не работает - PullRequest
3 голосов
/ 12 мая 2019

Итак, у меня есть конвейер Jenkins, который читает текстовый файл (JSON) с использованием метода readFile, предоставляемого Jenkins Pipeline. В текстовом файле 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 имеется более одной переменной, которую я хочу заменить

Проблема связана с методом readFile, предоставляемым Jenkins Pipeline. Хотя он очень аккуратный и простой в использовании, он не интерполирует строки.

Я ожидаю ниже выходной

println appMachine

{
   "name":"gaga",
   "fqdn":"gaga"
}

Вывод получаю

{
   "name":"${appServerName}",
   "fqdn":"${appServerName}"
}

1 Ответ

5 голосов
/ 12 мая 2019

Ваше предположение, что readFile step (или любой другой метод, который читает содержимое из текстового файла) должно связывать переменные из текущей области и интерполировать переменные-заполнители в необработанном тексте, неверно. Тем не менее, вы можете использовать шаблонный движок 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 { ... }), поэтому шаблонизатор не жалуется на отсутствие свойства с данным именем. В этом случае метод по умолчанию возвращает переменную «как есть», но вместо этого вы можете вернуть пустую строку или значение 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
...