Support Gradle configuration cache
Opened this issue · 7 comments
$ mkdir /tmp/test && cd "$_"
$ gradle init --type java-library --java-version 21 --project-name test --dsl groovy --test-framework junit-jupiter --no-comments --no-incubating --quiet
$ perl -i -l -p -e "print \" id 'net.nemerosa.versioning' version '2.8.2'\" if $. == 4" lib/build.gradle
$ printf '\nversioning {}\nversion = versioning.info.full\n' >> lib/build.gradle
$ git init --quiet
$ git add -A
$ git commit --quiet -m "initial"
$ ./gradlew --configuration-cache --quiet clean
FAILURE: Build failed with an exception.
* Where:
Build file '/private/tmp/test/lib/build.gradle' line: 32
* What went wrong:
Configuration cache problems found in this build.
2 problems were found storing the configuration cache.
- Build file 'lib/build.gradle': external process started 'git --version'
See https://docs.gradle.org/8.7/userguide/configuration_cache.html#config_cache:requirements:external_processes
- Build file 'lib/build.gradle': external process started 'git config --system --edit'
See https://docs.gradle.org/8.7/userguide/configuration_cache.html#config_cache:requirements:external_processes
See the complete report at file:///private/tmp/test/build/reports/configuration-cache/2cvh062oate61b7yhx8pzmmbf/3h3vaqnt0bpkufj7xky7uxoi0/configuration-cache-report.html
> Starting an external process 'git --version' during configuration time is unsupported.
> Starting an external process 'git config --system --edit' during configuration time is unsupported.
* 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 2s
$ gradle --version
------------------------------------------------------------
Gradle 8.7
------------------------------------------------------------
Build time: 2024-03-22 15:52:46 UTC
Revision: 650af14d7653aa949fce5e886e685efc9cf97c10
Kotlin: 1.9.22
Groovy: 3.0.17
Ant: Apache Ant(TM) version 1.10.13 compiled on January 4 2023
JVM: 21.0.2 (Eclipse Adoptium 21.0.2+13-LTS)
OS: Mac OS X 12.7.4 x86_64
$ cat lib/build.gradle
plugins {
id 'java-library'
id 'net.nemerosa.versioning' version '2.8.2'
}
repositories {
mavenCentral()
}
dependencies {
testImplementation libs.junit.jupiter
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
api libs.commons.math3
implementation libs.guava
}
java {
toolchain {
languageVersion = JavaLanguageVersion.of(21)
}
}
tasks.named('test') {
useJUnitPlatform()
}
versioning {}
version = versioning.info.full
configuration-cache-report.html
at net.nemerosa.versioning.git.GitInfoService.getInfo(GitInfoService.groovy:37)
at net.nemerosa.versioning.SCMInfoService$getInfo.call(Unknown Source)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:148)(3 internal lines hidden)
at net.nemerosa.versioning.VersioningExtension.computeInfo(VersioningExtension.groovy:195)
at net.nemerosa.versioning.VersioningExtension.getInfo(VersioningExtension.groovy:182)
at net.nemerosa.versioning.VersioningExtension_Decorated.getInfo(Unknown Source)
Interim solution?
It is possible to declare that a particular task is not compatible with the configuration cache via the Task.notCompatibleWithConfigurationCache() method.
Configuration cache problems found in tasks marked incompatible will no longer cause the build to fail.
https://docs.gradle.org/current/userguide/configuration_cache.html#config_cache:task_opt_out
Hi,
I see in the first snippet that you're using the version 2.8.2? Is that possible to try with version 3.1.0.
As for the cache configuration issue, I don't know how the call to the external command (git
) could be cached and if it even makes sense. So I agree with you that the least bad approach would maybe to mark it as not compatible with the cache.
What do you think?
$ mkdir /tmp/test && cd "$_"
$ gradle init --type java-library --java-version 21 --project-name test --dsl groovy --test-framework junit-jupiter --no-comments --no-incubating --quiet
$ perl -i -l -p -e "print \" id 'net.nemerosa.versioning' version '3.1.0'\" if $. == 4" lib/build.gradle
$ printf '\nversioning {}\nversion = versioning.info.full\n' >> lib/build.gradle
$ git init --quiet
$ git add -A
$ git commit --quiet -m "initial"
$ ./gradlew --configuration-cache --quiet clean
FAILURE: Build failed with an exception.
* Where:
Build file '/private/tmp/test/lib/build.gradle' line: 32
* What went wrong:
Configuration cache problems found in this build.
2 problems were found storing the configuration cache.
- Build file 'lib/build.gradle': external process started '/usr/local/bin/git --version'
See https://docs.gradle.org/8.7/userguide/configuration_cache.html#config_cache:requirements:external_processes
- Build file 'lib/build.gradle': external process started '/usr/local/bin/git config --system --show-origin --list -z'
See https://docs.gradle.org/8.7/userguide/configuration_cache.html#config_cache:requirements:external_processes
See the complete report at file:///private/tmp/test/build/reports/configuration-cache/2cvh062oate61b7yhx8pzmmbf/ebyxie6m7vpbm2q7bw5v4bf88/configuration-cache-report.html
> Starting an external process '/usr/local/bin/git --version' during configuration time is unsupported.
> Starting an external process '/usr/local/bin/git config --system --show-origin --list -z' during configuration time is unsupported.
* 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 5s
The example provided by the Gradle team wraps the git
call inside providers.exec
:
def gitVersion = providers.exec {
commandLine("git", "--version")
}.standardOutput.asText.get()
Maybe calls to SCMInfoService
should be wrapped in providers.exec
or calls to Grgit
and SVNClientManager
should be wrapped.
There is Gradle Roadmap item this issue might be added to ...
https://blog.gradle.org/road-to-gradle-9#configuration-cache-improvements
In Gradle 9.0, the Configuration Cache will be the preferred mode of execution, and turning it off will be deprecated.
Here is what another project using Grgit did:
I was able to work around this by wrapping my calls to versioning.info
in a provider:
val provider = project.provider {
// Intentionally skip cache (not sure if necessary though)
val info = versioning.computeInfo()
runCatching { info.tag ?: info.full }.getOrDefault("0.0.0")
}
project.version = provider.get()