close

Spring Shell 2.1.0 is now available

On behalf of the team and everyone who has contributed, I’m happy to announce that Spring Shell 2.1.0 has been released and is now available from https://repo.spring.io/milestone.

Please see the release notes for more details.

Thanks to all those who have contributed with issue reports and pull requests.

Earlier this year we started an effort align the project with latest Spring Boot and Spring Framework versions as it was difficult to use existing Spring Shell release of a spring family.

Originally the main issue we wanted to address was a removal of a bean cycles which Spring Boot is now enforcing by default. While this feature can be turned off it is not something Spring Shell should require. This required a lot of changes and we chose to handle it with rework of a shell internals. One big challenge was how the old Spring Shell worked by essentially keeping command info methods backed by @ShellMethod annotations and then calling those methods via reflection using not so well defined ways.

Now that it was clear that we needed to do a bigger overhaul it made sense to do further development now rather than waiting for Spring Boot 3 and Spring Framework 6 which Spring Shell eventually would have needed to support.

Here is a recap of the changes that were done:

Command Registration

CommandRegistration is a new programmatic way to define commands. The existing annotation model of commands translates to these registration behind a scene. This new registration model now allows to us control commands dynamically which wasn’t the case in the old shell implementation.

Existing Annotations

What comes for @ShellMethod and @ShellOption We’ve tried to keep those compatible and future development will most likely introduce new annotations more aligned with CommandRegistration.

Theming

Modern terminal implementations are not bound to just show a simple text, but allow for different types of font styles and can be used with colors. In the old Spring Shell these were mostly hard coded while it was possible to use ANSI sequences via JLine to write anything into a console. It made sense to introduce a theming system where text written can be styled and figures chosen per style. Figures are just unicode characters supported by modern terminals which is the basis for creating pretty shell UI’s.

sample-style-list

sample-figure-list

UI Components

You’ve mostly likely used various CLI tools which go beyond just asking some text from a user and then doing something based on that. For example GitHub CLI is a good example as some of its commands enter interactive mode and ask users for input using various tricks like selector lists and other sort of shell style forms.

What we wanted to accomplish in Spring Shell was to create these components which can be use independently or combine those into a flow.

component-flow-showcase-1

Graal

A big topic in a future Spring Framework release is native compilation with GraalVM. This obviously makes a big impact on the CLI side as that little jvm bootstrap timeout goes away when your existing code is translated into native binary.

With 2.1.x it was shown using our experimental Spring Native project that it is possible to create a Spring Shell application which works the same way in Linux, MacOS and Windows.

sample-version-linux

sample-version-win

sample-version-macos

Official support for GraalVM in Spring Shell comes with 3.x.

Templating

Writing a command into a terminal is easy as you essentially just write something. However what we’ve done in some of the built-in commands like help is not always something a user wants to have or they may have other reasons to modify how it looks. Some default outputs from Spring Shell are now based on templates based on ST4 from the ANTRL project.

This allows a user to replace templates used in Spring Shell and modify default behaviour. These templates also integrate into the theme framework so that it’s possible to define templates per active theme.

How can you help?

Project Page | GitHub | Issues | Documentation

comments powered by Disqus