James, Thank you for walking through this with me yesterday.
If we look at the collective features and functionality provided across these tools (grails-shell-cli, grails-wrapper, profiles, grails-forge-cli, grails-forge-api, start.grails.org, IntelliJ Grails Plugin grails-shell-cli integration): 1. grails project generation, before the the project exists 2. grails component generation within an existing grails application such as domains, services, tests, etc. 3. execution of grails scripts, including from plugins, such as list-plugins or dbm-update I think the following are important to maintain from a feature and historical/backwards compatibility standpoint. The implementation can and should be changed, modernized and simplified and most importantly consolidated, where possible. ./grails can start the process which performs all three of the items above ./grailsw can start the process which performs 2 and 3, within an existing application maintaining an interactive mode on these is a nice to have grails-shell-cli and grails-forge-cli have cli autocomplete, with grails-forge-cli being more advanced. We should maintain this. Some of what is provided by these tools overlaps with Gradle features and tasks or even directly calls Gradle. Where possible and logical, we should continue to move in that direction while maintaining simple command syntax and without requiring complex end project changes. grails-wrapper and the IntelliJ Grails Plugin both call the grails-shell-cli when executing grails scripts. So there are at leas 3 ways to get to grails-shell-cli today. I think keeping these is important, but any simplification or consolidation of code will make maintenance much easier. profiles and grails-forge-core both handle initial grails application generation and some grails component generation. grails-forge-core is more advanced and has had substantially more effort applied in recent years. My opinion is that profiles should exist for Grails 7.0.x, but likely be deprecated for 7.1.x and then profiles should fold into grails-forge-core for Grails 8.x.x. As part of this, we need to make it easier to extend grails-forge like has been done historically with profiles, so companies can have custom grails-forge features. With all that said, I am on board with this proposal of changes. James On 2025/05/06 16:35:16 James Daugherty wrote: > Hi Everyone, > > James F & I have been discussing the ASF release process. I've previously > mentioned that we have to have reproducible builds to use GitHub actions. > We have made the discovery that it's impossible to have reproducible builds > in forge due to this bug: https://github.com/oracle/graal/issues/291 > Moreover, upon investigation, the shipped binary size of the > grails-forge-cli is 81mb. The jar files are only 40mb. For this reason, > we want to propose we ship the jar files instead to be compliant with > Apache's requirements. > > With that said, what follows is what we've found & what we want to change > so that we have: > 1. reproducible builds > 2. flexibility to call either forge or shell > 3. keep shipped binary sizes to a minimum (bandwidth saving) > > My thought process follows, and a set of requirements to implement what we > need to achieve these calls. Please review and provide feedback. > > > Thoughts & Proposal: > ------------------------------------------------------ > * Following project structures today: > 1. Single Project > 2. Multi Project Grails Builds > 3. Multi Project Mixed Framework Builds > > * a `Grails` shell script has to be at the root > - executing that shell script needs to divert to either the > grails-shell-cli or the grails-forge-cli > - alternatively we can have a basic application that passes through to > either of them > > * How to find the root directory > - look for gradle.properties > > * Where to put binaries > - .grails/$grailsVersion/lib > > * We ship "a" grails wrapper still with the project? > - yes, called grailsw or grailsw.bat > > * How do we ship the micronaut libraires? > - currently 81mb of the binary, but 40gig > > * Proposal: keep grails-wrapper in grails-core > - purpose of this project is to download a given `grails-wrapper-impl` > project jar so that we don't distribute large file sizes (saving money) > - forge will use this > - sdkman will use grails-wrapper-impl > - grails-wrapper will write to .grails directory > > * Proposal: change grails-wrapper-impl to be able to delegate to one or the > other > - wrapper will be changed to look for a .grails directory and that > directory will contain all of the jar files for shell-cli or forge-cli > > * Proposed grails structure > gradle.properties <- will be required, grails-wrapper will look for this > file to determine the grails version instead of the latest > .grails <- folder for libs that get downloaded from grailsw invocation. > grails-wrapper.jar <- this is the grails-wrapper project's jar file, it > will be at the root instead of in .grails > grailsw <- this will be the grails-wrapper-impl project > grailsw.bat <- bat verison of grailsw > > ------------------------------------------------------------ > > Required changes then are: > 1. move `grails-wrapper-impl` to grails forge since it will need both forge > + grails shell > 2. change the name of the shell script for `grails-wrapper-impl` to be > `grails` > 3. change the name of the shell script for `grails-forge-cli` to > `grails-forge-cli` instead of `grails` > 4. change the name of the shell script for `grails-shell-cli` to > `grails-shell-cli` instead of `grails` > 5. enhance `grails-wrapper` in core to download the grails version found in > the current project via the gradle.properties (or parent folders until one > is found) > 6. enhance `grails-wrapper` to save to .grails directory in project root > 7. enhance `grails-wrapper-impl` to invoke grails-shell-cli or to invoke > grails-forge-cli; add `-t/--type [forge|shell]` as the option. Default to > `-t shell` > 8. the binaries shipped for sdkman will be `grails-wrapper-impl` - which > will include forge & shell > 9. ship `grails-shell-cli` and `grails-forge-cli` scripts in addition to > `grails` script for sdkman > 10. enhance grails-wrapper-impl to have bash completion for --forge, maybe > some basics for shell (out of scope for all of shell) > > Other thoughts: > 1. you have to keep forge separate from grails-core because to extend to > forge, you have to fork it. > 2. for release voting we'll always build both grails-core & grails-forge > together. We will vote on them together too. > > Short term: > 1. have compatibility for both grails-shell-cli & grails-forge-cli via the > grails-wrapper-impl gradle project in grails-core > 2. have the option to use either shell or forge because we ship the > original commands & our delegator (grails-wrapper-impl) can call either via > a flag > > Long term: > 1. change grails-forge-cli to be grails-wrapper-impl > 2. enhance forge to be extendable so that it does not have to be forked > like it does today (i.e. similar to the way profiles work) > > > -James >