2

I have Jenkins pipeline shared library, that specifies a global variable foo which provides two methods. One of the has no argument, the other has one optional argument:

/vars/foo.groovy

def getBarOne() {
    //...
}

def getBarTwo(String value = '') {
    //...
}

Now I want to provide an IntellJ GSDL file which supports useful code completion for both of this methods. (The GSDL provided by my Jenkins only contains only the definition for the global variable but not for its methods, so I'm trying to add that.)

pipeline.gsdl (by Jenkins)

//The global script scope
def ctx = context(scope: scriptScope())
contributor(ctx) {
//...
property(name: 'foo', type: 'org.jenkinsci.plugins.workflow.cps.global.UserDefinedGlobalVariable')
}
//..

pipeline.gsdl (pimped by me)

//The global script scope
def ctx = context(scope: scriptScope())
contributor(ctx) {
//...
property(name: 'foo', type: 'org.jenkinsci.plugins.workflow.cps.global.UserDefinedGlobalVariable')
}
def uservarCtx = context(ctype: 'org.jenkinsci.plugins.workflow.cps.global.UserDefinedGlobalVariable')
contributor (uservarCtx) {
    method name: 'getBarOne', type: 'java.lang.String', params: [:]
    method name: 'getBarTwo', params: [value:'java.lang.String'], type: 'List<String>'
}
//..

So far so good.
However, code completion in my Jenkinsfile is not fully satisfactory, as it suggests

IntelliJ code completion suggestions

For getBarOne() it suggests both .barOne and .getBarOne(); for getBarTwo(..) only .getBarTwo(String value) is suggested, although the argument is optional.

How can I specify in the GDSL file, that the argument is optional, so that I get suggested all three (valid groovy) options: barTwo, getBarTwo() and getBarTwo(String value)? (Unfortunately the “GDSL AWESOMENESS” Series was of no help.)

Markus Mitterauer
  • 1,560
  • 1
  • 14
  • 28

1 Answers1

3

To have all three options provided, one has to specify two method signatures in the GDSL file. One with the (optional) argument, an one without it:

pipeline.gdsl

//...
def uservarCtx = context(ctype: 'org.jenkinsci.plugins.workflow.cps.global.UserDefinedGlobalVariable')
contributor (uservarCtx) {
    method name: 'getBarOne', type: 'java.lang.String', params: [:]
    method name: 'getBarTwo', params: [:], type: 'List<String>'     //<---
    method name: 'getBarTwo', params: [value:'java.lang.String'], type: 'List<String>'
}

autocomplete suggestions:

full autocomplete suggestions

Bonus track: Multiple global variables

As I've not only one global variable but two, I also wanted to have auto-completion to support that as well.

The trick to do that is, to have specifiy different types for your global variables:

pipeline.gsdl

//The global script scope
def ctx = context(scope: scriptScope())
contributor(ctx) {
//...
property(name: 'foo', type: 'org.jenkinsci.plugins.workflow.cps.global.UserDefinedGlobalVariable.Foo')
property(name: 'bar', type: 'org.jenkinsci.plugins.workflow.cps.global.UserDefinedGlobalVariable.Bar')
}
def varCtxFoo = context(ctype: 'org.jenkinsci.plugins.workflow.cps.global.UserDefinedGlobalVariable.Foo')
contributor (varCtxFoo) {
    //...
}
def varCtxBar = context(ctype: 'org.jenkinsci.plugins.workflow.cps.global.UserDefinedGlobalVariable.Bar')
contributor (varCtxBar) {
    //...
}
//..

Note the .Foo and .Bar suffix to the type UserDefinedGlobalVariable with the type definitions.

Markus Mitterauer
  • 1,560
  • 1
  • 14
  • 28