【问题标题】:Gradle: Executing task in subproject programmaticallyGradle:以编程方式执行子项目中的任务
【发布时间】:2016-04-29 15:38:44
【问题描述】:

我的 WAR 文件应该包含来自组件的 Java 源文件。 在我的根项目 build.gradle 中,我正在以编程方式执行子项目中的任务:

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
}

在子项目中我有任务:

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')
    }
}

控制台输出:

[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

,表示 collectFilesFromCopyTask() 被执行了 4 次。 它应该只执行一次,从 WAR 任务开始。

【问题讨论】:

    标签: gradle multi-project


    【解决方案1】:

    永远不要在 Gradle 中使用任务的 .execute() 方法。

    除非……,永远不要那样做。

    这不是受支持的事情,并且可能无法按预期工作。

    始终使用任务依赖关系或任务排序依赖关系来确保运行依赖任务或任务以特定顺序运行(如果它们都运行但不直接相互依赖)。

    使您的war 任务依赖于您的复制任务,并使您的war 任务使用这些任务的输出(不是手动files(...) 调用)。

    编辑:

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

    【讨论】:

    • >>让你的战争任务使用这些任务的输出
    • 只需from mySuperFancyTask 就可以了。如果你这样声明它,你甚至可以节省任务依赖,因为以这种方式使用它应该添加一个隐式的任务依赖。
    • from 'application1:copySourceFiles' 产生错误:无法将 URL 'application1:copySourceFiles' 转换为文件。
    • 为了类似于你的原始逻辑,整个事情可以简化为war { into("/") { from { subprojects.tasks*.findByName('copySourceFiles').findAll { it instanceof Copy } } } },包括隐式任务依赖
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多