jamesfredley commented on code in PR #11:
URL: https://github.com/apache/grails-micronaut/pull/11#discussion_r4225110259


##########
build-logic/plugins/src/main/groovy/org/apache/grails/buildsrc/CompilePlugin.groovy:
##########
@@ -155,6 +175,60 @@ class CompilePlugin implements Plugin<Project> {
         }
     }
 
+    /**
+     * Writes the Groovy compiler configuration for {@code compile}, including 
the shared
+     * reproducibility script and this project's published version.
+     *
+     * <p>The published version is captured in {@code afterEvaluate}, after 
the build script assigns
+     * {@code version}. The script file is produced by a task, not written 
during configuration, so
+     * {@code clean compileGroovy} in one invocation regenerates it after 
{@code clean} deletes
+     * {@code build/}.</p>
+     */
+    private static void configurePublishedVersionScript(Project project, 
GroovyCompile compile) {
+        File baseScript = GradleUtils.findRootGrailsCoreDir(project)
+                .file('gradle/groovy-compile-configscript.groovy').asFile

Review Comment:
   The empty-base fallback is gone. 
`PublishedVersionCompilerScriptTask.baseScript` is a required `@InputFile`, so 
a missing reproducibility script fails the writer instead of emitting a script 
with an empty base. Fixed in d03db59a81.



##########
build-logic/plugins/src/main/groovy/org/apache/grails/buildsrc/CompilePlugin.groovy:
##########
@@ -155,6 +175,60 @@ class CompilePlugin implements Plugin<Project> {
         }
     }
 
+    /**
+     * Writes the Groovy compiler configuration for {@code compile}, including 
the shared
+     * reproducibility script and this project's published version.
+     *
+     * <p>The published version is captured in {@code afterEvaluate}, after 
the build script assigns
+     * {@code version}. The script file is produced by a task, not written 
during configuration, so
+     * {@code clean compileGroovy} in one invocation regenerates it after 
{@code clean} deletes
+     * {@code build/}.</p>
+     */
+    private static void configurePublishedVersionScript(Project project, 
GroovyCompile compile) {
+        File baseScript = GradleUtils.findRootGrailsCoreDir(project)
+                .file('gradle/groovy-compile-configscript.groovy').asFile
+        File output = 
project.layout.buildDirectory.file("groovy-compiler/${compile.name}-config.groovy").get().asFile

Review Comment:
   The writer is now a typed task registered from `sourceSets.configureEach`. 
`configurationScriptFile` is set from `writer.flatMap { it.outputFile }`, so 
neither the build directory nor the task is realized during configuration. That 
also removes the `ConcurrentModificationException`. Fixed in d03db59a81.



##########
build-logic/plugins/src/main/groovy/org/apache/grails/buildsrc/CompilePlugin.groovy:
##########
@@ -155,6 +175,60 @@ class CompilePlugin implements Plugin<Project> {
         }
     }
 
+    /**
+     * Writes the Groovy compiler configuration for {@code compile}, including 
the shared
+     * reproducibility script and this project's published version.
+     *
+     * <p>The published version is captured in {@code afterEvaluate}, after 
the build script assigns
+     * {@code version}. The script file is produced by a task, not written 
during configuration, so
+     * {@code clean compileGroovy} in one invocation regenerates it after 
{@code clean} deletes
+     * {@code build/}.</p>
+     */
+    private static void configurePublishedVersionScript(Project project, 
GroovyCompile compile) {
+        File baseScript = GradleUtils.findRootGrailsCoreDir(project)
+                .file('gradle/groovy-compile-configscript.groovy').asFile
+        File output = 
project.layout.buildDirectory.file("groovy-compiler/${compile.name}-config.groovy").get().asFile
+        // Captured here, inside afterEvaluate, so version is the build 
script's value and the
+        // writer action does not touch the project. A configuration-time 
write would not survive
+        // `clean`, and compileGroovy would then fail because nothing 
regenerates its input.
+        String version = project.version?.toString() ?: ''
+        String name = project.name
+        String writerName = "grailsCompilerConfig${compile.name.capitalize()}"
+        // mustRunAfter(clean): `clean compileGroovy` schedules both, and 
command-line order is not a
+        // dependency. Without this, clean can delete the script after the 
writer creates it.
+        Task writer = project.tasks.register(writerName) { Task task ->
+            task.mustRunAfter('clean')
+            
task.inputs.file(baseScript).withPathSensitivity(PathSensitivity.NONE).withPropertyName('reproducibleCompilerScript')
+            task.inputs.property('publishedVersion', version)
+            task.inputs.property('publishedName', name)
+            task.outputs.file(output)
+            task.doLast {
+                writePublishedVersionScript(baseScript, output, version, name)
+            }
+        }.get()
+        compile.dependsOn(writer)
+        compile.groovyOptions.configurationScript = output

Review Comment:
   Same change as the writer-registration thread: the script path stays a 
provider until the task runs. Fixed in d03db59a81.



##########
build-logic/plugins/src/main/groovy/org/apache/grails/buildsrc/CompilePlugin.groovy:
##########
@@ -155,6 +175,60 @@ class CompilePlugin implements Plugin<Project> {
         }
     }
 
