2016-07-07 138 views
5

我需要從管道中的文件中讀取值。我正在使用split(),它將它們放入陣列。我需要將它們放入Arraylist,所以我使用的是Arrays.asList()。時遇到的問題是我無法使用尺寸()長度()方法,所以我不能使一個for循環如Jenkins管道 - 如何遍歷列表

for (ii = 0; ii < var.length; ii++) 

for (ii = 0; ii < var.size; ii++) 

因爲我得到的錯誤:unclassified字段java.util.Arrays $ ArrayList長度

所以我試圖用一個for每個循環,但是當我採取一些行動(如ls命令例如)在我的finally塊中,它只能迭代1次。但是,如果我只是運行命令'echo',它會按照它應該的每個元素進行迭代。任何關於如何修改我的代碼以使其在使用任何命令時都能對列表中的每個元素進行迭代的建議?

正常工作....

node{ 
    wrap([$class: 'ConfigFileBuildWrapper', managedFiles: [[fileId: 'dest_hosts.txt', targetLocation: '', variable: 'DEST_HOST']]]) { 
     HOST = Arrays.asList(readFile(env.DEST_HOST).split("\\r?\\n")) 
     deploy(HOST) 
    } 
} 

@NonCPS 
def deploy(host){ 
    for (String target : host){ 
     try { 
      echo target 
     } 
     finally { 
      echo target 
     } 
    } 
} 

OUTPUT(迭代針對每個元件):

[Pipeline] node 
Running on <obfuscated> 
[Pipeline] { 
[Pipeline] wrap 
provisoning config files... 
copy managed file [<obfuscated>] to file:/var/lib/jenkins/<obfuscated> 
[Pipeline] { 
[Pipeline] readFile 
[Pipeline] echo 
www.testhost.com 
[Pipeline] echo 
www.testhost.com 
[Pipeline] echo 
www.testhost2.com 
[Pipeline] echo 
www.testhost2.com 
[Pipeline] } 
Deleting 1 temporary files 
[Pipeline] // wrap 
[Pipeline] } 
[Pipeline] // node 
[Pipeline] End of Pipeline 
Finished: SUCCESS 

但是,如果我採取某些動作,如'LS -l'它只迭代1次

node{ 
    wrap([$class: 'ConfigFileBuildWrapper', managedFiles: [[fileId: 'dest_hosts.txt', targetLocation: '', variable: 'DEST_HOST']]]) { 
     HOST = Arrays.asList(readFile(env.DEST_HOST).split("\\r?\\n")) 
     deploy(HOST) 
    } 
} 

@NonCPS 
def deploy(host){ 
    for (String target : host){ 
     try { 
      echo target 
     } 
     finally { 
      sh 'ls -l' 
     } 
    } 
} 

OUTPUT(只迭代1次):

[Pipeline] node 
Running on <obfuscated> 
[Pipeline] { 
[Pipeline] wrap 
provisoning config files... 
copy managed file [<obfuscated>] to file:/var/lib/jenkins/<obfuscated> 
[Pipeline] { 
[Pipeline] readFile 
[Pipeline] echo 
www.testhost.com 
[Pipeline] sh 
[sandbox%2Fpipeline-test-new1] Running shell script 
+ ls -l 
total 8 
-rw-r--r-- 1 jenkins jenkins 10 Jun 17 16:07 someFile 
[Pipeline] } 
Deleting 1 temporary files 
[Pipeline] // wrap 
[Pipeline] } 
[Pipeline] // node 
[Pipeline] End of Pipeline 
Finished: SUCCESS 

回答

5
ArrayList

(和通常Lists)不具有的長度或大小字段,它們具有size()方法。因此,使用,在爲:

for (ii = 0; ii < var.size(); ii++) 
+0

謝謝你的作品。雖然我仍然好奇爲什麼上面的2nd for循環只迭代一次,有什麼想法? – mdo123

+0

我現在正在經歷類似的事情。據我所知,這與「sh」呼叫有關。你知道這件事嗎? – pmmaga

+0

@pmmaga沒有抱歉,我沒有想到這一點。我只是使用@ krzyk的答案,但我沒有接受@ krzyk的答案,因爲我認爲答案的一部分應該包括上面描述的行爲的解釋。具體來說,爲什麼每個循環都在finally塊中使用「echo」,但只有在執行sh命令時才迭代一次。我想也許sh cmd正在返回一個非零退出狀態,但每個循環都應該繼續爲每個元素,所以我不確定。 – mdo123

1

我無法準確地告訴你爲什麼,因爲我還沒有想出如何找到有關詹金斯有用的信息,而無需花費數小時谷歌搜索,但我可以告訴你:

有一段時間我以爲你可以通過在sh'echo $ line'之後添加'echo line'來使它運行良好,但是那竟然是由詹金斯運行一個PREVIOUS版本的腳本造成的...

我嘗試了各種各樣的東西,但都沒有工作,然後我發現這個:

Why an each loop in a Jenkinsfile stops at first iteration

其在詹金斯管道中的已知的bug!

(已知的bug是JENKINS-26481,它說「至少一些封鎖只能由工作流程插件管理的Groovy CPS DSL腳本內執行一次」)

2

按照本教程:https://github.com/jenkinsci/pipeline-plugin/blob/master/TUTORIAL.md#serializing-local-variables

...a method marked with the annotation @NonCPS ... will be treated as 「native」 by the Pipeline engine, and its local variables never saved. However it may not make any calls to Pipeline steps

就你而言,sh調用是一個流水線步驟操作,你顯然不能從@NonCPS帶註釋的方法中執行操作。

關於將數組轉換爲List,那麼因爲我們在Groovy的土地上,所以您可以在陣列上使用.toList()方法。