casid / jte

Secure and speedy templates for Java and Kotlin.
https://jte.gg
Apache License 2.0
748 stars 56 forks source link

Make Gradle tasks cacheable #295

Closed marcospereira closed 9 months ago

marcospereira commented 10 months ago

What?

Gradle has a build cache that can be used to speed up the build process. From Gradle docs:

The Gradle build cache is a cache mechanism that aims to save time by reusing outputs produced by other builds. The build cache works by storing (locally or remotely) build outputs and allowing builds to fetch these outputs from the cache when it is determined that inputs have not changed, avoiding the expensive work of regenerating them.

I noticed that the build cache for the compileKotlin task was not working when using jte's generate or precompile, because the inputs generated by those tasks were not cached. Therefore, the generated code would be considered new input for compileKotlin, meaning the task cannot use the build cache. I suspect the same applies to compileJava, but I didn't check.

Local validation

Comparison when running the compileKotlin task with and without -Dorg.gradle.caching=true.

Before

Running with --build-cache multiple times has no effect since the cache is always stale:

time -h -p gradle --warning-mode=none --build-cache clean compileKotlin
> Task :cleanGenerateJte
> Task :cleanPrecompileJte UP-TO-DATE
> Task :clean
> Task :checkKotlinGradlePluginConfigurationErrors

> Task :generateJte
Extension gg.jte.models.generator.ModelExtension generated 3 files.

> Task :kspKotlin
> Task :compileKotlin

BUILD SUCCESSFUL in 6s
7 actionable tasks: 6 executed, 1 up-to-date
real 6.96
user 1.10
sys 0.16

After

With no cache (--warning-mode=none for brevity):

time -h -p gradle --warning-mode=none clean compileKotlin
> Task :cleanGenerateJte
> Task :cleanPrecompileJte UP-TO-DATE
> Task :clean
> Task :checkKotlinGradlePluginConfigurationErrors

> Task :generateJte
Extension gg.jte.models.generator.ModelExtension generated 3 files.

> Task :kspKotlin
> Task :compileKotlin

BUILD SUCCESSFUL in 8s
7 actionable tasks: 6 executed, 1 up-to-date
real 9.30
user 1.17
sys 0.15

With a populated build-cache (notice the FROM-CACHE):

time -h -p gradle --warning-mode=none --build-cache clean compileKotlin
> Task :cleanGenerateJte
> Task :cleanPrecompileJte UP-TO-DATE
> Task :clean
> Task :checkKotlinGradlePluginConfigurationErrors
> Task :generateJte FROM-CACHE
> Task :kspKotlin FROM-CACHE
> Task :compileKotlin FROM-CACHE

BUILD SUCCESSFUL in 1s
7 actionable tasks: 3 executed, 3 from cache, 1 up-to-date
real 1.49
user 1.13
sys 0.16

Let's see the effect on testClasses after running the command above:

time -h -p gradle --warning-mode=none --build-cache clean testClasses
> Task :cleanGenerateJte
> Task :cleanPrecompileJte UP-TO-DATE
> Task :clean
> Task :checkKotlinGradlePluginConfigurationErrors
> Task :generateJte FROM-CACHE
> Task :kspKotlin FROM-CACHE
> Task :compileKotlin FROM-CACHE
> Task :compileJava NO-SOURCE
> Task :processResources
> Task :classes
> Task :kspTestKotlin
> Task :processTestResources
> Task :compileTestKotlin
> Task :compileTestJava NO-SOURCE
> Task :testClasses

BUILD SUCCESSFUL in 8s
11 actionable tasks: 7 executed, 3 from cache, 1 up-to-date
real 8.94
user 1.21
sys 0.18

And then, since the build cache was populated:

time -h -p gradle --warning-mode=none --build-cache clean testClasses
> Task :cleanGenerateJte
> Task :cleanPrecompileJte UP-TO-DATE
> Task :clean
> Task :checkKotlinGradlePluginConfigurationErrors
> Task :generateJte FROM-CACHE
> Task :kspKotlin FROM-CACHE
> Task :compileKotlin FROM-CACHE
> Task :compileJava NO-SOURCE
> Task :processResources
> Task :classes
> Task :kspTestKotlin FROM-CACHE
> Task :compileTestKotlin FROM-CACHE
> Task :compileTestJava NO-SOURCE
> Task :processTestResources
> Task :testClasses

BUILD SUCCESSFUL in 1s
11 actionable tasks: 5 executed, 5 from cache, 1 up-to-date
real 2.40
user 1.26
sys 0.16
marcospereira commented 10 months ago

@casid, I'm trying to figure out how to add a test for this, though.

codecov[bot] commented 10 months ago

Codecov Report

All modified and coverable lines are covered by tests :white_check_mark:

Comparison is base (241efe8) 91.21% compared to head (5170ff2) 91.15%.

Additional details and impacted files ```diff @@ Coverage Diff @@ ## main #295 +/- ## ============================================ - Coverage 91.21% 91.15% -0.07% + Complexity 1197 1196 -1 ============================================ Files 76 76 Lines 3132 3132 Branches 484 484 ============================================ - Hits 2857 2855 -2 - Misses 167 168 +1 - Partials 108 109 +1 ``` [see 1 file with indirect coverage changes](https://app.codecov.io/gh/casid/jte/pull/295/indirect-changes?src=pr&el=tree-more&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Andreas+Hager)

:umbrella: View full report in Codecov by Sentry.
:loudspeaker: Have feedback on the report? Share it here.

edward3h commented 10 months ago

I don't have time to have a detailed look, but I skimmed through and it seems good.

marcospereira commented 10 months ago

I don't have time to have a detailed look, but I skimmed through and it seems good.

Yeah, I'm trying to understand why the tests Work On My Machine™ but not on CI.

marcospereira commented 10 months ago

Hum, it seems things are... broken(?) somehow. From this run: https://github.com/casid/jte/actions/runs/6748107408/job/18345752283?pr=295#step:6:479

> Task :publishToMavenLocal
Skipping task ':publishToMavenLocal' as it has no actions.

🤔

casid commented 10 months ago

Unfortunately, I'm not really a gradle expert, so I can't help much with this. :-(

marcospereira commented 10 months ago

Unfortunately, I'm not really a gradle expert, so I can't help much with this. :-(

No worries. I was able to figure out how to properly test the tasks when the build-cache is involved.

I think this is good to review/merge. 🚀

marcospereira commented 10 months ago

@casid @edward3h build is green, and this is good to be reviewed. :)

casid commented 10 months ago

LGTM, would wait a few more days with the merge, so that @edward3h might have a chance to look at it.

edward3h commented 10 months ago

I'm busy this weekend, but I can take a look on Monday.

edward3h commented 9 months ago

I am happy with this change. Thanks @marcospereira !

marcospereira commented 9 months ago

I am happy with this change. Thanks @marcospereira !

Awesome! Thanks for taking the time to review, @edward3h.

@casid, I guess this is good to merge/release then. 🍾

casid commented 9 months ago

Thanks everyone!

marcospereira commented 9 months ago

Hey @casid, just a quick check about when we can have a release with these changes. 🚀

casid commented 9 months ago

@marcospereira I just released version 3.1.5 :-)