Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Groovy multiline string interpolation whitespace

I am trying to generate some generic Groovy code for Jenkins but I seem to have trouble with multi line strings and extra white space. I've tried everything I could find by Googling but I can't seem to get it working.

My issue isn't related to simple multi line strings. I managed to trim white space by using the stripIndent() and stripMargin() methods for simple cases. My issue is caused by having interpolated methods inside my strings.

Groovy info: 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())

This is what it prints(or writes to disk):

Text here
                      import jenkins.model.Jenkins
          currentBuild.displayName = "name"

script {
   def user = env.BUILD_USER_ID
}



Map downstreamJobs = [:]
stage ("test2-test1-${region}_test2") {
    test
}

Why the extra space around the import lines? I know the indentation method is supposed to trim all white space according to the least number of leading spaces, so that's why we use backslash (example here https://stackoverflow.com/a/19882917/7569335).

That works for simple strings, but it breaks down once use start using interpolation. Not with regular variables, just when you interpolate an entire method.

like image 984
Serban Cezar Avatar asked Sep 06 '25 21:09

Serban Cezar


1 Answers

as variant - use just stripMargin() and only once on a final string

String method2(String tier, String jobName) {
    return """\
            |Map downstreamJobs = [:]
            |stage ("${jobName}-${tier}-\${region}_${jobName}") {
            |    test
            |}
        """
}

static String simpleLog() {
    return """\
            |script {
            |   def user = env.BUILD_USER_ID
            |}
          """
}

static String method1() {
    return """\
            |import jenkins.model.Jenkins
            |currentBuild.displayName = "name"

            ${simpleLog()}
        """
}

String generateFullDeploymentPipelineCode() {
    return """\
            |Text here
            ${method1()}
            ${method2("test1", "test2")}
            """.stripIndent().stripMargin()
}

println(generateFullDeploymentPipelineCode())

result:

Text here
import jenkins.model.Jenkins
currentBuild.displayName = "name"

script {
   def user = env.BUILD_USER_ID
}

Map downstreamJobs = [:]
stage ("test2-test1-${region}_test2") {
    test
}

another variant with trim() and stripIndent()

def method2(String tier, String jobName) {
    return """
            Map downstreamJobs = [:]
            stage ("${jobName}-${tier}-\${region}_${jobName}") {
                test
            }
        """.trim()
}

def simpleLog() {
    return """
            script {
               def user = env.BUILD_USER_ID
            }
          """.trim()
}

def method1() {
    return """
            import jenkins.model.Jenkins
            currentBuild.displayName = "name"
            ${simpleLog()}
        """.trim()
}

def generateFullDeploymentPipelineCode() {
    return """\
            Text here
            ${method1()}
            ${method2("test1", "test2")}
            """.stripIndent()
}

println(generateFullDeploymentPipelineCode())
like image 167
daggett Avatar answered Sep 10 '25 00:09

daggett