0

There is a job which will run daily to collect some info on Jenkins.
For debug, I will print one ArrayList to Jenkins console for possible further debug.
So I run inspect() to print it, and find it's not working as expected.
If all the elements of an array and keys/values of a map are all quoted, I can directly copy paste the output to somewhere else for debug.

Short demo:

// Code
def hz = "3.90GHz"
def info = [["CPU": "CPU @ ${hz}"], ['HOST_OS':"Debian"]]
println(info.inspect())
// Output
[['CPU':CPU @ 3.90GHz], ['HOST_OS':'Debian']]

I find the value of "CPU" is not quoted. My current fix(Add toString() to the GString):

// Code
def hz = "3.90GHz"
def info = [["CPU": "CPU @ ${hz}".toString()], ['HOST_OS':"Debian"]]
println(info.inspect())
// Output
[['CPU':'CPU @ 3.90GHz'], ['HOST_OS':'Debian']]

I get two questions:

  1. inspect() seems not woking well with GString, is this expected, or a bug? Seems from the InvokerHelper class, run inspect() on "GString", it will run return arguments.toString();, so no quotes.
  2. Is there a better solution, other than adding toString() to GString?

Thanks in advance.

MadHatter
  • 301
  • 3
  • 12
  • 1
    in groovy v4+ gstring is quoted. so, probably it's a bug in version of groovy that you are using. – daggett Jun 27 '23 at 03:47
  • @daggett Thanks a lot for the info, indeed we're using an older version here 3.x. I'll check the 4.x version and whether we should upgrade the groovy version in Jenkins. – MadHatter Jun 27 '23 at 05:06
  • @daggett Veried, in groovy version "4.0.2", it check whether the source to be inspected is instanceof CharSequence and then deals with it. In the older version 3.x it only checks whether the source is instanceof String, no CharSequence check. The "inspect()" function is working as expected in 4.x. Thanks again for your info. – MadHatter Jun 27 '23 at 05:59

1 Answers1

0

Thanks for the info from @daggett, find out groovy 3.x and 4.x have different inspect() methods.
In 3.0.11, inside InvokerHelper class, it only checks for String, GString is not checked:

if (arguments instanceof String) {
    // xxx
}
try {
    return arguments.toString();
} catch (RuntimeException ex) {
    // xxx
} catch (Exception ex) {
    // xxx
}

And in 4.0.2 inside FormatHelper class, it checks for CharSequence which contains both String and GString:

String DQ = "\"";
if (arguments instanceof CharSequence) {
    String arg = escapeBackslashes ? escapeBackslashes(arguments.toString()) : arguments.toString();
    if (arguments instanceof String) {
        if (!inspect) return arg;
        return !escapeBackslashes && multiline(arg) ? "'''" + arg + "'''" : SQ + arg.replace(SQ, "\\'") + SQ;
    }
    if (!inspect) return arg;
    return !escapeBackslashes && multiline(arg) ? "\"\"\"" + arg + "\"\"\"" : DQ + arg.replace(DQ, "\\\"") + DQ;
}

In general, I think we can consider it as a bug in 3.0.11 inspect(), and the bug does not exist in 4.0.2.

MadHatter
  • 301
  • 3
  • 12