在运行依赖项时,如何让Gradle重新运行任务?

时间:2015-12-14 22:30:25

标签: gradle

假设我有一个依赖于另一个任务“依赖”的任务“主”。我希望在重建任何依赖项(或其依赖项的依赖项)时重新运行“main”,因为“main”依赖于“依赖项”(或“依赖项”的依赖项)产生的工件。

包含我正在处理的内容示例的build.gradle文件如下:

defaultTasks 'main'

task baseDependency {
    outputs.file 'deps.out'
    outputs.upToDateWhen { false }
    doLast {
        exec {
            commandLine 'bash', '-c', 'echo hello world > deps.out'
        }
    }
}

task dependency(dependsOn: baseDependency)

task main(dependsOn: dependency) {
    outputs.file 'main.out'
    doLast {
        exec {
            commandLine 'bash', '-c', 'echo hello world > main.out'
        }
    }
}

第一次执行gradle

:baseDependency
:dependency
:main

BUILD SUCCESSFUL

Total time: 0.623 secs

第二次执行:

:baseDependency
:dependency
:main UP-TO-DATE

BUILD SUCCESSFUL

Total time: 0.709 secs

如果“main” 标记为“UP-TO-DATE”,如果必须重建其依赖项,那么 非常喜欢。这似乎很重要。你怎么确定是这样的?

1 个答案:

答案 0 :(得分:3)

任务之间specify dependency的标准方式是通过任务的输入和输出。这可以是任何文件,文件集或目录。 在您的情况下,您应修改main任务并将inputs.file 'deps.out'添加到其定义中。

请注意,gradle有一个优化,可能会在您提供的简单示例中导致意外行为。

  

在第一次执行任务之前,Gradle会拍摄快照   的输入。此快照包含一组输入文件和一个   每个文件内容的哈希值。 Gradle然后执行任务。如果   任务成功完成,Gradle拍摄了快照   输出。此快照包含一组输出文件和一个散列   每个文件的内容。 Gradle会为下一个快照保留两个快照   任务执行的时间。

     

每次之后,在执行任务之前,Gradle会采用新的   输入和输出的快照。如果新快照是相同的   与之前的快照一样,Gradle假定输出最多   日期并跳过任务。如果它们不相同,Gradle会执行   任务。 Gradle会在下次任务时保留两个快照   执行。

因此,即使您在生成相同文件的简单示例中指定了正确的输入,依赖任务也将在第二次和后续运行时标记为最新。

如果您不想或不能对文件进行硬编码,则可以为依赖任务覆盖upToDateWhen,并根据此任务的dependencies及其{state计算任务的最新条件。 {3}}像这样:

outputs.upToDateWhen { task ->
   task.taskDependencies.inject(true) { r, dep ->
     r && dep.values.inject(true) { res, v ->
        res && (!(v instanceof Task) || v?.state.getSkipped())
     }
   }
}
如果不应该运行此任务(因为其输出已经是最新的),

upToDateWhen应该返回true。当没有执行任何依赖任务时就是这种情况(gradle文档对此我有点模糊,我必须承认,但getSkipped似乎按预期工作)。