gradle.processResources 中的代码块以是否请求另一个任务为条件

Code block in gradle.processResources conditional on whether another task was requested

我们有一个可选的 gradle 任务 docker,它依赖于任务 war,如果执行,需要生成一个 war 文件,其中包含一个额外的文件。这个额外的文件可以添加到 processResources 任务中的资源中(或者可能直接添加到 war 任务中)。但是对应的代码块一定不能运行如果任务docker没有被请求,也不会运行。

我们需要一个正确的条件在下面的块中检查任务docker是否在管道中:

processResources {
  if (/* CONDITION HERE: task docker is requested */) {
    from ("${projectDir}/docker") {
      include "app.properties"
    }
  }
}

task docker(type: Dockerfile) {
  dependsOn build
  ...

澄清processResourceswar任务的标准依赖,后者是build任务的标准依赖。 processResources 总是在 build 上执行,有或没有 docker 任务来收集资源以组装 war,并且在这种情况下可能不会被完全禁用。人们可以将有问题的代码移动到依赖于 docker 并在 processResources 的输出目录上工作的单独任务,但是在 war 是 运行 之前,这样的构造如此简单的事情会导致清晰度大大降低。

您可以简单地向您的 docker 任务添加额外的依赖项,使其不仅依赖于 build 任务,而且还依赖于 processResources。在这种情况下,只有在应该执行 docker 时才会调用您的 processResources 任务。

另一个解决方案是使用 TaskExecutionGraph。这让你可以初始化一些变量,它可以告诉你某个任务是否会被执行。但你必须明白,只有在所有配置完成后,该图才会准备好,你只能在执行阶段依赖它。这是一个简短的例子,它是如何使用的:

//some flag, whether or not some task will be executed
def variable = false

//task with some logic executed during the execution phase
task test1 << {
    if (variable) {
        println 'task2 will be executed'
    } else {
        println 'task2 will not be executed'
    }
}

//according to whether or not this task will run or not, 
//will differs test1 task behavior
task test2(dependsOn: test1) {

}

//add some logic according to task execution graph
gradle.taskGraph.whenReady {
    taskGraph ->
        //check the flag and execute only if it's true
        if (taskGraph.hasTask(test2)) {
            variable = true
            println 'task test2 will be executed'
        }
}

此外,如果 docker 任务不在执行图中,您可以尝试通过将启用 属性 设置为 false 来配置自定义任务以禁用它。在这种情况下,您不必在执行阶段提供一些标志和逻辑。喜欢:

task test1 {       
    //some logic for execution
    doLast {
        println "execute some logic"
    }
}

task test2(dependsOn: test1) {

}

gradle.taskGraph.whenReady {
    taskGraph ->
        if (!taskGraph.hasTask(test2)) {
            //Disable test1 task if test2 will not run
            test1.enabled = false
        }
}

但是如果不进行一些额外的配置,就不可能单独 运行 这个自定义任务。