我无法在脚本化的Jenkins Pipeline中的给定目录中创建文件名的简单列表。我尝试了在SO和其他论坛上发布的许多Groovy Script示例,但是该功能被阻止或找不到方法或其他方法。
这似乎是最简单的
def DOCKER_FILES_DIR = './dockerfiles' // ... def dir = new File(DOCKER_FILES_DIR); def dockerfiles = []; dir.traverse(type: FILES, maxDepth: 0) { dockerfiles.add(it) }
但这会错误地解决相对路径,因此出现此错误:
java.io.FileNotFoundException: /./dockerfiles
我还尝试用以下方法包装它dir:
dir
def DOCKER_FILES_DIR = './dockerfiles' // ... def dockerfiles = []; dir("${env.WORKSPACE}"){ def dir = new File(DOCKER_FILES_DIR); dir.traverse(type: FILES, maxDepth: 0) { dockerfiles.add(it) } }
但是有同样的错误:
这不会产生错误,只会将一个文件添加到列表中:
def DOCKER_FILES_DIR = './dockerfiles' // ... def dockerfiles = []; def dir = new File("${env.WORKSPACE}/${DOCKER_FILES_DIR}"); dir.traverse(type: FILES, maxDepth: 0) { dockerfiles.add(it.getName()) }
dockerfiles然后,除第一个文件外,所有文件的内容都会丢失:
dockerfiles
['py365']
这是在詹金斯中重现它的最小管道:
#!groovy import static groovy.io.FileType.FILES node('master') { FILES_DIR = './foo' cleanWs() sh """ mkdir foo touch foo/bar1 touch foo/bar2 touch foo/bar3 """ def filenames = []; def dir = new File("${env.WORKSPACE}/${FILES_DIR}"); dir.traverse(type: FILES, maxDepth: 0) { filenames.add(it.getName()) } for (int i = 0; i < filenames.size(); i++) { def filename = filenames[i] echo "${filename}" } }
输出显示仅bar1打印:
bar1
Started by user Tamas Gal Running in Durability level: MAX_SURVIVABILITY [Pipeline] node Running on Jenkins in /var/lib/jenkins/workspace/TestHome [Pipeline] { [Pipeline] cleanWs [WS-CLEANUP] Deleting project workspace...[WS-CLEANUP] done [Pipeline] sh [TestHome] Running shell script + mkdir foo + touch foo/bar1 + touch foo/bar2 + touch foo/bar3 [Pipeline] echo bar1 [Pipeline] } [Pipeline] // node [Pipeline] End of Pipeline Finished: SUCCESS
您不能真正使用new File常规的Groovy / Java方式遍历文件系统。该调用默认情况下经过安全检查(请参阅JENKINS-38131),并且由于Jenkins Pipelines如何执行您的管道代码,因此该呼叫通常无法正常工作。
new File
你可以做到这一点的一种方法是使用findFiles从步骤 管道实用程序步骤 插件。它返回一个FileWrapper[]可以检查/用于其他目的的。
findFiles
FileWrapper[]
node { // ... check out code, whatever final foundFiles = findFiles(glob: 'dockerfiles/**/*') // do things with FileWrapper[] }
另一种选择是掏空并捕获标准:
node { // ... check out code, whatever final foundFiles = sh(script: 'ls -1 dockerfiles', returnStdout: true).split() // Do stuff with filenames }