为什么复制任务会在第一次构建时删除陈旧的输出?
Why copy task delete stale output on first build?
我有这个 kotlin gradle 构建脚本代表我的用例。
我正在使用 Gradle 6.7.
这是我的 kotlin gradle 构建文件:
plugins {
java
}
tasks.register("createFile"){
doLast{
projectDir.resolve("tmp.txt").createNewFile()
projectDir.resolve("tmp.txt").writeText("tmp")
}
dependsOn("assemble")
}
tasks.register("createExecFile", Exec::class){
workingDir(buildDir)
commandLine("cmd", "/c", "mkdir destdir\subdir")
dependsOn("createFile")
}
tasks.register("copyBug", Copy::class){
from(projectDir.resolve("tmp.txt"))
into(buildDir.resolve("destDir"))
dependsOn("createExecFile")
}
现在运行gradle copyBug -i
.
第一次这会给你这个输出:
> Task :copyBug Deleting stale output file: E:\repo\BugCOpy\build\destDir Caching disabled for task ':copyBug' because: Build cache is disabled Task ':copyBug' is not up-to-date because: No history is available.
复制任务删除了前一个执行任务创建的文件。
现在,如果您重新运行此命令,复制任务将不会删除陈旧文件。
那些陈旧的文件是什么?我怎样才能防止这些文件被删除?我的第一个构建与其他构建不同。
我应该提交错误吗?
在您的 createExecFile
任务中,您无需告知 Gradle 就可以生成输出文件。所以 Gradle 不知道这个任务和 copyBug
任务使用相同的输出目录。相反,Gradle 认为 copyBug
是唯一在 build/destdir
下产生输出的任务,因此假设该目录中的任何现有文件不应该存在(并且“陈旧”)是更安全的.
解决方案是告诉 Gradle 你的 createExecFile
任务输出到 build/destdir
:
tasks.register("createExecFile", Exec::class) {
workingDir(buildDir)
commandLine("cmd", "/c", "mkdir destdir\subdir")
// tell Gradle about the output directory
outputs.dir(buildDir.resolve("destdir"))
dependsOn("createFile")
}
如果您需要更多背景信息,请参阅 this release notes section for why this behavior was introduced and this explanation to a very similar issue。
我的构建过程看起来像
- 运行 gradle(第 1 部分)
- 做点别的事
- 运行 gradle(第 2 部分)
令我恼火的是 运行ning gradle 在第 3 步中不仅会向输出目录添加一些文件,而且会首先删除该文件夹作为陈旧文件夹。连加
outputs.dir(...)
没有阻止 Gradle 将其删除。计算我的任务的输入和输出看起来太乏味了,但幸运的是我找到了一种方法告诉 Gradle 不要执行任何最新的跟踪:
Example 37. Ignoring up-to-date checks 提及要添加
doNotTrackState("Comment why this is needed")
这最终帮助我保留了构建步骤 1 中的文件。
我有这个 kotlin gradle 构建脚本代表我的用例。 我正在使用 Gradle 6.7.
这是我的 kotlin gradle 构建文件:
plugins {
java
}
tasks.register("createFile"){
doLast{
projectDir.resolve("tmp.txt").createNewFile()
projectDir.resolve("tmp.txt").writeText("tmp")
}
dependsOn("assemble")
}
tasks.register("createExecFile", Exec::class){
workingDir(buildDir)
commandLine("cmd", "/c", "mkdir destdir\subdir")
dependsOn("createFile")
}
tasks.register("copyBug", Copy::class){
from(projectDir.resolve("tmp.txt"))
into(buildDir.resolve("destDir"))
dependsOn("createExecFile")
}
现在运行gradle copyBug -i
.
第一次这会给你这个输出:
> Task :copyBug Deleting stale output file: E:\repo\BugCOpy\build\destDir Caching disabled for task ':copyBug' because: Build cache is disabled Task ':copyBug' is not up-to-date because: No history is available.
复制任务删除了前一个执行任务创建的文件。
现在,如果您重新运行此命令,复制任务将不会删除陈旧文件。
那些陈旧的文件是什么?我怎样才能防止这些文件被删除?我的第一个构建与其他构建不同。
我应该提交错误吗?
在您的 createExecFile
任务中,您无需告知 Gradle 就可以生成输出文件。所以 Gradle 不知道这个任务和 copyBug
任务使用相同的输出目录。相反,Gradle 认为 copyBug
是唯一在 build/destdir
下产生输出的任务,因此假设该目录中的任何现有文件不应该存在(并且“陈旧”)是更安全的.
解决方案是告诉 Gradle 你的 createExecFile
任务输出到 build/destdir
:
tasks.register("createExecFile", Exec::class) {
workingDir(buildDir)
commandLine("cmd", "/c", "mkdir destdir\subdir")
// tell Gradle about the output directory
outputs.dir(buildDir.resolve("destdir"))
dependsOn("createFile")
}
如果您需要更多背景信息,请参阅 this release notes section for why this behavior was introduced and this explanation to a very similar issue。
我的构建过程看起来像
- 运行 gradle(第 1 部分)
- 做点别的事
- 运行 gradle(第 2 部分)
令我恼火的是 运行ning gradle 在第 3 步中不仅会向输出目录添加一些文件,而且会首先删除该文件夹作为陈旧文件夹。连加
outputs.dir(...)
没有阻止 Gradle 将其删除。计算我的任务的输入和输出看起来太乏味了,但幸运的是我找到了一种方法告诉 Gradle 不要执行任何最新的跟踪:
Example 37. Ignoring up-to-date checks 提及要添加
doNotTrackState("Comment why this is needed")
这最终帮助我保留了构建步骤 1 中的文件。