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
> 

Reply via email to