【问题标题】:gradle zip task only creates zip in configuration phasegradle zip 任务仅在配置阶段创建 zip
【发布时间】:2020-05-19 14:55:17
【问题描述】:

当我尝试在 Zip 类型的 gradle 任务的执行阶段创建 zip 文件时,没有创建 zip 文件。 如果我在配置阶段执行相同的操作(省略 doLast 语句),则创建的 zip 文件没有问题。 由于 println 语句显示在输出日志中,因此调用了 doLast 块。

之所以需要在执行阶段生成zip,是因为需要压缩的文件是编译执行的结果。 我也尝试过用 jar 任务解决这个问题,但这给了我类似的问题。

代码如下:

    task createClassPathJar(type: Zip) {
  dependsOn("createManifest")

    from("${projectRoot}") {
        include "MANIFEST.MF"
    }
    archiveName = "dummy.jar"

    doLast {

    destinationDir(file("${projectRoot}"))

    archiveName = "zipfile.jar"

    println "executing phase createClassPathJar. archiveName: " + archiveName
  }
}

有人可以帮我吗?我正在使用 Gradle v6.4.1。

【问题讨论】:

    标签: gradle zip lifecycle execution


    【解决方案1】:

    您不能使用doLast 配置任务的操作,因为它将在特定操作(在本例中为压缩)运行之后 执行。要么使用 doFirst 闭包,要么以不依赖于其他配置的方式设置任务配置:

    例如,根据您的任务createManifest 定义其输出的正确程度,您可以使用“from createManifest”直接使用它来定义Zip 任务内容。

    我猜您使用doLast 闭包的原因是基于变量的destinationDir 调用。相反,您可以只使用一个懒惰地评估变量的闭包:

    task createManifest {
       outputs.file('path/to/MANIFEST.MF')
    }
    
    task createClassPathJar(type: Zip) {
        from createManifest
        archiveName = 'zipfile.jar'
        destinationDir = file({ "${projectRoot}" }) // or just file({ projectRoot })
    }
    

    【讨论】:

    • 我需要 doFirst / doLast 闭包的原因是清单文件是在执行阶段创建的。如果在配置阶段创建了 zip,则尚未创建清单。
    • 每个任务总是执行阶段执行。我的示例只是配置任务的一种更优雅的方式,应该优先于使用 doFirst / doLast 闭包。
    • 这很有趣,确实 createManifest 任务现在由 createClassPathJar 任务调用。 “取决于您的任务 createManifest 定义其输出的正确程度”是什么意思?如何指示 createManifest 任务返回文件?
    • 任务的类型是Gradle提供的还是自己实现的?如果它是由 Gradle 提供的,那么它默认会正确定义其输出。
    • 感谢 Lukas,它有效!这个解决方案不仅解决了我的问题,还提供了对增量构建机制的更好理解。直到现在,我还不知道输出可以在 gradle 任务配置中实现。在深入探讨这个问题时,我看到了一篇描述这种机制的文章:blog.gradle.org/introducing-incremental-build-support
    【解决方案2】:

    尝试使用doFirst 而不是doLast

    task createClassPathJar(type: Zip) {
      dependsOn("createManifest")
      from("${projectRoot}") {
        include "MANIFEST.MF"
      }
      archiveName = "dummy.jar"
      doFirst {
        destinationDir(file("${projectRoot}"))
        archiveName = "zipfile.jar"
        println "executing phase createClassPathJar. archiveName: " + archiveName
      }
    }
    

    我不知道您的情况,但我尝试通过在 doFirst 块中将存档名称更改为当前时间,并且存档名称有效地匹配执行时间而不是配置时间。

    【讨论】:

    • 我测试了你的解决方案,起初这似乎解决了问题。但是,如果我删除 zip 文件和清单并再次运行脚本,则会创建清单,但 createClassPathJar 的状态为 UP-TO-DATE,因此不会重新创建 zipfile.jar。你能解释一下这种行为吗?
    猜你喜欢
    • 2016-08-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多