codeconsole commented on code in PR #16114:
URL: https://github.com/apache/grails-core/pull/16114#discussion_r3741917138
##########
grails-gradle/plugins/src/main/groovy/org/grails/gradle/plugin/core/GrailsGradlePlugin.groovy:
##########
@@ -204,33 +199,63 @@ class GrailsGradlePlugin implements Plugin<Project> {
if (grailsExtension != null) {
c.groovyOptions.forkOptions.jvmArgumentProviders.add(new
GrailsCompileStaticArtefactsProvider(grailsExtension.compileStatic))
}
- Closure<String> userScriptGenerator = getGroovyCompilerScript(c,
project)
- c.doFirst {
- // This isn't ideal - we're performing configuration at
execution time, but the alternative would be having
- // to maintain a clean / configuration task and then gradle
would want to cache those tasks. Since the inputs
- // to those tasks would effectively be the runtimeClasspath,
dependency problems can arise if another task
- // changes the runtimeClasspath. To prevent having to add
those tasks into the dependency chain, use doFirst
- File combinedFile = groovyCompilerConfigFile.get().asFile
- if (!combinedFile.exists()) {
- combinedFile.parentFile.mkdirs()
- combinedFile.createNewFile()
- }
+ }
- String configuredScript = null
- if (c.groovyOptions.configurationScript) {
- configuredScript =
c.groovyOptions.configurationScript.text?.trim() ?: null
- }
- String grailsScript = userScriptGenerator?.call()
+ // The combined compiler configuration script is produced by its own
task rather than from a
+ // doFirst on the compile task. Gradle finalizes task properties
before any task action runs,
+ // so assigning groovyOptions.configurationScript from doFirst fails
from Gradle 9.7 on, where
+ // GroovyCompileOptions became a lazy property — "The value for task
':compileGroovy' property
+ // 'groovyOptions.configurationScriptFile' is final and cannot be
changed any further." Once
+ // the property is assigned during configuration, Gradle also treats
the script as an input
+ // file that has to exist before the compile task runs, which a
producing task guarantees
+ // across a `clean build` and a doFirst cannot.
+ //
+ // Wiring happens after evaluation so a configurationScript set by the
build script is already
+ // in place and gets folded into the combined file rather than
clobbered. Names are read via
+ // TaskCollection.names, which does not realize the tasks.
+ project.afterEvaluate {
Review Comment:
Confirmed and fixed in 8b8d063316. `TaskCollection.names` is an immutable
snapshot, so a `GroovyCompile` registered after the `afterEvaluate` got no
generator and no configuration script, silently.
Generator tasks are now registered from `sourceSets.configureEach`, which is
live — source sets are what create `GroovyCompile` tasks, so a source set added
from `projectsEvaluated` is covered.
One correction on the suggested remedy: a task rule plus string `dependsOn`
does not work. Rules are not consulted when resolving a `dependsOn` name — the
build fails at graph construction with `Task with name
'generateCompileGroovyGrailsCompilerConfig' not found`. And registering the
generator from inside the task-container callback is what the snapshot was
avoiding in the first place: it throws `TaskCreationException: Could not create
task ':compileGroovy'`. Hooking the source-set container sidesteps both.
Test: `GrailsGroovyCompilerConfigSpec` — *a GroovyCompile registered after
the project is evaluated still gets a generator*.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]