Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/eclipse/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
当Gradle的依赖项运行时,如何使其重新运行?_Gradle - Fatal编程技术网

当Gradle的依赖项运行时,如何使其重新运行?

当Gradle的依赖项运行时,如何使其重新运行?,gradle,Gradle,假设我有一个任务“main”,它依赖于另一个任务“dependency”。我希望“main”在其依赖项(或其依赖项的依赖项)重建时可以重新运行,因为“main”依赖于“dependency”(或“dependency”的依赖项)生成的工件 包含我正在处理的示例的build.gradle文件如下所示: defaultTasks 'main' task baseDependency { outputs.file 'deps.out' outputs.upToDateWhen { f

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

包含我正在处理的示例的
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”是而不是标记为“最新的”,如果它的依赖项必须重建,我会非常喜欢。这似乎很重要。如何确保这种情况?

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

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

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

每次之后,在任务执行之前,Gradle都会接受一个新的 输入和输出的快照。如果新快照相同 与前面的快照一样,Gradle假设输出达到 日期并跳过任务。如果它们不相同,Gradle将执行 任务Gradle会在下次执行任务时保留这两个快照 执行

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

如果您不希望或无法硬编码对文件的依赖关系,您可以覆盖依赖任务的
UpdateWhen
,并根据此任务的类型及其类似内容计算任务是否最新的条件:

outputs.upToDateWhen { task ->
   task.taskDependencies.inject(true) { r, dep ->
     r && dep.values.inject(true) { res, v ->
        res && (!(v instanceof Task) || v?.state.getSkipped())
     }
   }
}
UpdateWhen
如果此任务根本不应运行(因为其输出已经是最新的),则应返回
true
。在没有运行依赖任务的情况下就是这种情况(gradle文档对此有点含糊不清,我必须承认,但是
getSkipped
似乎工作正常)。

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

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

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

每次之后,在任务执行之前,Gradle都会接受一个新的 输入和输出的快照。如果新快照相同 与前面的快照一样,Gradle假设输出达到 日期并跳过任务。如果它们不相同,Gradle将执行 任务Gradle会在下次执行任务时保留这两个快照 执行

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

如果您不希望或无法硬编码对文件的依赖关系,您可以覆盖依赖任务的
UpdateWhen
,并根据此任务的类型及其类似内容计算任务是否最新的条件:

outputs.upToDateWhen { task ->
   task.taskDependencies.inject(true) { r, dep ->
     r && dep.values.inject(true) { res, v ->
        res && (!(v instanceof Task) || v?.state.getSkipped())
     }
   }
}

UpdateWhen
如果此任务根本不应运行(因为其输出已经是最新的),则应返回
true
。当没有运行依赖任务时就是这种情况(gradle文档对此有点含糊不清,我必须承认,但是
getSkipped
似乎工作正常)。

我已经详细阐述了我的示例。另外,我不想像那样硬编码输入,但是
dependency.output.files
在我的情况下实际上不起作用,因为直接依赖并不总是产生我需要的输出。例如,它可能只是一个聚合其他任务的任务。我已经添加了基于
UpdateWhen
的通用解决方案的最后一段。您介意包含示例代码吗?我不清楚
UpdateWhen
的语义,以及我是否应该使用
getDidWork
getExecuted
,或者反转
getSkipped
GetUpdate
中的一个。这会让我对什么感兴趣?这是预期的处理方式吗?对我来说,似乎真的很奇怪,没有简单、标准的方式来说明任务取决于其
dependsOn
链中任务的输出。我已经详细阐述了我的示例。另外,我不想像那样硬编码输入,但是
dependency.output.files
在我的情况下实际上不起作用,因为直接依赖并不总是产生我需要的输出。例如,它可能只是一个聚合其他任务的任务。我已经添加了基于
UpdateWhen
的通用解决方案的最后一段。您介意包含示例代码吗?我不清楚
UpdateWhen
的语义以及是否应该使用
getDidWork