如果另一个任务在 gradle 中不是最新的,则只有 运行 个任务

Only run task if another isn't UP-TO-DATE in gradle

我想在Gradle中做功能测试时自动添加一个serverRun任务,所以我添加了一个依赖:

funcTestTask.dependsOn(serverRun)

这导致任务 运行ning 是否 funcTestTask 甚至 运行s

:compile
:serverRun
:funcTestTask (and associate compile tasks... etc)
:serverStop

OR

:compile UP-TO-DATE
:serverRun <-- unnecessary 
:funcTestTask UP-TO-DATE
:serverStop

启动服务器的成本相当高,我只希望它在功能测试不是最新的情况下启动,我想做或东西 :

if(!funcTestTask.isUpToDate) {
    funcTestTask.dependsOn(serverRun)
}

所以我知道我无法知道 funcTestTask 的最新状态,直到它的所有 inputs/outputs 都被决定但是我可以继承它的最新检查器吗?

serverRun.outputs.upToDateWhen(funcTestTask.upToDate)

替代方法是 "doFirst" FuncTest 中的 ServerRun,我认为这通常不受欢迎?

funcTestTask.doFirst { serverRun.execute() }

有没有办法有条件地 运行 一项任务先于另一项任务?

更新 1
尝试设置 inputs/outputs 相同

serverRun.inputs.files(funcTestTask.inputs.files)
serverRun.outputs.files(funcTestTask.outputs.files)

这似乎重新运行 服务器重新编译(好),在成功的未更改功能测试(也好)之后跳过重新运行s,但不会重新运行 测试在像下面这样的失败测试之后

:compile
:serverRun
:funcTestTask FAILED

then

:compile UP-TO-DATE
:serverRun UP-TO-DATE <-- wrong!
:funcTestTask FAILED

我最终写入 'failure file' 并将其作为 serverRun 任务的输入:

File serverTrigger = project.file("${buildDir}/trigger") 

project.gradle.taskGraph.whenReady { TaskExecutionGraph taskGraph ->
  // make the serverRun task have the same inputs/outputs + extra trigger
  serverRun.inputs.files(funcTestTask.inputs.files, serverTrigger)
  serverRun.outputs.files(funcTestTask.outputs.files)
}

project.gradle.taskGraph.afterTask { Task task, TaskState state ->
  if (task.name == "funcTestTask" && state.failure) {
    serverRun.trigger << new Date()
  }
}

根据 Gradle 论坛上我的问题的答案中的信息: http://forums.gradle.org/gradle/topics/how-can-i-start-a-server-conditionally-before-a-functionaltestrun

由于该任务是您要控制的任务的从属任务,因此您可以尝试:

tasks {
    onlyIf {
        dependsOnTaskDidWork()
    }
}

面对同样的问题,我找到了一个非常干净的解决方案。在我的例子中,我希望在构建为 运行 时生成一个 eclipse 项目设置,但仅在生成新 jar 时才生成。当 jar 是最新的时,不应执行任何项目设置。以下是如何做到这一点:

tasks.eclipse {
  onlyIf {
    !jar.state.upToDate
  }
}

build {
  dependsOn tasks.eclipse
}

我遇到了同样的问题,但我想出的解决方案要简单得多。 只有在需要测试时才会启动服务器

test {
    doFirst {
        exec {
            executable = 'docker/_ci/run.sh'
            args = ['--start']
        }
    }

    doLast {
        exec {
            executable = 'docker/_ci/run.sh'
            args = ['--stop']
        }
    }
}

假设你有 task1task2 这取决于 task1 并且你需要 运行 task2 只有当 task1 不是 up-to-date,可以用下面的例子:

task task1 {
  // task1 definition
}

task task2(dependsOn: task1) {
  onlyIf { task1.didWork }
}

在这种情况下,仅当任务 1 不是 up-to-date 时,任务 2 才会 运行。重要的是仅对 dependsOn 中定义的任务使用 didWork,以确保在该任务(在我们的示例中为 task1)有机会评估 didWork 之后运行.