在不中断增量构建的情况下在任务中执行多个命令

Execute more than one command in a task without breaking incremental build

我们使用 gradle 增量构建并希望 运行 两个命令(最好来自一个任务)。其中一个解决方案 可以获取两个命令 运行ning...但是它会破坏增量构建。它看起来像:

task myTask() {
inputs.files(inputFiles)

  project.exec {
     workingDir web
     commandLine('mycmd')
  }
  project.exec {
    workingDir web
    commandLine('mysecond-cmd')
  }
}

如果 运行ning 单个命令和增量构建正在运行,任务看起来与此类似,似乎有所不同的是 workingDir:

task myTask(type: Exec)  {
     workingDir  myDir // this seems to trigger/enable continuos compilation
    commandLine ('myCmd')
 }

目前最好的选择是创建 3 个任务,一个用于我想要的每个 cmdline 任务 运行,第三个用于将它们分组,这看起来很脏。

问题是:有没有办法在一个任务中 运行 两个或多个命令,同时增量构建仍然有效?

我将尝试回答评论中的问题:如何从没有输出文件的任务中发出构建应该监视某些文件的信号。不幸的是,如果不知道确切的用例,很难回答这个问题。

首先,Gradle 需要某种形式的声明输出,它可以检查任务是否具有 运行 或是否需要 运行。考虑到任务可能在之前的 运行 期间失败了,但输入文件从那时起就没有改变。应该Gradle运行任务吗?

如果您的任务没有任何输出,这意味着您需要考虑为什么该任务在任何给定的构建执行中应该 运行 或不应该。如果它不创建或修改文件或与系统的另一部分交互,它在做什么?

假设增量构建是正确的解决方案——它可能不是——Gradle 确实允许您通过 TaskOutputs.upToDateWhen(Action) 处理异常情况。下面是一个示例,它有一个简单的任务 (gen),该任务生成一个文件作为没有输出的任务 (runIt) 的输入:

task gen {
    ext.outputDir = "$buildDir/stuff"
    outputs.dir outputDir

    doLast {
        new File(outputDir, "test.txt").text = "Hurray!\n"
    }
}

task runIt {
    inputs.dir gen
    outputs.upToDateWhen { !gen.didWork }
    doLast {
        println "Running it"
    }
}

这指定 runIt 仅在输入文件已更改或任务 gen 实际执行某些操作时才会 运行。在此示例中,这两个场景等同于同一件事。如果 gen 运行s,则 runIt 的输入文件已更改。

要了解的关键是,您提供给 upToDateWhen() 的条件是在构建的 执行 阶段评估的,而不是配置阶段。

希望对您有所帮助,如果您需要任何说明,请告诉我。