Insert % character in the middle of the string in Groovy - jenkins

My Code snippet below,(running from Jenkins)
def mainUrl = "http://localhost:8080/job/"
...
jobsName.each(){
println "Jobs: ${it}"
println "${mainUrl}${it}/config.xml"
}
Which gives output like below:
Jobs: Env_test
Jobs: Dev_test
Jobs: Model test
Jobs: Prod test
I'm trying to replace the space character with % and used replaceAll method too, still no luck.
println "${mainUrl}${it}.replaceAll("//s","%")/config.xml"
Output I got:
http://localhost:8080/job/Model test.replaceAll(
http://localhost:8080/job/Prod test.replaceAll(
I'm looking for a Output like,
http://localhost:8080/job/Model%test/config.xml
http://localhost:8080/job/Prod%test/config.xml
Any suggestions . Thanks.

Try:
println "${mainUrl}${it.replaceAll('\\s','%')}/config.xml"

Change your code to:
println "${mainUrl}${it}".replaceAll("\\s","%") + "/config.xml"
Taking this apart, it means:
join mainUrl and it (you missed a double quote char after {it}),
replace each space (regex reguires a backslash (not forward slash), but here it should be doubled),
and add /config.xml, but as a separate string.

Related

Jenkins pipeline script to write value of variable in file

