【问题标题】:Conditionally skip subproject in multi-module Gradle build有条件地跳过多模块 Gradle 构建中的子项目
【发布时间】:2017-07-05 10:51:32
【问题描述】:

考虑以下 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 检查该属性,如果为真,则完全跳过相应的项目。

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

我希望这更有意义

【问题讨论】:

  • 你想达到什么目的?您只想构建根项目还是一个子项目?情况应该如何?
  • @lu.koerfer 我进行了编辑以澄清

标签: gradle build.gradle


【解决方案1】:

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

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

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

include ':foo', ':bar'

startParameter.excludedTaskNames += ':foo:build'

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

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

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

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

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

startParameter.buildProjectDependencies = false

【讨论】:

    猜你喜欢
    • 2020-06-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-02
    • 2013-06-26
    • 1970-01-01
    相关资源
    最近更新 更多