You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@grails.apache.org by "jamesfredley (via GitHub)" <gi...@apache.org> on 2026/07/22 06:38:32 UTC

[I] Move src/main/scripts command resources out of runtime plugin artifacts [grails-core]

jamesfredley opened a new issue, #16035:
URL: https://github.com/apache/grails-core/issues/16035

   ## Summary
   
   PR #15948 successfully isolates `ApplicationCommand` implementations and their CLI-only dependencies in companion `-cli` artifacts, but the older plugin script-command channel still packages CLI-only command resources in each plugin's normal runtime JAR.
   
   `GrailsPluginGradlePlugin.configurePluginResources` copies everything under `src/main/scripts` into the main `processResources` output at `META-INF/commands`. That main plugin JAR is then placed on the application's `runtimeClasspath` and inside deployed `bootJar`/`bootWar` artifacts.
   
   This affects both command resource formats resolved from that directory:
   
   - `*.groovy`, compiled at command execution time by `GroovyScriptCommandFactory`
   - `*.yml` / `*.json`, parsed by `YamlCommandFactory` into multi-step commands
   
   The CLI implementation dependencies themselves remain correctly isolated. The remaining problem is command-only code/resources in the deployed runtime plugin artifact.
   
   Related: #15377 and #15948.
   
   ## Current behavior
   
   The plugin convention still performs this main-source-set copy:
   
   ```groovy
   TaskProvider<Copy> copyCommands = project.tasks.register('copyCommands', Copy) {
       from("${project.projectDir}/src/main/scripts")
       into("${processResources.destinationDir}/META-INF/commands")
   }
   processResources.dependsOn(copyCommands, copyTemplates)
   ```
   
   `ClasspathCommandResourceResolver` later scans `classpath*:META-INF/commands/*.<extension>` from the command runner's context classloader. `runCommand` intentionally combines the application runtime classpath with `grailsCliClasspath`, so discovery currently depends on the command resources remaining in runtime plugin JARs.
   
   ## Reproduction
   
   The existing legacy-command fixture contains:
   
   ```text
   grails-test-examples/legacy-commands-plugin/src/main/scripts/hello-legacy-script.groovy
   ```
   
   Build and inspect the plugin and deployable application archives:
   
   ```bash
   ./gradlew :grails-test-examples-legacy-commands:bootJar
   jar tf grails-test-examples/legacy-commands-plugin/build/libs/grails-test-examples-legacy-commands-plugin-0.0.1.jar
   jar tf grails-test-examples/legacy-commands/build/libs/grails-test-examples-legacy-commands-0.1.war
   ```
   
   The plugin JAR contains:
   
   ```text
   META-INF/commands/hello-legacy-script.groovy
   ```
   
   The deployable WAR contains that plugin JAR:
   
   ```text
   WEB-INF/lib/grails-test-examples-legacy-commands-plugin-0.0.1.jar
   ```
   
   The same copy task accepts YAML and JSON files without filtering, and `YamlCommandFactory` resolves those formats from the same `META-INF/commands` location.
   
   Control checks confirm that PR #15948's dependency isolation is working:
   
   ```bash
   ./gradlew :grails-test-examples-legacy-commands:dependencyInsight \
     --dependency grails-shell-cli --configuration runtimeClasspath
   ./gradlew :grails-test-examples-legacy-commands:dependencyInsight \
     --dependency grails-core-cli --configuration runtimeClasspath
   ```
   
   Both report no matching runtime dependency. The deployable WAR also contains no `grails-shell-cli`, `grails-core-cli`, `grails-core-cli-legacy`, or `grails-profiles-*` JAR.
   
   ## Expected behavior
   
   When a plugin publishes a companion CLI artifact, command resources from `src/main/scripts` should be placed in that companion artifact and excluded from the normal runtime plugin JAR. The companion remains available through `grailsCliClasspath`, preserving command discovery and execution without shipping command-only resources in deployed applications.
   
   ## Suggested coverage
   
   Add a functional fixture containing both:
   
   ```text
   src/main/scripts/example-script.groovy
   src/main/scripts/example-multi-step.yml
   ```
   
   Verify that:
   
   1. The normal plugin JAR and consuming `bootJar`/`bootWar` do not contain either command resource.
   2. The companion `-cli` JAR contains both resources under `META-INF/commands`.
   3. `grails <command>` and `runCommand` still discover and execute both commands through `grailsCliClasspath`.
   4. `grails-shell-cli`, profile artifacts, and companion CLI dependencies remain absent from `runtimeClasspath` and the deployed archive.
   
   ## Out of scope / verified isolated
   
   - YAML commands packaged inside profile JARs under `META-INF/grails-profile/commands` are resolved by the CLI profile repository and were absent from the deployed application archive.
   - `ServiceCommandFactory`, its `META-INF/services` registrations, and built-in profile command implementations remain in `grails-shell-cli`; that artifact was absent from the application's runtime classpath and deployed WAR.
   


-- 
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: notifications-unsubscribe@grails.apache.org.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [I] Move src/main/scripts command resources out of runtime plugin artifacts [grails-core]

Posted by "jdaugherty (via GitHub)" <gi...@apache.org>.
jdaugherty closed issue #16035: Move src/main/scripts command resources out of runtime plugin artifacts
URL: https://github.com/apache/grails-core/issues/16035


-- 
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: notifications-unsubscribe@grails.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org