1

I’ve function like the following

def runTestsInDocker(arg) {
    measureDuration(script: this, measurementName: 'build') {
        executeDocker(dockerImage: dockerImage,  dockerWorkspace: '/go/src') {
            sh """
            mkdir -p /go/src/github.com/ftr/myGoPro
            go ${arg}                        
            """
        }
    }

When I’ve only 1 parameter this is working as expected Now I want to add new parameters so I can do something like this

def runTestsInDocker(arg,arg2,arg3) {
    measureDuration(script: this, measurementName: 'build') {
        executeDocker(dockerImage: dockerImage,  dockerWorkspace: '/go/src') {
            sh """
            mkdir -p /go/src/github.com/ftr/myGoPro

            go ${arg}  
           go ${arg1}
           go ${arg2}
            """
        }
    }

But here I’ve two problems

1 . What happen if I need to pass only one parameter?

  1. If I’ve 10 parameters to pass I will have 10 args?

Is there a nicer way in groovy to handle it ?

update , let's say I need to call to the function with 1 parameters

   def runTestsInDocker(Map<String,String> params) {
        measureDuration(script: this, measurementName: 'build') {
            executeDocker(dockerImage: dockerImage,  dockerWorkspace: '/go/src') {
                sh """
                mkdir -p /go/src/github.com/ftr/myGoPro

                go ${params.get('arg')}  

                """
            }
        }

And other function

   def runTestsInDocker(Map<String,String> params) {
        measureDuration(script: this, measurementName: 'build') {
            executeDocker(dockerImage: dockerImage,  dockerWorkspace: '/go/src') {
                sh """
                mkdir -p /go/src/github.com/ftr/myGoPro

                go ${params.get('arg')}  
                go ${params.get('arg1')} 
                """
            }
        }

I don't know in advance how much parameters I will need to use, so how can I do it dynamically ?

Cœur
  • 37,241
  • 25
  • 195
  • 267
07_05_GuyT
  • 2,787
  • 14
  • 43
  • 88

2 Answers2

2

You can send Map to method to invoke multiple parameters

def runTestsInDocker( Map<String,String> params) {

and call it using a Map:

def params = [ arg:'value', arg1:'value1' ];
runTestsInDocker(params);

Inside method iterate through map dynamically as:

params.each{ k, v -> go ${v} }
Ori Marko
  • 56,308
  • 23
  • 131
  • 233
1

Looking at your target example, this looks like a perfect case for varargs.

def runTestsInDocker(String... args) {
    measureDuration(script: this, measurementName: 'build') {
        executeDocker(dockerImage: dockerImage, dockerWorkspace: '/go/src') {
            sh """
            mkdir -p /go/src/github.com/ftr/myGoPro
            go ${args.join('\ngo ')}
            """
        }
    }
}

If you really want to only pass parameters at certain position, this method signature allows that as well.

runTestsInDocker(null,'foo',null,'bar')
// OR
def args = []
args[2] = 'foo'
args[5] = 'bar'
runTestsInDocker(args as String[])

If, for some reason, you really want parameters with different names and semantics, then I would look into following:

  • Default values, like runTestsInDocker(String arg = null, String arg1 = null, String arg2 = null)
  • Map parameter, like runTestsInDocker(Map map)
  • POGO parameter, like runTestsInDocker(MyPogo args). Compared to map, this provides type checking and it is very easy to construct a POGO with just the values you need.
Ari Manninen
  • 306
  • 2
  • 7
  • can you please explain on this `go ${args.join('\ngo ')}` ? why there is `\ngo`? – 07_05_GuyT Dec 04 '18 at 11:38
  • '\n' is newline character. After that, another 'go '. So, if you join 'a','b' and 'c' with '\ngo ', you will get 'a\ngo b\ngo c' where \n starts a new line. – Ari Manninen Dec 04 '18 at 19:10