skip to content
blog.metters.dev

Jenkins Pipeline insight: Trim shell command outputs

/ 2 min read

This article refers to an experience I had while adding a new Jenkins Pipeline. There was a helper method with a regular expression to check the name of the current branch for the occurrence of a specific word. Let’s say it was supposed to check whether the branch is a bugfix branch. The helper method always returned false and it was the regular expression I blamed, naturally.

Boolean isBugfixBranch() {
def currentBranchName = sh(script: "git rev-parse --abbrev-ref HEAD", returnStdout: true)
def matcher = currentBranchName =~ /^(bugfix\/)(ISSUE-[0-9]{1,6})([\/-])(.*)$/
return matcher.matches()
}

I investigated the regex on regexr.com, but all it confirmed was that the expression was solid. Simplifying the regex, e.g. to .* also did not work. The mystery was solved rather coincidentally, because other shell commands already had trim() appended. Well, there must be a reason for that, I figured. And it worked.

What is the reason to trim results in shell commands? Let’s look at the following snippet:

void replaceWithUnderscore() {
def currentBranchName = sh(script: "git rev-parse --abbrev-ref HEAD", returnStdout: true).replaceAll("\\s", "_")
print(currentBranchName)
}

Only after replacing any whitespace character, it becomes obvious that there is in fact a trailing linebreak, which messes with the expected pattern for the regex. My helper function should have used trim() after the script execution:

Boolean isBugfixBranch() {
def currentBranchName = sh(script: "git rev-parse --abbrev-ref HEAD", returnStdout: true).trim()
def matcher = currentBranchName =~ /^(bugfix\/)(ISSUE-[0-9]{1,6})([\/-])(.*)$/
return matcher.matches()
}