+    /**
+     * Writes the Groovy compiler configuration for {@code compile}, including 
the shared
+     * reproducibility script and this project's published version.
+     *
+     * <p>The published version is captured in {@code afterEvaluate}, after 
the build script assigns
+     * {@code version}. The script file is produced by a task, not written 
during configuration, so
+     * {@code clean compileGroovy} in one invocation regenerates it after 
{@code clean} deletes
+     * {@code build/}.</p>
+     */
+    private static void configurePublishedVersionScript(Project project, 
GroovyCompile compile) {
+        File baseScript = GradleUtils.findRootGrailsCoreDir(project)
+                .file('gradle/groovy-compile-configscript.groovy').asFile
+        File output = 
project.layout.buildDirectory.file("groovy-compiler/${compile.name}-config.groovy").get().asFile
+        // Captured here, inside afterEvaluate, so version is the build 
script's value and the
+        // writer action does not touch the project. A configuration-time 
write would not survive
+        // `clean`, and compileGroovy would then fail because nothing 
regenerates its input.
+        String version = project.version?.toString() ?: ''
+        String name = project.name
+        String writerName = "grailsCompilerConfig${compile.name.capitalize()}"
+        // mustRunAfter(clean): `clean compileGroovy` schedules both, and 
command-line order is not a
+        // dependency. Without this, clean can delete the script after the 
writer creates it.
+        Task writer = project.tasks.register(writerName) { Task task ->
+            task.mustRunAfter('clean')
+            
task.inputs.file(baseScript).withPathSensitivity(PathSensitivity.NONE).withPropertyName('reproducibleCompilerScript')
+            task.inputs.property('publishedVersion', version)
+            task.inputs.property('publishedName', name)
+            task.outputs.file(output)
+            task.doLast {
+                writePublishedVersionScript(baseScript, output, version, name)
+            }
+        }.get()
+        compile.dependsOn(writer)
+        compile.groovyOptions.configurationScript = output
+    }
+
+    private static void writePublishedVersionScript(File baseScript, File 
output, String version, String name) {
+        output.parentFile.mkdirs()
+        String base = baseScript.exists() ? 
baseScript.getText(StandardCharsets.UTF_8.name()) : ''
+        String script = """${base}

Review Comment:
   Same as the other base-script thread: the missing-file branch is gone, and 
the base script is a required task input. Fixed in d03db59a81.



##########
build-logic/plugins/src/main/groovy/org/apache/grails/buildsrc/CompilePlugin.groovy:
##########
@@ -155,6 +175,60 @@ class CompilePlugin implements Plugin<Project> {
         }
     }
 
+    /**
+     * Writes the Groovy compiler configuration for {@code compile}, including 
the shared
+     * reproducibility script and this project's published version.
+     *
+     * <p>The published version is captured in {@code afterEvaluate}, after 
the build script assigns
+     * {@code version}. The script file is produced by a task, not written 
during configuration, so
+     * {@code clean compileGroovy} in one invocation regenerates it after 
{@code clean} deletes
+     * {@code build/}.</p>
+     */
+    private static void configurePublishedVersionScript(Project project, 
GroovyCompile compile) {
+        File baseScript = GradleUtils.findRootGrailsCoreDir(project)
+                .file('gradle/groovy-compile-configscript.groovy').asFile
+        File output = 
project.layout.buildDirectory.file("groovy-compiler/${compile.name}-config.groovy").get().asFile
+        // Captured here, inside afterEvaluate, so version is the build 
script's value and the
+        // writer action does not touch the project. A configuration-time 
write would not survive
+        // `clean`, and compileGroovy would then fail because nothing 
regenerates its input.
+        String version = project.version?.toString() ?: ''
+        String name = project.name
+        String writerName = "grailsCompilerConfig${compile.name.capitalize()}"
+        // mustRunAfter(clean): `clean compileGroovy` schedules both, and 
command-line order is not a
+        // dependency. Without this, clean can delete the script after the 
writer creates it.
+        Task writer = project.tasks.register(writerName) { Task task ->
+            task.mustRunAfter('clean')
+            
task.inputs.file(baseScript).withPathSensitivity(PathSensitivity.NONE).withPropertyName('reproducibleCompilerScript')
+            task.inputs.property('publishedVersion', version)
+            task.inputs.property('publishedName', name)
+            task.outputs.file(output)
+            task.doLast {
+                writePublishedVersionScript(baseScript, output, version, name)
+            }
+        }.get()
+        compile.dependsOn(writer)
+        compile.groovyOptions.configurationScript = output
+    }
+
+    private static void writePublishedVersionScript(File baseScript, File 
output, String version, String name) {
+        output.parentFile.mkdirs()
+        String base = baseScript.exists() ? 
baseScript.getText(StandardCharsets.UTF_8.name()) : ''
+        String script = """${base}
+
+withConfig(configuration) {
+    inline(phase: 'CONVERSION') { source, context, classNode ->
+        classNode.putNodeMetaData('projectVersion', 
'${escapeGroovyLiteral(version)}')
+        classNode.putNodeMetaData('projectName', 
'${escapeGroovyLiteral(name)}')
+    }
+}
+"""
+        output.setText(script, StandardCharsets.UTF_8.name())
+    }
+
+    private static String escapeGroovyLiteral(String value) {
+        value.replace('\\', '\\\\').replace('\'', '\\\'')

Review Comment:
   Leaving the escaping as it was. The inputs are `project.version` and 
`project.name`, which will not contain newlines, and grails-gradle embeds the 
same values without further escaping. Backslash and single quote are still 
escaped.



-- 
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]

Reply via email to