代码之家  ›  专栏  ›  技术社区  ›  tamasgal

获取jenkinsfile(groovy)中给定文件夹中的文件名列表

  •  5
  • tamasgal  · 技术社区  · 7 年前

    我无法在脚本化的Jenkins管道中的给定目录中创建简单的文件名列表。我尝试了许多发布在So和其他论坛上的groovy脚本示例,但要么功能被阻塞,要么找不到方法,要么什么都没有。

    这似乎是最简单的

    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 用:

    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 除了第一个文件外,还缺少所有文件:

    ['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 打印时间:

    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
    
    2 回复  |  直到 7 年前
        1
  •  20
  •   mkobit    7 年前

    你不能真正利用 new File 和常规的Groovy/Java方法来遍历文件系统。默认情况下,调用是安全检查的(请参见 JENKINS-38131 )因为Jenkins管道是如何执行管道代码的,所以它甚至不能正常工作。

    一种方法是使用 findFiles Pipeline Utility Steps plugin . 它返回一个 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
    }
    
        2
  •  3
  •   tamasgal    7 年前

    这一个有效,但它是丑陋的地狱:

    #!groovy
    
    node('master') {
        FILES_DIR = './foo'
        cleanWs()
    
        sh """
            mkdir foo
            touch foo/bar1
            touch foo/bar2
            touch foo/bar3
        """
    
        def TMP_FILENAME = ".docker_files_list"
        sh "ls ${FILES_DIR} > ${TMP_FILENAME}"
        def filenames = readFile(TMP_FILENAME).split( "\\r?\\n" );
        sh "rm -f ${TMP_FILENAME}"
    
        for (int i = 0; i < filenames.size(); i++) {
            def filename = filenames[i]
            echo "${filename}"
        }
    }