Skip to content

Conversation

@matrei
Copy link
Contributor

@matrei matrei commented Jan 13, 2026

Background

As part of the ongoing effort to upgrade Grails to Groovy 5, it became apparent that the Groovysh class is no longer available. It was replaced by the Main class when Groovy switched to JLine 3 (introduced in #2263).

Current Situation

Grails currently relies on Groovysh to start an interactive shell with a preconfigured Binding, for example:

Binding binding = new Binding()
binding.setVariable('ctx', this)
binding.setVariable(GrailsApplication.APPLICATION_ID, getBean(GrailsApplication))
new Groovysh(binding, new IO()).run('')

This approach allows Grails to inject application-specific context into the shell.

Problem

The new Main class does not provide a programmatic entry point that allows callers to supply a custom Binding. As a result, there is no straightforward way to replicate the existing Grails behavior using the new shell infrastructure.

Proposed Solution

This PR introduces a programmatic entry point to the Main class that makes it possible to inject a Binding. This restores the ability for Grails (and other consumers) to launch the Groovy shell with a predefined execution context, preserving existing functionality while remaining compatible with Groovy 5.

@codecov-commenter
Copy link

Codecov Report

❌ Patch coverage is 9.09091% with 10 lines in your changes missing coverage. Please review.
✅ Project coverage is 67.0199%. Comparing base (ddcd5dc) to head (f507941).

Files with missing lines Patch % Lines
...main/groovy/org/apache/groovy/groovysh/Main.groovy 9.0909% 10 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@                Coverage Diff                 @@
##               master      #2364        +/-   ##
==================================================
+ Coverage     66.9341%   67.0199%   +0.0858%     
- Complexity      29379      29413        +34     
==================================================
  Files            1382       1382                
  Lines          116156     116164         +8     
  Branches        20463      20465         +2     
==================================================
+ Hits            77748      77853       +105     
+ Misses          31958      31827       -131     
- Partials         6450       6484        +34     
Files with missing lines Coverage Δ
...main/groovy/org/apache/groovy/groovysh/Main.groovy 9.1304% <9.0909%> (+9.1304%) ⬆️

... and 6 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@paulk-asert
Copy link
Contributor

paulk-asert commented Jan 14, 2026

This looks good to me. I created GROOVY-11839 to track. There is a minor question on whether to use Binding or Map and if Map, whether to put it as the first param. This would just change the order if called from Java, but would allow explicit named params from Groovy - though I understand that Grails would be passing along a Map variable not using explicit named params. I'll ponder a little and suggest something here.

@paulk-asert
Copy link
Contributor

I merged this and made a slight tweak. Hope that's okay with what you have planned for Grails. Let me know if not.

@matrei matrei deleted the grovvysh-binding branch January 15, 2026 07:08
@matrei
Copy link
Contributor Author

matrei commented Jan 15, 2026

Nice! Thanks @paulk-asert.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants