TeamCity - passing parameter values with whitespace to command line - teamcity

I'm passing some TeamCity parameters to the command line build step. The problem comes when the parameter value contains spaces, e.g.:
%env.TEAMCITY_BUILDCONF_NAME% ---> My TC Project
Is there a way to replace white spaces with some other character, for example underscore?
%env.TEAMCITY_BUILDCONF_NAME% ---> My_TC_Project

You can typically keep using the white spaces if you wrap the parameter in double quotes:
%program.files.dir% => C:\Program Files (x86)
Executable: dir
Parameters: "%program.files.dir%"

I don't know how to replace spaces with underscore, but I had an issue with whitespaces.
In a TeamCity build step, I was trying to run an sqlcmd as Executable with Parameters
-S %sql_server% -U %sql_username% -P %sql_password%
-i "custom_script.sql" -d "%custom_db%"
-v DealerName="%DealerName%"
where DealerName was "Great Dealer Ltd" but it didn't work with white spaces, even with double quotes.
It fixed the issue by setting it as a Custom Script like
sqlcmd -S %sql_server% -U %sql_username% -P %sql_password%
-i "custom_script.sql" -d "%custom_db%"
-v DealerName="%DealerName%"
and (thanks to my boss suggestion) it worked like charm.
Even if is not the precise answer to your question, it could be useful for similar issues.

String given below worked for me.
%env.TEAMCITY_BUILDCONF_NAME% ---> "My\ TC\ Project"

Related

Dynamicly build string path for curl capath