I am extracting the username/password from credential store and I am assigning it to a variable. I want to write this value in a file.
I am using the below code:
for (creds in jenkinsCredentials) {
if(creds.id == "credential"){
def password = creds.password
println(creds.username)
println(password)
writeFile file: '\\Jenkins_Home\\workspace\\test\\test.properties', text: 'pass=${password}'
It prints the value of password.
But it just writes pass=${password}, not the value of the password.
How can I write the values of the variable in the file?
Try the double quotes as mentioned by Sriram. He is correct that pipeline groovy script does have issue with single quotes.
Also found sometimes that double quotes can also be an issue and that they have to be escaped (\"). See how you go!
I also have another solution, where you can define the text going into the file as a variable and enclosing the writeFile arguments in brackets, see below:
in jenkinsCredentials) {
if(creds.id == "credential"){
def password = creds.password
println(creds.username)
println(password)
def pass = "pass=" + password
writeFile (file: '\\Jenkins_Home\\workspace\\test\\test.properties', text: pass)
Use double quotes (") instead of single quotes (') as below:
writeFile file: "\\Jenkins_Home\\workspace\\test\\test.properties", text: "pass=${password}"
For some reason, pipeline groovy script has some issue with single quotes(')

Access project parameter in multi line shell script in jenkins pipeline [duplicate]

def a = "a string"
def b = 'another'
Is there any difference? Or just like javascript to let's input ' and " easier in strings?
Single quotes are a standard java String
Double quotes are a templatable String, which will either return a GString if it is templated, or else a standard Java String. For example:
println 'hi'.class.name // prints java.lang.String
println "hi".class.name // prints java.lang.String
def a = 'Freewind'
println "hi $a" // prints "hi Freewind"
println "hi $a".class.name // prints org.codehaus.groovy.runtime.GStringImpl
If you try templating with single quoted strings, it doesn't do anything, so:
println 'hi $a' // prints "hi $a"
Also, the link given by julx in their answer is worth reading (esp. the part about GStrings not being Strings about 2/3 of the way down.
My understanding is that double-quoted string may contain embedded references to variables and other expressions. For example: "Hello $name", "Hello ${some-expression-here}". In this case a GString will be instantiated instead of a regular String. On the other hand single-quoted strings do not support this syntax and always result in a plain String. More on the topic here:
http://docs.groovy-lang.org/latest/html/documentation/index.html#all-strings
I know this is a very old question, but I wanted to add a caveat.
While it is correct that single (or triple single) quotes prevent interpolation in groovy, if you pass a shell command a single quoted string, the shell will perform parameter substitution, if the variable is an environment variable. Local variables or params will yield a bad substitution.

Comparing 2 parameters in Jenkins pipeline in a single command

what is wrong with below code, comparing 2 strings in groovy
I am trying do the comparison between the 2 parameters in a single line to make it look tidier
if (params.dirname == ((params.path =~ ~/${params.dirname}/).with { matches() ? it[0] : null })) {
print success
}
Throwing Exception -
java.lang.NoSuchMethodError: No such DSL method 'matches' found among steps
There is no need to over-complicate your use case. According to:
params.dirname = hde, params.path = /usr/tmp/jenkins/hde/filename.txt or /usr/hde/jenkins/ing/filename.txt or any random path which has hde in it
you are trying to find if given string a contains substring b. It can be done using Java's method String.contains(String substring). Alternatively you can use regular expression for that, but String.contains() just looks a few times simpler to understand what is your intention. Consider following Groovy script:
def params = [
dirname: 'hde',
path: '/usr/tmp/jenkins/hde/filename.txt'
]
// Using String.contains()
if (params.path.contains(params.dirname)) {
println "Path '${params.path}' contains '${params.dirname}'"
}
// Using regular expression
if (params.path ==~ /(.*)${params.dirname}(.*)/) {
println "Path '${params.path}' contains '${params.dirname}'"
}
When you run it both if statements evaluates to true:
Path '/usr/tmp/jenkins/hde/filename.txt' contains 'hde'
Path '/usr/tmp/jenkins/hde/filename.txt' contains 'hde'

Jenkins and Groovy and Regex

I am very new to using groovy. Especially when it comes to Jenkins+Groovy+Pipelines.
I have a string variable that can change from time to time and want to apply a regex to accomodate the 2 or 3 possible results the string may return.
In my groovy code I have:
r = "Some text that will always end in either running, stopped, starting."
def regex = ~/(.*)running(.*)/
assert regex.matches(r)
But I receive an error in the jenkins output:
hudson.remoting.ProxyException: groovy.lang.MissingMethodException: No signature of method: java.util.regex.Pattern.matches() is applicable for argument types: (java.lang.String)
UPDATE:
I was able to create a pretty nifty jenking groovy while loop in a pipeline job i am creating to wait for a remote process using the regex info here and a tip in a different post (How do I iterate over all bytes in an inputStream using Groovy, given that it lacks a do-while statement?).
while({
def r = sh returnStdout: true, script: 'ssh "Insert your remote ssh command that returns text'
println "Process still running. Waiting on Stop"
println "Status returned: $r"
r =~ /running|starting|partial/
}());
Straight-forward would be:
String r = "Some text that will always end in either running, stopped, starting."
assert r =~ /(.*)running(.*)/
If you are only using this regex here you can try the following:
r = "Some text that will always end in either running, stopped, starting."
assert r ==~ /(.*)(running|stopped|starting)\.?$/, "String should end with either running, started or stopped"
Explanation:
(.*) - matches anything
(running|stopped|starting) - matches either running, stopped or starting
\.? - optionally end with a dot expect zero or one occurrence of a dot, but you need to escape it, because the dot is a regex special character
$ - end of the line, so nothing should come after
the ==~ operator is the groovy binary match operator. This will return true if it matches, else false
See this example on regex 101
matches does not receive String.
Try
Pattern.compile("your-regex").matcher("string-to-check").find()

How to get the output of python script executed from a ruby method

I am trying to run a python script from ruby method. I am running this method as a rake task within a Rails app. I am using the solution mentioned here:
def create
path = File.expand_path('../../../../GetOrders', __FILE__)
output = `"python2 " + path + "/parse.py"`
print output
str = JSON.parse(output)
print str
end
EDIT: This works:
output = `python2 #{path}/parse.py`
EDIT2:
Using the python script i am trying to pass a list of dictionaries to the ruby function. The python script looks something like:
import xml.etree.ElementTree as ET
import json
def parse():
tree = ET.parse('response.xml')
root = tree.getroot()
namespaces = {'resp': 'urn:ebay:apis:eBLBaseComponents'}
order_array = root.find("resp:OrderArray", namespaces=namespaces)
detailsList = []
for condition:
details["key1"] = value1
details["key2"] = value2
detailsList.append(details)
output = json.dumps(detailsList)
return output
print parse()
Could someone explain what i am doing wrong and how can I fix this. Thanks
When you do this:
output = `python2 #{path}/parse.py`
output will be assigned the standard output of the python script, but that script isn't writing anything to standard output; the json data that's the return value of the parse() call is simply discarded. You seem to be expecting the execution of the script to have a "return value" that's the return value of the script's last expression, but that's not how processes work.
You probably want to replace the parse() call at the end of the script with print parse().
You are calling this exact line on the shell:
"python2 -path- /parse.py"
which the shell interprets as a single command: python2 (with a space at the end).
Try using string interpolation, which works with the backtick operator:
output = `python2 #{path}/parse.py`
Imagine typing this exact string:
"python2 " + path + "/parse.py"
into your shell (e.g. bash). It would look for a program named "python2 " and give it four arguments
+
path
+
/parse.y
You can't put arbitrary Ruby code inside a backtick string the same way you can't put arbitrary code in normals strings. You must use string interpolation.

Resources