Search code examples
inheritancegradlegroovybuild.gradlegradle-task

How do you share code between gradle tasks?


So I have some gradle tasks to interact with glassfish ...

task startGlassfish(type:Exec){
    workingDir "${glassfishHome}${File.separator}bin"

    if (System.properties['os.name'].toLowerCase().contains('windows')) {
        commandLine 'cmd', '/c', 'asadmin.bat'
    } else {
        commandLine "./asadmin"
    }

    args "start-domain", "${glassfishDomain}"
}

task stopGlassfish(type:Exec){
    workingDir "${glassfishHome}${File.separator}bin"

    if (System.properties['os.name'].toLowerCase().contains('windows')) {
        commandLine 'cmd', '/c', 'asadmin.bat'
    } else {
        commandLine "./asadmin"
    }

    args "stop-domain", "${glassfishDomain}"
}

task deploy(dependsOn: 'war', type:Exec) {
    workingDir "${glassfishHome}${File.separator}bin"

    if (System.properties['os.name'].toLowerCase().contains('windows')) {
        commandLine 'cmd', '/c', 'asadmin.bat'
    } else {
        commandLine "./asadmin"
    }

    args "deploy", "--force=true", "${war.archivePath}"
}

That's a lot of unnecessary code duplication and I'd like to refactor it into something slimmer.

I did try

class GlassfishAsadminTask extends Exec{
    @TaskAction
    def run() {
        workingDir "${glassfishHome}${File.separator}bin"

        if (System.properties['os.name'].toLowerCase().contains('windows')) {
            commandLine 'cmd', '/c', 'asadmin.bat'
        } else {
            commandLine "./asadmin"
        }
    }
}

task startGlassfish(type:GlassfishAsadminTask){

    args "start-domain", "${glassfishDomain}"
}

but that fails with

Execution failed for task ':startGlassfish'.

> execCommand == null!

So I'm obviously misunderstanding something.

How do I get this to work?


Solution

  • When writing custom task classes I suggest first checking the original task's code. Exec task's @TaskAction is exec() method as can be seen in AbstractExecTask class

    You can use the following code;

    class GlassfishAsadminTask extends Exec{
        // arguments that tasks will pass (defined as array)
        @Input
        String[] cmdArguments
    
        @TaskAction
        public void exec() {
            // access properties with project.proppertyName
            workingDir "${project.glassfishHome}${File.separator}bin"
    
            if (System.properties['os.name'].toLowerCase().contains('windows')) {
                commandLine 'cmd', '/c', 'asadmin.bat'
            } else {
                commandLine "./asadmin"
            }
            // set args that is set by the task
            args cmdArguments
            super.exec()
        }
    }
    
    // A sample task
    task startGlassfish(type: GlassfishAsadminTask) {
         cmdArguments = ["start-domain", "${glassfishDomain}"]
    }