Curl has the option to add capath as one of its arguments.
This argument can contain one path or several paths in this format:
curl --capath /certs/path1:/certs/path2:/certs/path3 https://domain.com
Is it possible to use curl capath arg with subfolders by only adding the root dir such as /certs/ ?
And if not i would like to build the string which automatically expands to this
format: /certs/path1:/certs/path2:/certs/path3
When i echo this command :
echo /certs/*
/certs/path1 /certs/path2 /certs/path3
required output:
/certs/path1:/certs/path2:/certs/path3
The idea is to have some automatic expanding method that will do that without sed awk or external tool.
something like this:
curl --capath /certs/*{:} https://domain.com
will automatlcy result with :
curl --capath /certs/path1:/certs/path2/:/certs/path3 https://domain.com
Unfortunately, I don't see any way to do it without an externl program.
Well, you could do
for s in /certs/*
do
path+="$s:"
done
But I don't think you are looking for this.
The point is that you are using the wildcard character '*' and it is interpreted by your shell as a list of string, separated with space.
Else just put in a variable
var=`/certs/* | tr ' ' ':'`
Hope this will answer. And if someone can find a real solution, then I want to know it too =)

sed / Batch / Windows: Prevent changig Backslash to slash

I have a variable with a path, like this:
SET "somevar=D:\tree\path\nonsens\oink.txt"
And I have a file, where somethink like this is written
VAR=moresonsense
Now I want to replace the word morenonsense to D:\tree\path\nonsens\oink.txt. This should be the result
VAR=D:\tree\path\nonsens\oink.txt
For this, I am using the tool sed for windows. But using sed in windows gives me the following:
VAR=D: ree/path/nonsens/oink.txt
The spaces between the colon and ree is a tab. I thought, I could fix it with the following line before calling sed:
SET "somevar=%somevar:\\=\\\\%"
But no, this line is not working. So I have some questions:
Is there a possibility, to prevent sed from changing \t to a tab and prevent changing two backslashed \ to a slash /?
Is there another easy way to replace a string with another string within a file with BATCH?
Does someone has another idea how to resolve this problem?
You should not \-escape the \ instances in the variable expansion; use the following:
SET "somevar=%somevar:\=\\%"
I don't know whether that solves all your problems, but SET "somevar=%somevar:\\=\\\\%" definitely does not work as intended, because it'll only match two consecutive \ chars in the input, resulting in a no-op with your input.

Understanding 'sed' command

I am currently trying to install GCC-4.1.2 on my machine: Fedora 20.
In the instruction, the first three commands involve using 'sed' commands, for Makefile modification. However, I am having difficulty in using those commands properly for my case. The website link for GCC-4.1.2.
The commands are:
sed -i 's/install_to_$(INSTALL_DEST) //' libiberty/Makefile.in &&
sed -i 's#\./fixinc\.sh#-c true#' gcc/Makefile.in &&
sed -i 's/#have_mktemp_command#/yes/' gcc/gccbug.in &&
I am trying to understand them by reading the 'sed' man page, but it is not so easy to do so. Any help/tip would be appreciated!
First, the shell part: &&. That just chains the commands together, so each subsequent line will only be run if the prior one is run successfully.
sed -i means "run these commands inline on the file", that is, modify the file directly instead of printing the changed contents to STDOUT. Each sed command here (the string) is a substitute command, which we can tell because the command starts with s.
Substitute looks for a piece of text in the file, and then replaces it. So the order is always s/needle/replacement/. See how the first and last lines have those same forward-slashes? That's the traditional delimiter between the command (substitute), the needle to find in the haystack (install_to_$(INSTALL_DEST), and the text to replace it with ().
So, the first one looks for the string and deletes it (the empty replacement). The last one looks for #have_mktemp_command# and replaces it with yes.
The middle one is a bit weird. See how it starts with s# instead of s/? Well, sed will let you use any delimiter you like to separate the needle from the replacement. Since this needle had a / in it (\./fixinc\.sh), it made sense to use a different delimiter than /. It will replace the text ./fixinc.sh with -c true.
Last note: Why does the second needle have \. instead of .? Well, in a Regular Expression like the needle is (but not used in your example), some characters are magical and do magical fairy dust operations. One of those magic characters is .. To avoid the magic, we put a \ in front of it, escaping away from the magic. (The magic is "match any character", and we want a literal period. That's why.)

Shell string with double quotes - RTC command

I am trying to run a RTC 4.x command to add components to a workspace. The list of components have spaces in the names so they need to be surrounded by quotes. I am storing this list in a simple string variable:
COMPONENTS="\"TestComp\" \"Common Component\""
When I just echo out COMPONENTS it displays correctly, but when I use it in a scm command odd things happen to the quotes. I am running this in Jenkins so I can get some additional output, but the same thing happens when I run it on the command line so this is not a Jenkins issue.
From the console log:
+ COMPONENTS='"TestComp" "Common Component"'
+ echo '"TestComp"' '"Common' 'Component"'
"TestComp" "Common Component"
The command is trying to run the following:
+ scm workspace add-components TEST_Workspace -s Test_Stream '"TestComp"' '"Common' 'Component"'
Which produces:
Problem running 'workspace add-components':
Unmatched component ""Common".
Typically, you need to use an array to store items that may themselves contain whitespace:
components=("TestComp" "Common Component")
scm workspace add-components TEST_Workspace -s Test_Stream "${components[#]}"
Quoting an array expansion indexed with # produces a sequence of words, one per element of the array, rather than a single word.

Modifying Jenkins Description for a build

I would like to remotely change a Jenkins build description. I have my script all set and ready except for one tiny problem: Multiple line descriptions.
I am using the REST API and JSON in Jenkins to download the old description:
old_description=$(curl -s --user "$USER:$PASSWORD" --data-urlencode "tree=description" \
"$jenkins_url/job/$job_name/$build_number/api/json")
old_description=${old_description#*:\"} #Remove JSON garbage
old_description=${old_description%\"\}} #Remove JSON garbage
The `curl command pulls out:
<font color=blue><b>At first you don't succeed. Try again</b></font><br/>
\r\n<font color=gold><b>At first you don't succeed. Try again</b></font><br/>
\r\n<font color=green><b>At first you don't succeed. Try again</b></font>
(Note: I added line breaks to make the above easier to read. This is pulled out as a single line).
The \r\n are separate lines, so I do this:
old_description=$(sed 's/\\r\\n/\
/g' <<<$old_description)
And that changes $old_description to:
font color=blue><b>At first you don't succeed. Try again</b></font><br/>
<font color=gold><b>At first you don't succeed. Try again</b></font><br/>
<font color=green><b>At first you don't succeed. Try again</b></font>
(NOTE: The new lines are part of the value. This is a three line description.)
My program (depending upon the command line parameters) can replace, append, or prepend a new description to the build:
if [ "$prepend_flag" -a -n "$old_description" ] #Prepend new description to old description
then
new_description="$new_description<br/>
$old_description"
elif [ "$append_flag" -a -n "$old_description" ] #Append new description to old description
then
new_description="$old_description<br/>
$new_description"
fi
Now, I'll redo the description:
if curl -u $USER:$PASSWORD --data-urlencode "description=$new_description" \
--data-urlencode "Submit=Submit" \
"$jenkins_url/job/$job_name/$build_number/submitDescription"
then
echo "Description successfully changed on Build #$build_number in Jenkins job $job_name"
else
echo "WARNING: Description was not set. Manually change the descripiton of the build"
echo " for Build #$build_number in Jenkins job $job_name"
fi
If I am prepending or appending the new description the first time, I get this in Jenkins:
<font color=blue><b>At first you don't succeed. Try again</b></font><br/>
<font color=gold><b>At first you don't succeed. Try again</b></font><br/>
<font color=green><b>At first you don't succeed. Try again</b></font><br/>
<font color=red><b>My new description</b></font><br/>
Looks nice. The next time, it doesn't work. I get this:
<font color=blue><b>At first you don't succeed. Try again</b></font><br/>\n<font color=gold><b>At first you don't succeed. Try again</b></font><br/>\n<font color=green><b>At first you don't succeed. Try again</b></font><br/>\n<font color=red><b>My new description</b></font><br/>
<font color=blue><b>My new new description</b></font>
Note the \n showing up.
How can I fix this issue?
I've put the whole program in pastebin.
I played around with this for a long while...
First, instead of doing this:
new_description="$new_description<br/>
$old_description"
to append or prepend the line, I used printf:
new_description="$(printf "$new_description\r\n$old_description")"
By using printf, I put a <CR><LF> instead of just a <LF> in my description line separator. This way, I don't have a jumble of <NL> and <CR><NL> and I'm no longer dependent upon the operating system's definition of the line break.
The sed command took me a long, long time to figure out. I tried all sorts of things:
old_description=$(sed 's/\\r\\n/\r\n/g' <<<$old_description)
But, nothing seemed to work... I tried the -E flag which allows me to use the extended regular expressions, but it kept interpreting \r\n as replacing \\r\\n with literal 'rn.
After several hours of this, I finally tried double quotation marks instead of single quotation marks:
old_description=$(sed "s/\\r\\n/\r\n/g" <<<$old_description)
That worked! You normally use single quotation marks with sed to protect the regular expression from interpolation. However, the single quotes were also killing the interpolation of \r\n as <CR><LF>. Changing them with double quotes solved the problem.

Resources