Gradle文档中的示例:配置和执行阶段
Gradle文档“避免陷阱”一章具有“配置和执行阶段”的示例。 link
请记住,Gradle具有独特的配置和执行阶段(请参阅构建生命周期)。
def classesDir = file('build/classes')
classesDir.mkdirs()
tasks.register('clean', Delete) {
delete 'build'
}
tasks.register('compile') {
dependsOn 'clean'
doLast {
if (!classesDir.isDirectory()) {
println 'The class directory does not exist. I can not operate'
// do something
}
// do something
}
}
有2个任务,编译
和清洁
。构建目录是作为项目的一部分而创建的。 Clean
任务包含一个命令来删除构建目录。 编译
任务包含检查,是否存在构建目录的子目录。
起初,这似乎是一个易于理解的示例:目录不可用,因为它已更早地删除。但是后来我注意到了一些我无法理解的东西。
当目录的创建发生在配置阶段时,干净的任务在执行阶段删除了目录。
我理解第一部分,因为在项目的配置阶段创建了构建目录。我不明白的是第二部分。文档说这发生在执行阶段。但是,删除目录并未包裹在dofirst
或dolast
block中,因此该任务的这一部分应在配置阶段发生。
试图理解,第1轮
要获得更好的概述,我添加了更多println
并删除了仅注释的行。
def classesDir = file('build/classes')
classesDir.mkdirs()
println "configuration phase of project";
tasks.register('clean', Delete) {
println "step 1 in configuration phase of "+getName();
delete 'build'
println "step 3 in configuration phase of "+getName();
}
tasks.register('compile') {
println "configuration phase of "+getName();
dependsOn 'clean'
doLast {
if (!classesDir.isDirectory()) {
println 'The class directory does not exist. I can not operate'
}
}
}
通过./ gradlew compile -info
提供以下输出。
configuration phase of project
All projects evaluated.
configuration phase of compile
Selected primary task 'compile' from project :
step 1 in configuration phase of clean
step 3 in configuration phase of clean
Tasks to be executed: [task ':clean', task ':compile']
Tasks that were excluded: []
:clean (Thread[Execution worker for ':',5,main]) started.
> Task :clean
Caching disabled for task ':clean' because:
Build cache is disabled
Task ':clean' is not up-to-date because:
Task has not declared any outputs despite executing actions.
:clean (Thread[Execution worker for ':',5,main]) completed. Took 0.002 secs.
:compile (Thread[Execution worker for ':',5,main]) started.
> Task :compile
Caching disabled for task ':compile' because:
Build cache is disabled
Task ':compile' is not up-to-date because:
Task has not declared any outputs despite executing actions.
The class directory does not exist. I can not operate
:compile (Thread[Execution worker for ':',5,main]) completed. Took 0.0 secs.
关于我的问题,我没有从此输出中获得更多信息。为什么在执行阶段中删除了该目录,尽管未用dofirst
或dolast
块包裹?这是否与
试图理解,第2轮
我想相信这是文档中的一个错误,但是在更改代码后,这是不合适的。
def classesDir = file('build/classes');
classesDir.mkdirs();
tasks.register('clean', Delete) {
doFirst {
delete 'build';
println "[debug-print] ("+getName()+") build directory exists in doFirst: "+file("build").exists();
}
doLast {
println "[debug-print] ("+getName()+") build directory exists in doLast: "+file("build").exists();
}
}
tasks.register('compile') {
dependsOn 'clean'
doFirst {
println "[debug-print] ("+getName()+") build directory exists in doFirst: "+file("build").exists();
}
doLast {
println "[debug-print] ("+getName()+") build directory exists in doLast: "+file("build").exists();
}
}
./ gradlew compile
的输出是:
> Task :clean
[debug-print] (clean) build directory exists in doFirst: true
[debug-print] (clean) build directory exists in doLast: false
> Task :compile
[debug-print] (compile) build directory exists in doFirst: false
[debug-print] (compile) build directory exists in doLast: false
这看起来像delete
实际上并未删除目录,或者至少没有立即删除。这与 delete :
添加了该任务要删除的一些文件。
但是话又说回来,我不明白何时删除实际目录。在执行阶段,但不在dofirst
中,而不是dolast
?这与我对执行阶段的理解不符。
The Gradle documentation, chapter "Avoiding traps", has an example "Configuration and execution phase". Link
It is important to keep in mind that Gradle has a distinct configuration and execution phase (see Build Lifecycle).
def classesDir = file('build/classes')
classesDir.mkdirs()
tasks.register('clean', Delete) {
delete 'build'
}
tasks.register('compile') {
dependsOn 'clean'
doLast {
if (!classesDir.isDirectory()) {
println 'The class directory does not exist. I can not operate'
// do something
}
// do something
}
}
There are 2 tasks, compile
and clean
. The build directory is created as part of the project. The clean
task contains a command to delete the build directory. The compile
task contains a check, whether a subdirectory of the build directory exists.
At first this seemed to be an easy-to-understand example: a directory isn't available, because it gets deleted earlier. But then i noticed something that i can't understand.
As the creation of the directory happens during the configuration phase, the clean task removes the directory during the execution phase.
I understand the first part, as the build directory is created during the configuration phase of the project. What i don't understand is the second part. The documentation says this happens during the execution phase. But the removal of the directory isn't wrapped in a doFirst
or doLast
block, so this part of the task should happen during the configuration phase.
Trying to understand, round 1
To get a better overview, i added more println
and removed the comment-only lines.
def classesDir = file('build/classes')
classesDir.mkdirs()
println "configuration phase of project";
tasks.register('clean', Delete) {
println "step 1 in configuration phase of "+getName();
delete 'build'
println "step 3 in configuration phase of "+getName();
}
tasks.register('compile') {
println "configuration phase of "+getName();
dependsOn 'clean'
doLast {
if (!classesDir.isDirectory()) {
println 'The class directory does not exist. I can not operate'
}
}
}
Starting gradle via ./gradlew compile --info
provided the following output.
configuration phase of project
All projects evaluated.
configuration phase of compile
Selected primary task 'compile' from project :
step 1 in configuration phase of clean
step 3 in configuration phase of clean
Tasks to be executed: [task ':clean', task ':compile']
Tasks that were excluded: []
:clean (Thread[Execution worker for ':',5,main]) started.
> Task :clean
Caching disabled for task ':clean' because:
Build cache is disabled
Task ':clean' is not up-to-date because:
Task has not declared any outputs despite executing actions.
:clean (Thread[Execution worker for ':',5,main]) completed. Took 0.002 secs.
:compile (Thread[Execution worker for ':',5,main]) started.
> Task :compile
Caching disabled for task ':compile' because:
Build cache is disabled
Task ':compile' is not up-to-date because:
Task has not declared any outputs despite executing actions.
The class directory does not exist. I can not operate
:compile (Thread[Execution worker for ':',5,main]) completed. Took 0.0 secs.
I didn't get more information from this output, regarding my question. Why is the directory deleted during the execution phase, despite not being wrapped in a doFirst
or doLast
block? Does this have something to do with Delete?
Trying to understand, round 2
I wanted to believe this is a mistake in the documentation, but after modifying the code a little bit more, this doesn't fit.
def classesDir = file('build/classes');
classesDir.mkdirs();
tasks.register('clean', Delete) {
doFirst {
delete 'build';
println "[debug-print] ("+getName()+") build directory exists in doFirst: "+file("build").exists();
}
doLast {
println "[debug-print] ("+getName()+") build directory exists in doLast: "+file("build").exists();
}
}
tasks.register('compile') {
dependsOn 'clean'
doFirst {
println "[debug-print] ("+getName()+") build directory exists in doFirst: "+file("build").exists();
}
doLast {
println "[debug-print] ("+getName()+") build directory exists in doLast: "+file("build").exists();
}
}
The output of ./gradlew compile
is:
> Task :clean
[debug-print] (clean) build directory exists in doFirst: true
[debug-print] (clean) build directory exists in doLast: false
> Task :compile
[debug-print] (compile) build directory exists in doFirst: false
[debug-print] (compile) build directory exists in doLast: false
This looks like delete
isn't actually deleting the directory, or at least not right away. This matches the javadoc of Delete:
Adds some files to be deleted by this task.
But then again, i don't understand when the actual directory removal happens. During the execution phase, but not in doFirst
and not in doLast
? This doesn't match my understanding of the execution phase.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这个人通过
delete
通过delete.delete()
配置任务,该在配置期间排队删除了什么,但是直到执行阶段才会发生任务的实际操作。在执行阶段(在任务操作执行之前,通过
delete.delete()
在执行任务执行之前,通过delete.delete()
将目录排队以删除。似乎是因为dofirst {}
在执行过程中运行,并且该目录在dolast {}
期间消失。This one configures the
Delete
task viaDelete.delete()
, which queues what to delete during configuration, but the actual action of the task does not happen until the execution phase.This one appears to be queueing the directory to delete via
Delete.delete()
during the execution phase (modifying the task configuration on-the-fly), before the task action executes. It seems this way becausedoFirst { }
runs during execution, and the directory is gone duringdoLast { }
.