How can I extend the behavior of a Gradle issue for a new issue type?

I would like to ask several things for several test problems. Specifically, I would like to add a few environment variables and a few system properties, perhaps a few other things like "dependencies" or "worker". With an ordinary task, Test

I can do this,

task test1(type:Test, dependsOn:[testPrep,testPrep1]){
     workingDir testWorkingPath
     systemProperty 'property','abs'
     environment.find { it.key ==~ /(?i)PATH/ }.value += (System.properties['path.separator'] + myLibPath)
     environment.LD_LIBRARY_PATH = "/usr/lib64:/lib64:${myLibPath}:" + environment.LD_LIBRARY_PATH
 }

task test2(type:Test, dependsOn:[testPrep]){
     workingDir testWorkingPath
     systemProperty 'property','abs'
     environment.find { it.key ==~ /(?i)PATH/ }.value += (System.properties['path.separator'] + myLibPath)
     environment.LD_LIBRARY_PATH = "/usr/lib64:/lib64:${myLibPath}:" + environment.LD_LIBRARY_PATH
     systemPropety 'newProperty','fdsjfkd'
 }

      

It would be nice to have a new problem type MyTestType

that extends the usual test problem type where a common definition is defined.

task test1(type:MyTestType){
     dependsOn testPrep1
 }

task test2(type:MyTestType){
     systemPropety 'newProperty','fdsjfkd'
 } 

      

What would be the best way to do this? It looks like the method execute()

is final and cannot be extended. I will need to do something like doFirst

to set these properties. Should I add any additional values โ€‹โ€‹to the constructor? Is there any other hook I can use? Thank you.

+3


source to share


2 answers


In general, you can extend the "Test" task and implement your own settings

task test1(type:MyTestType){
}

task test2(type:MyTestType){
     systemProperty 'newProperty','fdsjfkd'
}

class MyTestType extends Test {
    public MyTestType(){
        systemProperty 'property','abs'
    }
}

      



Alternatively, you can set up all type tasks Test

with fewer templates:

// will apply to all tasks of type test. 
// regardless the task was created before this snippet or after
tasks.withType(Test) {
   systemProperty 'newProperty','fdsjfkd'   
}

      

+4


source


You can also specify the behavior of a specific parameter of the superclass. Let's say for example you want to centralize a block environment.find

, but allow customization myLibPath

for each task like this:

task test1(type: MyTestType) {
}
task test2(type: MyTestType) {
  libPath = '/foo/bar'
}

      

You can do this by overriding the method configure

:



class MyTestType {
  @Input def String libPath

  @Override
  public Task configure(Closure configureClosure) {
    return super.configure(configureClosure >> {
      environment.find { it.key ==~ /(?i)PATH/ }.value += (System.properties['path.separator'] + (libPath ?: myLibPath))
    })
  }
}

      

Here we are using the close operator < to combine a closed connection with our overridden behavior. The custom one configureClosure

will be launched first, perhaps by setting a property libPath

, and then running the block environment.find

. This can also be combined with soft defaults in the constructor, as in Rene Grรถschke's answer

Note that this particular use case might break if you configure more than one task, as the statement environment.find

transforms the existing state instead of replacing it.

0


source







All Articles