I am trying to get all the directories that are under one directory(deployment) by using groovy(in Jenkins pipeline). To do this I used the following code snippet.
def currentDir = new File("${WORKSPACE}/deployment")
currentDir.eachFile FileType.DIRECTORIES, {
println it.name
}
After executing this I am only receiving one directory even though there are several directories.
I tried another code snipped which gave me the entire path of the directory. But still here also I am only getting one directory path even though there are several directories.
def dir = new File("${WORKSPACE}/deployment")
dir.eachFileRecurse (FileType.DIRECTORIES) { directory ->
println directory
}
What I actually want is the 1st solution but with all the directories. Am I doing something wrong here? Is there a setting on Jenkins pipeline to make sure that all the directories are getting visible? Please note I also allowed In Script Approval
in order to execute this.
CodePudding user response:
There are several problems with the code:
- Groovy methods like
.each*
,.find*
and similar ones that iterate over collections can be problematic in pipeline code. - The code will fail when trying to execute on a different node than "master". Groovy/Java code always runs on master, so it doesn't have direct access to
WORKSPACE
directory on another node. The code would try to find the directory on the master instead of the current node.
Unfortunately there is no built-in Jenkins function to iterate over directories (findFiles
only iterates over files).
A good workaround is to use shell code:
// Get directory names by calling shell command
def shOutput = sh( returnStdout: true, script: 'find * -maxdepth 0 -type d' )
// Split output lines into an array
def directories = shOutput.trim().split('\r?\n')
// Make sure to use "for" instead of ".each" to work around Jenkins bugs
for( name in directories ) {
println name
}
By passing returnStdout: true
to the sh
step it will return the standard output of the command. Use trim()
to strip any extraneous line breaks from the end and split()
to create an array from the output lines.
Here is the PowerShell version of that code (it's mostly the same except for the first line):
// Get directory names by calling shell command
def shOutput = powershell( returnStdout: true, script: '(Get-ChildItem -Directory).Name' )
// Split output lines into an array
def directories = shOutput.trim().split('\r?\n')
// Make sure to use "for" instead of ".each" to work around Jenkins bugs
for( name in directories ) {
println name
}