Jenkins用の一般的なGroovyコードを生成しようとしていますが、複数行の文字列と余分な空白に問題があるようです。グーグルで見つけたものをすべて試しましたが、うまくいかないようです。
私の問題は、単純な複数行の文字列とは関係ありません。単純なケースでは、stripIndent()メソッドとstripMargin()メソッドを使用して空白をトリミングすることができました。私の問題は、文字列内にメソッドを補間したことが原因です。
Groovy情報: Groovy Version: 3.0.2 JVM: 13.0.2 Vendor: Oracle Corporation OS: Mac OS X
String method2(String tier, String jobName) {
return """
Map downstreamJobs = [:]
stage ("${jobName}-${tier}-\${region}_${jobName}") {
test
}
""".stripIndent().stripMargin()
}
static String simpleLog() {
return """
script {
def user = env.BUILD_USER_ID
}
""".stripIndent().stripMargin()
}
static String method1() {
return """\
import jenkins.model.Jenkins
currentBuild.displayName = "name"
${simpleLog()}
""".stripIndent().stripMargin()
}
String generateFullDeploymentPipelineCode() {
return """Text here
${method1()}
${method2("test1", "test2")}
""".stripIndent().stripMargin()
}
println(generateFullDeploymentPipelineCode())
これはそれが印刷する(またはディスクに書き込む)ものです:
Text here
import jenkins.model.Jenkins
currentBuild.displayName = "name"
script {
def user = env.BUILD_USER_ID
}
Map downstreamJobs = [:]
stage ("test2-test1-${region}_test2") {
test
}
なぜインポートラインの周りに余分なスペースがあるのですか?インデント方法では、先頭のスペースの最小数に従ってすべての空白がトリミングされることになっているので、バックスラッシュを使用します(例はhttps://stackoverflow.com/a/19882917/7569335)。
これは単純な文字列では機能しますが、補間の使用を開始すると機能しなくなります。メソッド全体を補間するときだけで、通常の変数ではありません。
補間によって文字列を挿入するときは、その最初の行だけをインデントします。挿入された文字列の次の行は異なるインデントになり、すべてが台無しになります。
GString
(つまり.strings[]
と.values[]
)のあまり知られていないメンバーを使用して、補間された各値のすべての行のインデントを揃えることができます。
String method2(String tier, String jobName) {
indented """
Map downstreamJobs = [:]
stage ("${jobName}-${tier}-\${region}_${jobName}") {
test
}
"""
}
String simpleLog() {
indented """\
script {
def user = env.BUILD_USER_ID
}
"""
}
String method1() {
indented """\
import jenkins.model.Jenkins
currentBuild.displayName = "name"
${simpleLog()}
"""
}
String generateFullDeploymentPipelineCode() {
indented """\
Text here
${method1()}
${method2("test1", "test2")}
"""
}
println generateFullDeploymentPipelineCode()
//---------- Move the following code into its own script ----------
// Function to adjust the indentation of interpolated values so that all lines
// of a value match the indentation of the first line.
// Finally stripIndent() will be called before returning the string.
String indented( GString templ ) {
// Iterate over the interpolated values of the GString template.
templ.values.eachWithIndex{ value, i ->
// Get the string preceding the current value. Always defined, even
// when the value is at the beginning of the template.
def beforeValue = templ.strings[ i ]
// RegEx to match any indent substring before the value.
// Special case for the first string, which doesn't necessarily contain '\n'.
def regexIndent = i == 0
? /(?:^|\n)([ \t]+)$/
: /\n([ \t]+)$/
def matchIndent = ( beforeValue =~ regexIndent )
if( matchIndent ) {
def indent = matchIndent[ 0 ][ 1 ]
def lines = value.readLines()
def linesNew = [ lines.head() ] // The 1st line is already indented.
// Insert the indentation from the 1st line into all subsequent lines.
linesNew += lines.tail().collect{ indent + it }
// Finally replace the value with the reformatted lines.
templ.values[ i ] = linesNew.join('\n')
}
}
return templ.stripIndent()
}
// Fallback in case the input string is not a GString (when it doesn't contain expressions)
String indented( String templ ) {
return templ.stripIndent()
}
出力:
Text here
import jenkins.model.Jenkins
currentBuild.displayName = "name"
script {
def user = env.BUILD_USER_ID
}
Map downstreamJobs = [:]
stage ("test2-test1-${region}_test2") {
test
}
結論:
このindented
関数を使用して、GString
テンプレートからコードを生成するためのクリーンなGroovy構文が実現されました。
これはかなりの学習経験でした。最初はevaluate
関数を使ってまったく違うことをしようとしましたが、複雑すぎて柔軟性がないことがわかりました。次に、「Groovy Goodness:Get to Know More About a GString」を発見するまで、mrhakiブログのいくつかの投稿をランダムに閲覧しました(常によく読んでください!)。これが、このソリューションを実装するための鍵でした。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加