Groovy "inpsect()" on ArrayList with GString value

27 views Asked by At

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.

1

There are 1 answers

0
MadHatter On

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.