Uploaded image for project: 'Jenkins'
  1. Jenkins
  2. JENKINS-46988

String.eachLine only reads first line

    XMLWordPrintable

    Details

    • Similar Issues:

      Description

      As with JENKINS-26481 the eachLine-method on String only works for the first iteration.

      Using version 3.39

      We use a cleanup-pipeline to find all running docker-containers without a corresponding feature-branch (deleted after merge).

      stage('clean') {
       def branches = []
       // extract available branches from git
       sh (returnStdout: true, script: "ssh-agent bash -c 'ssh-add /var/lib/jenkins/.ssh/id_rsa &>/dev/null; git ls-remote --heads --refs ssh://git@myrepo/project.git' | cut -f 2")
        .eachLine { branches << it }
       // extract all containers (including stopped)
       def containers = []
       sh (returnStdout: true, script: "docker ps -a --format '{{.Names}}' --filter name=project")
        .trim()
        .eachLine { containers << it }
       println(containers) // <---- only prints first container
       println(branches) // <---- only prints first branch
      
       //stop containers for non existing branches...
       containers.each{ containername ->
        if(branches.findAll({branch -> branch.contains(containername)}).isEmpty()){
         println("trying to stop ${containername}")
         //sh ("docker stop ${containername} || true") // container might already be stopped
         println("removing ${containername}")
         //sh ("docker rm ${containername}")
        }
       }
      }

      As a workaround replace eachLine with split('\n').each { ... }

        Attachments

          Activity

          lostiniceland Marc Schlegel created issue -
          lostiniceland Marc Schlegel made changes -
          Field Original Value New Value
          Description As with JENKINS-26481 the eachLine-method on String only works for the first iteration.

          Using version 3.39

          We use a cleanup-pipeline to find all running docker-containers without a corresponding feature-branch (deleted after merge).
          {code:java}
          stage('clean') {
           def branches = []
           // extract available branches from git
           sh (returnStdout: true, script: "ssh-agent bash -c 'ssh-add /var/lib/jenkins/.ssh/id_rsa &>/dev/null; git ls-remote --heads --refs ssh://git@myrepo/project.git&#39; | cut -f 2")
            .eachLine { branches << it }
           // extract all containers (including stopped)
           def containers = []
           sh (returnStdout: true, script: "docker ps -a --format '{{.Names}}' --filter name=project")
            .trim()
            .eachLine { containers << it }
           println(containers) // <---- only prints first container
           println(branches) // <---- only prints first branch

           //stop containers for non existing branches...
           containers.each{ containername ->
            if(branches.findAll({branch -> branch.contains(containername)}).isEmpty()){
             println("trying to stop ${containername}")
             //sh ("docker stop ${containername} || true") // container might already be stopped
             println("removing ${containername}")
             //sh ("docker rm ${containername}")
            }
           }
          }{code}
          As with -JENKINS-26481- the eachLine-method on String only works for the first iteration.

          Using version 3.39

          We use a cleanup-pipeline to find all running docker-containers without a corresponding feature-branch (deleted after merge).
          {code:java}
          stage('clean') {
           def branches = []
           // extract available branches from git
           sh (returnStdout: true, script: "ssh-agent bash -c 'ssh-add /var/lib/jenkins/.ssh/id_rsa &>/dev/null; git ls-remote --heads --refs ssh://git@myrepo/project.git&#39; | cut -f 2")
            .eachLine { branches << it }
           // extract all containers (including stopped)
           def containers = []
           sh (returnStdout: true, script: "docker ps -a --format '{{.Names}}' --filter name=project")
            .trim()
            .eachLine { containers << it }
           println(containers) // <---- only prints first container
           println(branches) // <---- only prints first branch

           //stop containers for non existing branches...
           containers.each{ containername ->
            if(branches.findAll({branch -> branch.contains(containername)}).isEmpty()){
             println("trying to stop ${containername}")
             //sh ("docker stop ${containername} || true") // container might already be stopped
             println("removing ${containername}")
             //sh ("docker rm ${containername}")
            }
           }
          }{code}
          As a workaround replace _eachLine_ with _split('\n').each \{ ... }_
          Hide
          knuckolls Kevin Nuckolls added a comment -

          I lost an afternoon to this bug and it's real and still open. The workaround mentioned of the split each works great. Just chiming in that this does actually need to be fixed.

          Show
          knuckolls Kevin Nuckolls added a comment - I lost an afternoon to this bug and it's real and still open. The workaround mentioned of the split each works great. Just chiming in that this does actually need to be fixed.
          Hide
          katie Katie Sissons added a comment -

          Chiming in as well, having the same issue. Example:

          	def tagged_branches = sh(returnStdout: true, script: "git branch --contains tags/${tag_name}")
          	println tagged_branches
          	tagged_branches.eachLine {
          		println it
          	}
          

          Outputs:

          12:36:41  + git branch --contains tags/v0.6.20
          12:36:41  [Pipeline] echo
          12:36:41    feature/install_from_net_drive
          12:36:41  * master
          12:36:41  
          12:36:42  [Pipeline] echo
          12:36:42    feature/install_from_net_drive
          12:36:42  [Pipeline] }
          12:36:42  [Pipeline] // script
          12:36:42  [Pipeline] }
          
          Show
          katie Katie Sissons added a comment - Chiming in as well, having the same issue. Example: def tagged_branches = sh(returnStdout: true , script: "git branch --contains tags/${tag_name}" ) println tagged_branches tagged_branches.eachLine { println it } Outputs: 12:36:41 + git branch --contains tags/v0.6.20 12:36:41 [Pipeline] echo 12:36:41 feature/install_from_net_drive 12:36:41 * master 12:36:41 12:36:42 [Pipeline] echo 12:36:42 feature/install_from_net_drive 12:36:42 [Pipeline] } 12:36:42 [Pipeline] // script 12:36:42 [Pipeline] }
          Hide
          stefanthurnherr Stefan Thurnherr added a comment -

          Just ran into this issue as well, but got this nice warning in the Jenkins output which helped me find the cause (i.e. this issue):

          expected to call java.lang.String.eachLine but wound up catching org.jenkinsci.plugins.workflow.cps.CpsClosure2.call; see: https://jenkins.io/redirect/pipeline-cps-method-mismatches/

          Show
          stefanthurnherr Stefan Thurnherr added a comment - Just ran into this issue as well, but got this nice warning in the Jenkins output which helped me find the cause (i.e. this issue): expected to call java.lang.String.eachLine but wound up catching org.jenkinsci.plugins.workflow.cps.CpsClosure2.call; see: https://jenkins.io/redirect/pipeline-cps-method-mismatches/
          Hide
          rakeshnagarajan Rakesh Nagarajan added a comment -
          node {
             def data = """# some useless text
                           |# even more
                           |finally interesting text"""
          data.eachLine { String line ->
            println line
          }
          
          }
          

          Same issue when we execute the above script.

          expected to call java.lang.String.eachLine but wound up catching org.jenkinsci.plugins.workflow.cps.CpsClosure2.call; see: https://jenkins.io/redirect/pipeline-cps-method-mismatches/
          
          Show
          rakeshnagarajan Rakesh Nagarajan added a comment - node { def data = """# some useless text |# even more |finally interesting text""" data.eachLine { String line -> println line } } Same issue when we execute the above script. expected to call java.lang.String.eachLine but wound up catching org.jenkinsci.plugins.workflow.cps.CpsClosure2.call; see: https://jenkins.io/redirect/pipeline-cps-method-mismatches/
          Hide
          rakeshnagarajan Rakesh Nagarajan added a comment -

          Workaround is working really fine

          As a workaround replace eachLine with split('\n').each { ... }

           

          Show
          rakeshnagarajan Rakesh Nagarajan added a comment - Workaround is working really fine As a workaround replace eachLine with split('\n').each { ... }  
          Hide
          jorhett Jo Rhett added a comment - - edited

          I don't feel that this issue is Minor, nor do I feel that the workaround is an acceptable solution. This basically means that every Jenkins user worldwide will burn some hours diagnosing this problem only to end up here.

          That this bug is more than 2 years old speaks to a significant lack of care.

          Show
          jorhett Jo Rhett added a comment - - edited I don't feel that this issue is Minor, nor do I feel that the workaround is an acceptable solution. This basically means that every Jenkins user worldwide will burn some hours diagnosing this problem only to end up here. That this bug is more than 2 years old speaks to a significant lack of care.
          Hide
          euphxenos Andrew Lawrence added a comment -

          I'd like to affirm the previous comment.  I just did exactly that – I spent a couple of hours trying to figure out why my code wasn't working, and ended up here when I realized it was a bug in the Jenkins groovy interpreter for scripted pipelines.

          Show
          euphxenos Andrew Lawrence added a comment - I'd like to affirm the previous comment.  I just did exactly that – I spent a couple of hours trying to figure out why my code wasn't working, and ended up here when I realized it was a bug in the Jenkins groovy interpreter for scripted pipelines.
          Hide
          flash1212 Dominique Thornton added a comment -

          Likewise. Just burned a bit of time on this. Moving to the workaround.

          Show
          flash1212 Dominique Thornton added a comment - Likewise. Just burned a bit of time on this. Moving to the workaround.
          Hide
          pkozuchowski Piotr Kożuchowski added a comment -

          I've just stumbled over this as well.

          Show
          pkozuchowski Piotr Kożuchowski added a comment - I've just stumbled over this as well.
          Hide
          tonyhoylerps Tony Hoyle added a comment -

          Same here.  What's worse is the error message links to a page https://jenkins.io/redirect/pipeline-cps-method-mismatches/ which has absolutely no hints on what the error could be, and assumes you know the internal workings of the groovy compiler.  No, I just want a simple and obvious construct to work..

           

           

           

          Show
          tonyhoylerps Tony Hoyle added a comment - Same here.  What's worse is the error message links to a page https://jenkins.io/redirect/pipeline-cps-method-mismatches/  which has absolutely no hints on what the error could be, and assumes you know the internal workings of the groovy compiler.  No, I just want a simple and obvious construct to work..      
          Hide
          nancyrobertson Nancy Robertson added a comment -

          Affects us as well

          Show
          nancyrobertson Nancy Robertson added a comment - Affects us as well
          Hide
          dmitryb Dmitry Bigunyak added a comment -

          Also wasted time one this issue, but thanks to this bug report, quickly switched to workaround.

          Show
          dmitryb Dmitry Bigunyak added a comment - Also wasted time one this issue, but thanks to this bug report, quickly switched to workaround.

            People

            Assignee:
            Unassigned Unassigned
            Reporter:
            lostiniceland Marc Schlegel
            Votes:
            30 Vote for this issue
            Watchers:
            25 Start watching this issue

              Dates

              Created:
              Updated: