isobretatel
isobretatel

Reputation: 3930

Gradle: Executing task in subproject programmatically

My WAR file should contain Java source files from components. In my root project build.gradle I am executing tasks in subprojects programmatically:

apply plugin: 'war'

jar.enabled = false
war {
    // - Copy Java source files to the folder corresponding to the component;
    into("/") { from { collectFilesFromCopyTask('copySourceFiles') } }
}

// Collects files from destinationDirs of copy tasks with matching taskName
def collectFilesFromCopyTask(taskName) {
    FileCollection collectedFiles = files{}

    // for each task in subprojects
    subprojects.each {project ->
        project.tasks.withType(Copy).matching { task -> task.name.equals( taskName ) }.each { copyFilesTask ->
            println 'copyFilesTask.destinationDir=' + copyFilesTask.destinationDir

            // execute task
            copyFilesTask.execute()

            // add destinationDir of the task to the collected files
            collectedFiles += files(copyFilesTask.destinationDir)
        }
    }

    return collectedFiles
}

In subproject I have task:

task copySourceFiles(type: Copy) {
    destinationDir = file(project.buildDir.name + '/sourceFiles')

    into('componentName') {
        from(project.projectDir)
        exclude('build')
        exclude('bin')
        exclude('src/main/webapp')
        exclude('.gradle')
    }
}

Console output:

[sts] -----------------------------------------------------
[sts] Starting Gradle build for the following tasks: 
[sts]      clean
[sts]      build
[sts] -----------------------------------------------------
copyFilesTask.destinationDir=<...>application1\build\sourceFiles
:clean
:compileJava UP-TO-DATE
:processResources UP-TO-DATE
:classes UP-TO-DATE
:war
copyFilesTask.destinationDir=<...>application1\build\sourceFiles
copyFilesTask.destinationDir=<...>application1\build\sourceFiles
copyFilesTask.destinationDir=<...>application1\build\sourceFiles
:assemble
:compileTestJava UP-TO-DATE
:processTestResources UP-TO-DATE
:testClasses UP-TO-DATE
:test UP-TO-DATE
:check UP-TO-DATE
:build

, which means that collectFilesFromCopyTask() is executed 4 times. It should be executed only once, from WAR task.

Upvotes: 0

Views: 1544

Answers (1)

Vampire
Vampire

Reputation: 38629

Never ever use the .execute() method of a task in Gradle.

Except of when ...... no, never ever do that.

It is not a supported thing to do and does probably not work as expected.

Always use task dependencies or task ordering dependencies to make sure dependent tasks are run or tasks are run in a specific order if they both run but otherwise do not depend on each other directly.

Make your war task depend on your copy tasks and make your war task use the outputs of those tasks (not a manual files(...) call).

EDIT:

war {
 into("/") { from { subprojects.tasks*.findByName('copySourceFiles').findAll { it instanceof Copy } } } 
}

Upvotes: 1

Related Questions