Gradle文档中的示例:配置和执行阶段

发布于 2025-01-22 18:16:18 字数 4422 浏览 4 评论 0原文

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任务包含一个命令来删除构建目录。 编译任务包含检查,是否存在构建目录的子目录。

起初,这似乎是一个易于理解的示例:目录不可用,因为它已更早地删除。但是后来我注意到了一些我无法理解的东西。

当目录的创建发生在配置阶段时,干净的任务在执行阶段删除了目录。

我理解第一部分,因为在项目的配置阶段创建了构建目录。我不明白的是第二部分。文档说这发生在执行阶段。但是,删除目录并未包裹在dofirstdolast 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.

关于我的问题,我没有从此输出中获得更多信息。为什么在执行阶段中删除了该目录,尽管未用dofirstdolast块包裹?这是否与

试图理解,第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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

执笔绘流年 2025-01-29 18:16:18
tasks.register('clean', Delete) {
    println "step 1 in configuration phase of "+getName();
    delete 'build'
    println "step 3 in configuration phase of "+getName();
}

这个人通过delete通过delete.delete()配置任务,该在配置期间排队删除了什么,但是直到执行阶段才会发生任务的实际操作。

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();
    }
}

在执行阶段(在任务操作执行之前,通过delete.delete()在执行任务执行之前,通过delete.delete()将目录排队以删除。似乎是因为dofirst {}在执行过程中运行,并且该目录在dolast {}期间消失。

tasks.register('clean', Delete) {
    println "step 1 in configuration phase of "+getName();
    delete 'build'
    println "step 3 in configuration phase of "+getName();
}

This one configures the Delete task via Delete.delete(), which queues what to delete during configuration, but the actual action of the task does not happen until the execution phase.

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();
    }
}

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 because doFirst { } runs during execution, and the directory is gone during doLast { }.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文