Gradle: 以编程方式执行子项目中的任务
Gradle: Executing task in subproject programmatically
我的 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 中任务的 .execute()
方法。
除非……没有,永远不要那样做。
这不是受支持的事情,可能无法按预期工作。
始终使用任务依赖关系或任务排序依赖关系来确保依赖任务是 运行 或任务是 运行 按特定顺序,如果它们都 运行 但否则不依赖直接互相。
使您的 war
任务依赖于您的复制任务,并使您的 war
任务使用这些任务的输出(而不是手动 files(...)
调用)。
编辑:
war {
into("/") { from { subprojects.tasks*.findByName('copySourceFiles').findAll { it instanceof Copy } } }
}
我的 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 中任务的 .execute()
方法。
除非……没有,永远不要那样做。
这不是受支持的事情,可能无法按预期工作。
始终使用任务依赖关系或任务排序依赖关系来确保依赖任务是 运行 或任务是 运行 按特定顺序,如果它们都 运行 但否则不依赖直接互相。
使您的 war
任务依赖于您的复制任务,并使您的 war
任务使用这些任务的输出(而不是手动 files(...)
调用)。
编辑:
war {
into("/") { from { subprojects.tasks*.findByName('copySourceFiles').findAll { it instanceof Copy } } }
}