Gradle连续生成行为异常

gj3fmq9x  于 2023-11-18  发布在  其他
关注(0)|答案(1)|浏览(103)

bounty将在6天后过期。回答此问题可获得+100声望奖励。Janning Vygen希望引起更多关注此问题:我真的很想更好地了解gradle

Gradle对我来说是一个神奇的盒子。我经常不明白它,总是尝试和错误。我使用gradle 8.1和groovy脚本。我有这个小任务

import java.time.Instant

tasks.register('continuous-build') {
    dependsOn tasks.compileJava
    onlyIf { !compileJava.state.upToDate }
    logger.lifecycle("Job executed at " + Instant.now())
    doLast {
        def file = new File(projectDir, "build/classes/java/main/.reloadTrigger");
        file.createNewFile();
        file.setLastModified(Instant.now().toEpochMilli())
        logger.lifecycle("This message is never seen")
    }
}

字符串
我希望这个任务运行--continuous-build和只是触摸一个文件,如果它完成编译。
这就是我的工作

运行./gradlew continuous-build --continuous

$ ./gradlew continuous-build --continuous
Reload triggered at 2023-11-10T11:48:50.446501720Z   
BUILD SUCCESSFUL in 1s
6 actionable tasks: 1 executed, 5 up-to-date
Waiting for changes to input files... (ctrl-d to exit)

对Main.java做一个小的修改,编译得很好

modified: [...]Main.java
Change detected, executing build...
Reload triggered at 2023-11-10T11:49:02.870526619Z
BUILD SUCCESSFUL in 1s
6 actionable tasks: 1 executed, 2 from cache, 3 up-to-date
Waiting for changes to input files... (ctrl-d to exit)


在此之后,文件时间戳被更改。这就是我想要的。

对Main.java做一个小修改,编译时出错

modified: [...]Main.java
Change detected, executing build...   
Reload triggered at 2023-11-10T11:49:09.303034432Z    
> Task :compileJava FAILED
[...]Main.java:22: error: <identifier> expected
    publi static final String ANSWER = "42";
         ^
1 error
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':compileJava'.
> Compilation failed; see the compiler error output for details.   
* Try:
> Run with --stacktrace option to get the stack trace.
> Run with --info or --debug option to get more log output.
> Run with --scan to get full insights.    
* Get more help at https://help.gradle.org    
BUILD FAILED in 1s
3 actionable tasks: 2 executed, 1 up-to-date    
Waiting for changes to input files... (ctrl-d to exit)


在此之后,文件的时间戳是改变。这就是我想要的,因为它编译错误。

对Main.java做一个小的更改,它再次编译良好

modified: [...]Main.java
Change detected, executing build...
Reload triggered at 2023-11-10T11:49:14.192599979Z
BUILD SUCCESSFUL in 1s
6 actionable tasks: 1 executed, 5 up-to-date
Waiting for changes to input files... (ctrl-d to exit)


在此之后,即使编译成功,文件时间戳也改变了。如果compileJava成功,我如何实现文件触摸cmd?
为什么第二条日志消息从未出现?
PS我已经缩短了输出一点点,使其更具可读性

mnemlml8

mnemlml81#

有几点要提:

  • doLast是一个任务的操作。它在任务结束时运行。
  • 您的gradle任务continuous-build通过dependsOn tasks.compileJava这一行依赖于compileJava任务,这意味着如果compileJava任务失败,即Java类编译失败,则doLast任务操作将不会从continuous-build任务执行。因此,这就是文件不会创建/更新的原因。
  • continuous-build gradle task中的onlyIf { !compileJava.state.upToDate }这一行告诉我们,只有当compileJava task状态发生变化时,任何task action才会被执行。简单地说,如果你在Java类中进行了代码更改,那么doLast action将从continuous-build task中执行,否则它将从执行中跳过。

因此,您的doLast操作完全取决于这两行dependsOn tasks.compileJavaonlyIf { !compileJava.state.upToDate }
为了演示,我更新了你的gradle任务来解释。

import java.time.Instant

tasks.register('continuous-build') {
    dependsOn tasks.compileJava
    onlyIf { !compileJava.state.upToDate }
    logger.lifecycle("Job executed at " + Instant.now())
    doLast {
        def file = new File(projectDir, "build/classes/java/main/.reloadTrigger");
        def created = file.createNewFile();
        logger.lifecycle("File created status :" + created);
        file.setLastModified(Instant.now().toEpochMilli())
        logger.lifecycle("Last modified date of the file: " + file.lastModified());
        logger.lifecycle("This message is never seen")
    }
}

字符串

首次执行:

x1c 0d1x的数据


第二次执行(Java类不变):

doLast任务操作将不会像点中解释的那样执行(因为这行onlyIf { !compileJava.state.upToDate })。


第三次执行(在Java类中修改):

doLast任务操作将被执行,这将触发文件被更新而不是创建,尽管时间戳这次将被更改。


第四次执行(在Java类中修改错误):

由于compileJava任务检测到其中一个Java类中存在编译错误,并且continuous-build任务依赖于compileJava,因此不会执行doLast任务操作。

相关问题