【问题标题】:Understanding Gradle task dependency (dependsOn)理解 Gradle 任务依赖(dependsOn)
【发布时间】:2016-05-24 17:01:48
【问题描述】:

两个问题:

  1. 指定 1 个任务由多个其他任务组成的 gradle 方法是什么?
  2. 似乎 gradle 的 taskName.execute() 方法不尊重 taskName 的依赖关系,这是真的吗?解决方法是什么?

更多背景:

现在我有一个没有插件的构建脚本(换句话说,不是 Java)。我想要一个名为tests 的任务,它将运行我所有的测试任务。我有 3 个这样的任务。称它们为 task1、task2 和 task3。

我可以说tests.dependsOn ['task1', 'task2', 'task3']

这有点奇怪,因为关系似乎是tests.isComprisedOf ['task1', 'task2', 'task3']

我可以说:

task tests << {
    task1.execute()
    task2.execute()
    task3.execute()
}

然后 task3,它本身依赖于 taskSetup,在没有运行 taskSetup 的情况下运行。换句话说,execute() 调用似乎不尊重 gradle 的依赖解析策略。

最后一个小抱怨(顺便说一句,我真的很喜欢 gradle),是很难搜索这个主题,因为依赖在 gradle 中意味着两个不同的东西:dependsOn 样式依赖和库样式依赖。

【问题讨论】:

  • 你能扩展一下“dependsOn 样式依赖”的概念吗?我现在正在尝试浏览文档,这个想法对我来说是新的。我不明白为什么添加依赖项意味着有关运行顺序或执行任务本身的任何事情。

标签: gradle


【解决方案1】:

通常,您不会调用task.execute()

您可以通过以下方式指定一个任务由其他任务组成:

task task1 << {
   println "Hello"
}

task task2 << {
   println "World"
}

task task3(dependsOn: 'task3dependency') << {
   println "QBert"
}

task task3dependency << {
   println "MR"
}

task tests(dependsOn: ['task1', 'task2', 'task3'])

这个输出:

$ gradle tests
:task1
Hello
:task2
World
:task3dependency
MR
:task3
QBert
:tests

BUILD SUCCESSFUL

请记住,依赖任务的运行顺序并不总是得到保证,但您可以通过 specifying the order task2.mustRunAfter task1 缓解这种情况。但通常,这些任务会按照您期望的顺序运行。

另外,您应该阅读Gradle's Build Lifecycle。当您使用语法task task1 &lt;&lt; {...} 时,您指定的是在任务的执行阶段运行的闭包。在运行执行之前,配置阶段会评估您的构建脚本并确定要运行的任务以及运行顺序。当你手动执行任务时,如:

task tests << {
    task1.execute()
    task2.execute()
    task3.execute()
}

你绕过了 Gradle 评估 task3 的任务依赖关系的能力,因此它只运行 task3。

【讨论】:

  • “请记住,依赖任务的运行顺序并不总是得到保证 [...] 通常,任务会按照您期望的顺序运行。” -- 很模糊,你知道在什么情况下可以依赖命令吗?
  • 您的第一个建议不适用于 CopyTar 任务类型。什么都没有被执行。
  • @TheOperator 我不知道在什么情况下你可以依赖你列出依赖任务的顺序。
  • @IgorGanapolsky 你能详细说明一下吗?我已经验证这确实适用于 Copy 和 Tar 类型。是否有可能您没有运行干净的构建,并且任务是最新的?
  • 我不知道这是否是官方记录的行为,但根据我自己的测试,如果一个任务依赖于多个其他任务,它们会按字母顺序执行。 task mytask(dependsOn: ['aTask', 'bTask'])task mytask(dependsOn: ['bTask', 'aTask']) 做同样的事情:aTask 总是在 bTask 之前执行
【解决方案2】:

Gradle 的任务模型是“扁平的”,没有聚合的概念。 (需要注意的是,TaskInternal#execute 是一个内部方法,不能从构建脚本中调用。)聚合通常使用 生命周期任务(具有任务依赖性但没有任何任务操作的任务)模拟):

task allTests {
    dependsOn tasks.withType(Test)
}

除了dependsOn,还支持以下任务关系:mustRunAftershouldRunAfterfinalizedBy

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-05-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多