有条件地跳过多模块Gradle构建中的子项目

时间:2017-07-05 10:51:32

标签: gradle build.gradle

考虑以下Gradle项目结构:

- root
|- build.gradle
|- barProject
 |- build.gradle
|- fooProject
 |- build.gradle

build.gradle 配置其子项目如下:

subprojects {
    apply plugin: 'java'

    //bunch of other stuff
}

现在,当我在根项目上调用gradlew build时,它会自动配置两个子项目,然后构建它们 - 一切都很好。

我也知道我可以通过各种方式(onlyIf()[taskName].enabled = false等)跳过特定任务。但是当我利用build上的任何一个时,Gradle仍会运行所有依赖任务(compileJavaprocessResourcesclasses等),直到最后点击build然后跳过。

我的问题是,是否有任何方式让Gradle停止并在配置阶段后立即转到下一个子项目?

编辑:

澄清;每个子项目都有一个名为skip的属性,在配置阶段进行评估。

现在当我在根项目上调用gradlew build时,我想要Gradle,理想情况下,检查该属性是否属实,然后完全跳过相应的项目。< / p>

Executing external task 'build'...

//check project.skip -> IF true -> skip project, go to :foo ELSE continue
:bar:compileJava
:bar:processResources UP-TO-DATE
:bar:classes
:bar:jar
:bar:startScripts
:bar:distTar
:bar:distZip
:bar:assemble
:bar:compileTestJava UP-TO-DATE
:bar:processTestResources UP-TO-DATE
:bar:testClasses UP-TO-DATE
:bar:test UP-TO-DATE
:bar:check UP-TO-DATE
:bar:build

//check project.skip -> IF true -> skip project, go to end ELSE continue
:foo:compileJava
:foo:processResources UP-TO-DATE
:foo:classes
:foo:jar
:foo:startScripts
:foo:distTar
:foo:distZip
:foo:assemble
:foo:compileTestJava UP-TO-DATE
:foo:processTestResources UP-TO-DATE
:foo:testClasses UP-TO-DATE
:foo:test UP-TO-DATE
:foo:check UP-TO-DATE
:foo:build

BUILD SUCCESSFUL

我希望这更有意义

1 个答案:

答案 0 :(得分:1)

嗯,首先:一个简单的解决方案就是完全调用您需要的任务。在简单的Gradle构建中,任务名称是唯一的。但是,在多项目构建中,每个项目都可以具有特定名称的任务。这就是Gradle引入任务路径的原因。任务路径将唯一项目路径与项目内唯一任务名称组合在一起::projectX:taskY

使用项目路径,您可以轻松指定要执行的项目特定任务::build用于根项目中的build任务,:<subproject>:build用于build子项目中的任务。如果是任务名称,例如build用于多项目构建,Gradle将搜索具有指定名称的任务的任何项目(root和subs)并执行所有项目。这解释了当前的行为。

执行的任务名称由Gradle StartParameterSettings对象管理。可以在Settings文件中修改这些settings.gradle,其中还包含子项目:

include ':foo', ':bar'

startParameter.excludedTaskNames += ':foo:build'

此行从执行中排除build子项目的foo任务。如果满足特定条件,则可以将子项目任务路径(甚至独立于任务名称)添加到排除的任务名称。但是,我没有找到一种方法来访问构建文件中的Settings,因此在配置阶段无法使用此解决方案。但是,如果您的条件完全基于项目/系统属性,则可以从settings.gradle访问它们。

我想到了配置阶段的另一个解决方案,但它基本上就是你已经提到的,因为它只是跳过了任务:

if (project.skip) {
    project.tasks.all { task -> task.enabled = false }
}

这样,将跳过项目中的所有任务(不仅是build任务)。

请考虑,也可以执行任务,因为它们会为另一个项目创建依赖关系。如果gradle :bar:build:foo:jar的项目依赖项,即使foo也会执行任务bar及其任务依赖项。您可以使用Gradle命令行选项-a--no-rebuildsettings.gradle中的以下条目禁用此行为:

startParameter.buildProjectDependencies = false