在 Jenkinsfile (Groovy) 中获取给定文件夹中的文件名列表 [英] Get a list of filenames in a given folder in Jenkinsfile (Groovy)

查看:23
本文介绍了在 Jenkinsfile (Groovy) 中获取给定文件夹中的文件名列表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我无法在脚本化的 Jenkins 流水线中的给定目录中创建简单的文件名列表.我尝试了许多在 SO 和其他论坛上发布的 Groovy 脚本示例,但要么该功能被阻止,要么我找不到方法或其他什么.

I cannot create a simple list of filenames in a given directory in a scripted Jenkins Pipeline. I tried many Groovy Script examples posted on SO and other forums but either the feature is blocked or I get method not found or whatever.

这似乎是最简单的

def DOCKER_FILES_DIR = './dockerfiles'
// ...
def dir = new File(DOCKER_FILES_DIR);
def dockerfiles = [];
dir.traverse(type: FILES, maxDepth: 0) {
    dockerfiles.add(it)
}

但是这会错误地解析相对路径,所以我得到了这个错误:

But this resolves the relative path incorrectly, so I get this error:

java.io.FileNotFoundException: /./dockerfiles

我也尝试将其包装在 dir 中:

I also tried to wrap it in dir with:

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)
    }
}

但得到了同样的错误:

java.io.FileNotFoundException: /./dockerfiles

这不会报错,只是将一个文件添加到列表中:

This does not give an error, but only adds one file to the list:

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 的内容会丢失除第一个文件以外的所有文件:

The contents of dockerfiles is then missing all the files but the first one:

['py365']

这是在 Jenkins 中重现它的最小流水线:

Here is a minimal Pipeline to reproduce it in Jenkins:

#!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:

And the output, showing that only bar1 is printed:

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 如何执行您的管道代码,甚至通常都能正常工作.

You can't really make use of the new File and normal Groovy/Java ways to traverse file systems. The call is security checked by default (see JENKINS-38131) and won't even generally work because of how Jenkins Pipelines executes your pipeline code.

您可以这样做的一种方法是使用 的工作区" rel="noreferrer">findFiles 步骤管道实用程序步骤插件.它返回一个 FileWrapper[] 可以检查/用于其他目的.

One way you could do this would be to use the findFiles step from the Pipeline Utility Steps plugin. It returns a FileWrapper[] which can be inspected/used for other purposes.

node {
  // ... check out code, whatever
  final foundFiles = findFiles(glob: 'dockerfiles/**/*')
  // do things with FileWrapper[]
}

另一种选择是脱壳并捕获标准输出:

Another option is to shell out and capture the standard out:

node {
  // ... check out code, whatever
  final foundFiles = sh(script: 'ls -1 dockerfiles', returnStdout: true).split()
  // Do stuff with filenames
}

这篇关于在 Jenkinsfile (Groovy) 中获取给定文件夹中的文件名列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