jamesfredley commented on code in PR #16082:
URL: https://github.com/apache/grails-core/pull/16082#discussion_r3699559916
##########
grails-gradle/plugins/src/main/groovy/org/grails/gradle/plugin/core/GrailsPluginGradlePlugin.groovy:
##########
@@ -244,22 +246,69 @@ class GrailsPluginGradlePlugin extends GrailsGradlePlugin
{
}
}
+ /**
+ * Packages plugin templates into the runtime jar and routes command
scripts into either the
+ * runtime jar or the companion {@code -cli} jar.
+ *
+ * <p>When {@link GrailsCliArtifactGradlePlugin} is applied, {@code
src/main/scripts} is copied
+ * into the cli source set as {@code META-INF/commands} so
Groovy/YAML/JSON command resources
+ * ship only on {@code grailsCliClasspath} and stay out of {@code
runtimeClasspath},
+ * {@code bootJar}, and {@code bootWar}. Without a companion, the
historical behavior is
+ * preserved: scripts remain in the runtime plugin jar so unmigrated
Grails 7 plugins and
+ * {@code legacyCommandSupport} consumers keep discovering them on the
application classpath.
+ * Templates always stay on the runtime jar.</p>
+ */
@CompileDynamic
protected void configurePluginResources(Project project) {
project.afterEvaluate() {
ProcessResources processResources = (ProcessResources)
project.tasks.getByName('processResources')
+ boolean hasCliCompanion =
project.pluginManager.hasPlugin(GrailsCliArtifactGradlePlugin.PLUGIN_ID)
+ ProcessResources commandResources = processResources
+ if (hasCliCompanion) {
+ SourceSet cliSourceSet =
project.extensions.getByType(SourceSetContainer)
+
.getByName(GrailsCliArtifactGradlePlugin.CLI_SOURCE_SET_NAME)
+ commandResources = (ProcessResources)
project.tasks.getByName(cliSourceSet.processResourcesTaskName)
+ }
- TaskProvider<Copy> copyCommands =
project.tasks.register('copyCommands', Copy) {
- from("${project.projectDir}/src/main/scripts")
- into("${processResources.destinationDir}/META-INF/commands")
+ TaskProvider<Copy> copyCommands =
project.tasks.register('copyCommands', Copy) { Copy copy ->
+ copy.from("${project.projectDir}/src/main/scripts")
+ // Resolve the destination lazily so the process*Resources
output dir is final.
+ copy.into {
+ "${commandResources.destinationDir}/META-INF/commands"
+ }
}
- TaskProvider<Copy> copyTemplates =
project.tasks.register('copyTemplates', Copy) {
- from("${project.projectDir}/src/main/templates")
- into("${processResources.destinationDir}/META-INF/templates")
+ TaskProvider<Copy> copyTemplates =
project.tasks.register('copyTemplates', Copy) { Copy copy ->
+ copy.from("${project.projectDir}/src/main/templates")
+ copy.into {
+ "${processResources.destinationDir}/META-INF/templates"
+ }
}
processResources.setDuplicatesStrategy(DuplicatesStrategy.INCLUDE)
- processResources.dependsOn(copyCommands, copyTemplates)
+ if (hasCliCompanion) {
+
commandResources.setDuplicatesStrategy(DuplicatesStrategy.INCLUDE)
+ commandResources.dependsOn(copyCommands)
+ processResources.dependsOn(copyTemplates)
+ // A prior non-companion (or pre-migration) build may have
left src/main/scripts
+ // copies under the main processResources output. Wipe
META-INF/commands there so
+ // incremental jars do not keep shipping them;
processResources then re-runs (its
+ // outputs changed) and restores any hand-authored
src/main/resources/META-INF/commands.
+ // Use the configured processResources destination, not a
hard-coded build path.
+ TaskProvider cleanStaleRuntimeCommands = project.tasks
+ .register('cleanStaleRuntimeCommandResources') { Task
cleanTask ->
+ cleanTask.outputs.upToDateWhen { false }
+ cleanTask.doLast {
+ project.delete(new
File(processResources.destinationDir, 'META-INF/commands'))
+ }
+ }
Review Comment:
Addressed in 7a3049d707.
Removed `cleanStaleRuntimeCommandResources` entirely (no more
`outputs.upToDateWhen { false }` wired into `processResources`/`jar`).
Instead:
1. `copyCommands` / `copyTemplates` are now **`Sync`** tasks with **unique**
dirs under `build/tmp/`
2. `processResources` / `processCliResources` consume those via `from(...)`
so Gradle owns each path
3. When a companion is present, the runtime `jar` filters
`META-INF/commands` to only hand-authored
`src/main/resources/META-INF/commands` entries - covers leftover files from
prior non-companion packaging **without** a forced clean task
`PluginScriptCommandPackagingSpec` still asserts companion vs non-companion
packaging, unique Sync output path, and that seeded stale runtime leftovers are
excluded from the runtime jar while hand-authored commands remain.
##########
grails-gradle/plugins/src/main/groovy/org/grails/gradle/plugin/core/GrailsPluginGradlePlugin.groovy:
##########
@@ -244,22 +246,69 @@ class GrailsPluginGradlePlugin extends GrailsGradlePlugin
{
}
}
+ /**
+ * Packages plugin templates into the runtime jar and routes command
scripts into either the
+ * runtime jar or the companion {@code -cli} jar.
+ *
+ * <p>When {@link GrailsCliArtifactGradlePlugin} is applied, {@code
src/main/scripts} is copied
+ * into the cli source set as {@code META-INF/commands} so
Groovy/YAML/JSON command resources
+ * ship only on {@code grailsCliClasspath} and stay out of {@code
runtimeClasspath},
+ * {@code bootJar}, and {@code bootWar}. Without a companion, the
historical behavior is
+ * preserved: scripts remain in the runtime plugin jar so unmigrated
Grails 7 plugins and
+ * {@code legacyCommandSupport} consumers keep discovering them on the
application classpath.
+ * Templates always stay on the runtime jar.</p>
+ */
@CompileDynamic
protected void configurePluginResources(Project project) {
project.afterEvaluate() {
ProcessResources processResources = (ProcessResources)
project.tasks.getByName('processResources')
+ boolean hasCliCompanion =
project.pluginManager.hasPlugin(GrailsCliArtifactGradlePlugin.PLUGIN_ID)
+ ProcessResources commandResources = processResources
+ if (hasCliCompanion) {
+ SourceSet cliSourceSet =
project.extensions.getByType(SourceSetContainer)
+
.getByName(GrailsCliArtifactGradlePlugin.CLI_SOURCE_SET_NAME)
+ commandResources = (ProcessResources)
project.tasks.getByName(cliSourceSet.processResourcesTaskName)
+ }
- TaskProvider<Copy> copyCommands =
project.tasks.register('copyCommands', Copy) {
- from("${project.projectDir}/src/main/scripts")
- into("${processResources.destinationDir}/META-INF/commands")
+ TaskProvider<Copy> copyCommands =
project.tasks.register('copyCommands', Copy) { Copy copy ->
+ copy.from("${project.projectDir}/src/main/scripts")
+ // Resolve the destination lazily so the process*Resources
output dir is final.
+ copy.into {
+ "${commandResources.destinationDir}/META-INF/commands"
+ }
}
- TaskProvider<Copy> copyTemplates =
project.tasks.register('copyTemplates', Copy) {
- from("${project.projectDir}/src/main/templates")
- into("${processResources.destinationDir}/META-INF/templates")
+ TaskProvider<Copy> copyTemplates =
project.tasks.register('copyTemplates', Copy) { Copy copy ->
+ copy.from("${project.projectDir}/src/main/templates")
+ copy.into {
+ "${processResources.destinationDir}/META-INF/templates"
+ }
}
processResources.setDuplicatesStrategy(DuplicatesStrategy.INCLUDE)
- processResources.dependsOn(copyCommands, copyTemplates)
+ if (hasCliCompanion) {
+
commandResources.setDuplicatesStrategy(DuplicatesStrategy.INCLUDE)
+ commandResources.dependsOn(copyCommands)
+ processResources.dependsOn(copyTemplates)
+ // A prior non-companion (or pre-migration) build may have
left src/main/scripts
+ // copies under the main processResources output. Wipe
META-INF/commands there so
+ // incremental jars do not keep shipping them;
processResources then re-runs (its
+ // outputs changed) and restores any hand-authored
src/main/resources/META-INF/commands.
+ // Use the configured processResources destination, not a
hard-coded build path.
+ TaskProvider cleanStaleRuntimeCommands = project.tasks
+ .register('cleanStaleRuntimeCommandResources') { Task
cleanTask ->
+ cleanTask.outputs.upToDateWhen { false }
+ cleanTask.doLast {
+ project.delete(new
File(processResources.destinationDir, 'META-INF/commands'))
+ }
+ }
Review Comment:
Agreed - forced clean tasks were the wrong tool. Fixed in 7a3049d707 per
your guidance:
- Unique Sync output dirs for `copyCommands` / `copyTemplates`
(`build/tmp/grails-plugin-*`)
- Downstream `process*Resources` consume via `from(...)` so Gradle tracks
ownership
- No clean task forced out-of-date or wired into every build
For leftovers already sitting under `processResources.destinationDir` from
the old side-write design, the runtime jar filters non-hand-authored
`META-INF/commands` entries when a companion is present (packaging-time filter,
not a clean task).
--
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]