How to use Jenkins local defined variable in IF statement? - jenkins

I have below code
def result = readFile('res.txt')
echo "${result}"
if ("${result}" > 5 )
{
echo "Yes"
} else {
echo "No"
}
}
It is printing NO but the answer in ${result} -> 11 which means it should print Yes. Can u pls help.

As noted in comments - you should cast the result to integer. Both result.toInteger() and Integer.parseInt(result) will work, although the first one is more straightforward and doesn't complain about extra white space (e.g. trailing endline character).
Besides, you don't need to mess with strange constructs like "${result}" because result is a normal variable, so your code may look like this:
def result = readFile('res.txt')
echo "${result}"
if (result.toInteger() > 5 ) {
echo "Yes"
} else {
echo "No"
}

Related

How to convert a jenkins boolean param into all caps "TRUE" or "FALSE" string parameter?

I have the following defined in my multibranch declarative pipeline:
steps {
script {
BUILD_PROD_FLAG = sh(returnStdout: true, script: "[ ${BUILD_PROD} = true ] && echo TRUE || echo FALSE; ").trim()
BUILD_PROD_FLAG_SECOND = expression { if (params.BUILD_PROD) { return "TRUE" } else { return "FALSE" } }
}
sh "echo alternative way to get true/false set (want this to say FALSE): ${BUILD_FLAG_SECOND}"
}
The first variable BUILD_PROD_FLAG works fine.
I would like to eliminate the convoluted bash spawning employed there.
The second one does not work:
Multibranch_PR-1#tmp/durable-212f3652/script.sh: 1: /home/ubuntu/workspace/s_InsightCamera_Multibranch_PR-1#tmp/durable-212f3652/script.sh: Syntax error: "(" unexpected
This apparently is due to
Which I am not able to comprehend.
When the expression block is removed it fails to parse:
org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
WorkflowScript: 67: unexpected token: if # line 67, column 57.
BUILD_FLAG_SECOND = if (params
^
1 error
And when I tried something else that is different:
BUILD_FLAG_SECOND = expression { return params.BUILD_PROD ? "TRUE" : "FALSE" }
I get the same Syntax error: "(" unexpected error. I don't understand why this is a .sh shell script, by the way.
Update: OK I think I get why it's a .sh, that's just the sh clause near the bottom that I have.
I also thought I solved it because I did neglect to quote things for the shell, but with the adjustment:
sh "echo 'alternative way to get true/false set (want this to say FALSE):' ${BUILD_FLAG_SECOND}"
Still the same error:
I think it is for real trying to interpolate the string #expression(<anonymous>=org.jenkinsci.plugins.workflow.cps.CpsClosure2#4a286654) in place of the BUILD_FLAG_SECOND variable...
Are you ready for the epic facepalm that is the solution?
BUILD_FLAG_SECOND = params.BUILD_PROD ? "TRUE" : "FALSE"
That's it.

stumped by simple groovy variable comparison

I have a groovy script (a Jenkins pipeline) and a simple variable comparison is not working like I expect. I have a class defined to hold some constants, like this:
class email_when {
static final int ON_FAILURE = 0
static final int ALWAYS = 1
}
At a certain point in the script I set an environment variable to one of these states, like this:
env.EMAIL_WHEN = email_when.ALWAYS
Then later, I check the value. This check is always failing and I don't understand why.
echo ("email when = "+env.EMAIL_WHEN+ " always = "+email_when.ALWAYS);
if (env.EMAIL_WHEN == email_when.ALWAYS)
{
echo ("Send email.")
}
else
{
echo ("NO EMAIL")
}
So this always prints
email when = 1 always = 1
NO EMAIL
I don't understand why?
I thought maybe it was some sort of object/value comparison thing? Although I am directly setting env.EMAIL_WHEN to email_when.ALWAYS.
I tried this and it still did the same thing:
if (env.EMAIL_WHEN.equals(email_when.ALWAYS))
Can anyone explain what I am missing?
Thanks!
Everything in env map automatically converted to String
so 1 != '1'

Checking for null pointer exception in an array in Jenkins scripted pipeline method

I am injecting Active Choices parameter value(s) in the Jenkins scripted pipeline.
PFB sample values passed to active choice parameter block:
return['ABC','DEF','GHI',JKL']
PFB my sample script:
node(){
selectModName()
}
def selectModName(){
stage 'Multi selection'
String[] mods = "${modName}".split(',')
modsz = mods.size()
echo ''+modsz+''
for(mod in mods){
if (modsz == null || modsz == 0){
echo 'There is nothing to be printed'
} else {
echo ''+mod+' is name of the module \n'
}
}
}
The else block is executed when I pass greater than or equal to 1 value(s) (working as intended). But if block is not executing its logic when I don't pass any parameter and press build now.
Funny thing is- size() is returning 1 instead of 0 (echo ''+modsz+'') when values aren't passed.
How to make if block execute its logic when no values are passed?
Your code always jumps to the "else" block, because
"".split(',')
produces an array with a single empty string.
assert "".split(',').size() == 1
assert "".splti(',') == [""] as String[]
When you use active choice parameter with multiple values selection and you don't select anything, your variable name stores an empty string. You should check first if the modName parameter is not an empty string and only otherwise split and display values.
node(){
selectModName()
}
def selectModName(){
stage 'Multi selection'
if (modName) {
String[] mods = modName?.split(',')
for (mod in mods) {
echo " ${mod} is name of the module"
}
} else {
echo 'There is nothing to be printed'
}
}

ob_get_clean and ob_get_contents return content to screen instead of putting it into variable when used with var_dump

I use this function for debugging:
function d($v,$tofile=null) {
static $wasused;
ob_start();
var_dump($v);
$dump = ob_get_clean();
if (is_array($v)) $dump = preg_replace("#=>\n#",'=>',$dump);
if (strlen($dump)>1000 or $tofile) {
fileput('debug.txt',$dump,$wasused);
echo n.n."strlen=".strlen($dump)." >> debug.txt".n.n;
}
elseif (strlen($dump)<80) echo $dump;
else echo n.n.$dump.n.n;
$wasused=true;
}
the problem is it sometimes return content to console, particularly when this content is var_dump result on a big array,
anyone of you have seen this problem before ?
If this is in your php.ini:
implicit_flush = On
change it to this:
implicit_flush = Off
Before assuming that there is a problem with var_dump itself, one would need to verify that fileput() does exactly what the question implies.

How to find functions in a cpp file that contain a specific word

using grep, vim's grep, or another unix shell command, I'd like to find the functions in a large cpp file that contain a specific word in their body.
In the files that I'm working with the word I'm looking for is on an indented line, the corresponding function header is the first line above the indented line that starts at position 0 and is not a '{'.
For example searching for JOHN_DOE in the following code snippet
int foo ( int arg1 )
{
/// code
}
void bar ( std::string arg2 )
{
/// code
aFunctionCall( JOHN_DOE );
/// more code
}
should give me
void bar ( std::string arg2 )
The algorithm that I hope to catch in grep/vim/unix shell scripts would probably best use the indentation and formatting assumptions, rather than attempting to parse C/C++.
Thanks for your suggestions.
I'll probably get voted down for this!
I am an avid (G)VIM user but when I want to review or understand some code I use Source Insight. I almost never use it as an actual editor though.
It does exactly what you want in this case, e.g. show all the functions/methods that use some highlighted data type/define/constant/etc... in a relations window...
(source: sourceinsight.com)
Ouch! There goes my rep.
As far as I know, this can't be done. Here's why:
First, you have to search across lines. No problem, in vim adding a _ to a character class tells it to include new lines. so {_.*} would match everything between those brackets across multiple lines.
So now you need to match whatever the pattern is for a function header(brittle even if you get it to work), then , and here's the problem, whatever lines are between it and your search string, and finally match your search string. So you might have a regex like
/^\(void \+\a\+ *(.*)\)\_.*JOHN_DOE
But what happens is the first time vim finds a function header, it starts matching. It then matches every character until it finds JOHN_DOE. Which includes all the function headers in the file.
So the problem is that, as far as I know, there's no way to tell vim to match every character except for this regex pattern. And even if there was, a regex is not the tool for this job. It's like opening a beer with a hammer. What we should do is write a simple script that gives you this info, and I have.
fun! FindMyFunction(searchPattern, funcPattern)
call search(a:searchPattern)
let lineNumber = line(".")
let lineNumber = lineNumber - 1
"call setpos(".", [0, lineNumber, 0, 0])
let lineString = getline(lineNumber)
while lineString !~ a:funcPattern
let lineNumber = lineNumber - 1
if lineNumber < 0
echo "Function not found :/"
endif
let lineString = getline(lineNumber)
endwhile
echo lineString
endfunction
That should give you the result you want and it's way easier to share, debug, and repurpose than a regular expression spit from the mouth of Cthulhu himself.
Tough call, although as a starting point I would suggest this wonderful VIM Regex Tutorial.
You cannot do that reliably with a regular expression, because code is not a regular language. You need a real parser for the language in question.
Arggh! I admit this is a bit over the top:
A little program to filter stdin, strip comments, and put function bodies on the same line. It'll get fooled by namespaces and function definitions inside class declarations, besides other things. But it might be a good start:
#include <stdio.h>
#include <assert.h>
int main() {
enum {
NORMAL,
LINE_COMMENT,
MULTI_COMMENT,
IN_STRING,
} state = NORMAL;
unsigned depth = 0;
for(char c=getchar(),prev=0; !feof(stdin); prev=c,c=getchar()) {
switch(state) {
case NORMAL:
if('/'==c && '/'==prev)
state = LINE_COMMENT;
else if('*'==c && '/'==prev)
state = MULTI_COMMENT;
else if('#'==c)
state = LINE_COMMENT;
else if('\"'==c) {
state = IN_STRING;
putchar(c);
} else {
if(('}'==c && !--depth) || (';'==c && !depth)) {
putchar(c);
putchar('\n');
} else {
if('{'==c)
depth++;
else if('/'==prev && NORMAL==state)
putchar(prev);
else if('\t'==c)
c = ' ';
if(' '==c && ' '!=prev)
putchar(c);
else if(' '<c && '/'!=c)
putchar(c);
}
}
break;
case LINE_COMMENT:
if(' '>c)
state = NORMAL;
break;
case MULTI_COMMENT:
if('/'==c && '*'==prev) {
c = '\0';
state = NORMAL;
}
break;
case IN_STRING:
if('\"'==c && '\\'!=prev)
state = NORMAL;
putchar(c);
break;
default:
assert(!"bug");
}
}
putchar('\n');
return 0;
}
Its c++, so just it in a file, compile it to a file named 'stripper', and then:
cat my_source.cpp | ./stripper | grep JOHN_DOE
So consider the input:
int foo ( int arg1 )
{
/// code
}
void bar ( std::string arg2 )
{
/// code
aFunctionCall( JOHN_DOE );
/// more code
}
The output of "cat example.cpp | ./stripper" is:
int foo ( int arg1 ) { }
void bar ( std::string arg2 ){ aFunctionCall( JOHN_DOE ); }
The output of "cat example.cpp | ./stripper | grep JOHN_DOE" is:
void bar ( std::string arg2 ){ aFunctionCall( JOHN_DOE ); }
The job of finding the function name (guess its the last identifier to precede a "(") is left as an exercise to the reader.
For that kind of stuff, although it comes to primitive searching again, I would recommend compview plugin. It will open up a search window, so you can see the entire line where the search occured and automatically jump to it. Gives a nice overview.
(source: axisym3.net)
Like Robert said Regex will help. In command mode start a regex search by typing the "/" character followed by your regex.
Ctags1 may also be of use to you. It can generate a tag file for a project. This tag file allows a user to jump directly from a function call to it's definition even if it's in another file using "CTRL+]".
u can use grep -r -n -H JOHN_DOE * it will look for "JOHN_DOE" in the files recursively starting from the current directory
you can use the following code to practically find the function which contains the text expression:
public void findFunction(File file, String expression) {
Reader r = null;
try {
r = new FileReader(file);
} catch (FileNotFoundException ex) {
ex.printStackTrace();
}
BufferedReader br = new BufferedReader(r);
String match = "";
String lineWithNameOfFunction = "";
Boolean matchFound = false;
try {
while(br.read() > 0) {
match = br.readLine();
if((match.endsWith(") {")) ||
(match.endsWith("){")) ||
(match.endsWith("()")) ||
(match.endsWith(")")) ||
(match.endsWith("( )"))) {
// this here is because i guessed that method will start
// at the 0
if((match.charAt(0)!=' ') && !(match.startsWith("\t"))) {
lineWithNameOfFunction = match;
}
}
if(match.contains(expression)) {
matchFound = true;
break;
}
}
if(matchFound)
System.out.println(lineWithNameOfFunction);
else
System.out.println("No matching function found");
} catch (IOException ex) {
ex.printStackTrace();
}
}
i wrote this in JAVA, tested it and works like a charm. has few drawbacks though, but for starters it's fine. didn't add support for multiple functions containing same expression and maybe some other things. try it.

Resources