[ 
https://issues.apache.org/jira/browse/CAMEL-23810?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Claus Ibsen updated CAMEL-23810:
--------------------------------
    Description: 
Port the Camel CLI (dsl/camel-jbang) from picocli to aesh, as JBang did: 
[https://www.jbang.dev/learn/from-picocli-to-sh-how-porting-jbang-s-cli-made-everything-better/]
 (jbangdev/jbang#2453).

Starts from the state after CAMEL-25388 (exit codes 0/1/2/3/70/124, 
CAMEL-25389) and CAMEL-24724 stage 1 and 2 (run and export are the picocli-free 
camel-jbang-run engine), and keeps the exit code contract.

h2. What reaches beyond the command layer

* *The plugin SPI is picocli*: {{Plugin.customize(CommandLine, 
CamelJBangMain)}} is public, and plugins outside Camel implement it: forage 
(Kaoto), kit, and the test plugin mounts the picocli commands of Citrus 
({{org.citrusframework.jbang.cli}}) with a picocli execution strategy.
* *The metadata and docs mojo reads the source*: 
{{PrepareCamelJBangCommandsMojo}} regex-parses the {{addSubcommand}} chains of 
{{CamelJBangMain}} and the picocli annotations (Roaster). The 175 pages under 
{{jbang-commands/}} and the JSON that AskTools uses come from it.
* *{{camel shell}} and the shell panel of the TUI* use jline's 
{{PicocliCommandRegistry}}.

h2. Size (main, 2026-10-31)

164 {{@Command}}, 861 {{@Option}}, 355 boolean options (160 {{arity="0..1"}}, 
89 {{fallbackValue="true"}}), 59 {{@Mixin}}, 5 converters, 17 parameter 
consumers ({{DebugConsumer}} looks ahead), 42 completion candidate classes, 
{{scope=INHERIT}} on {{--profile}}, user configuration via 
{{PicocliPropertiesDefaultProvider}}, {{originalArgs()}} to start the CLI again 
in another process ({{Run}}, {{Debug}}, {{InfraRun}}), 96 test files using 
picocli directly.

h2. aesh (checked 2026-10-31)

* 3.18.6 ({{org.aesh:aesh}}, {{aesh-processor}}, {{aesh-bom}}), Apache-2.0, 
Java 8 baseline. Annotation processor (no reflection, one registry per jar), 
{{@Mixin}}, negatable, {{fallbackValue}}/{{optionalValue}}, {{inherited}}, 
converters, completers, {{DefaultValueProvider}}, 
{{CommandResult.valueOf(int)}}, {{MutableCommandRegistry}} for commands added 
at runtime, AsciiDoc doc and bash/zsh/fish completion generators.
* No picocli compatibility layer: every annotation is rewritten (JBang: one PR, 
134 files).
* Risks: jbang#2504 (primitive boolean options) still open, JBang worked around 
it with boxed {{Boolean}}; bus factor about 1; about 40 releases in 2026 with 
API churn ({{@GroupCommandDefinition}} removed in 3.15); stricter parsing than 
picocli around attached values ({{-R-Xmx4G}}, {{-D k=v}}). Pin an exact version.

h2. Plan

As stage 2 of CAMEL-24724: a guard first, seams while still on picocli, then 
one switch. Not per command group (two parsers in one command tree).

# *Measure* the startup of {{camel --help}}, {{camel ps}}, {{camel version}} on 
the JVM and the share of picocli (part may be the eager creation of 143 
subcommands and the plugins, which picocli could do lazily too). A decision 
point: if the gain is small, the reasons are completion, the native launcher 
and staying aligned with JBang.
# *A golden guard of the CLI surface*, on picocli: the committed metadata JSON 
and pages, plus a {{CliParseGoldenTest}} recording command lines per command, 
the field values after parsing, the exit code and the help (booleans {{0..1}}, 
{{--profile}}, the lookahead consumers, {{split}}, converters, user 
configuration, {{$\{camel-version\}}}). The port keeps it unchanged, except the 
differences listed on purpose.
# *Seams in core*, on picocli, no behaviour change: the uses of {{spec}} and 
{{ParseResult}} behind {{CamelCommand}} helpers ({{isOptionGiven}}, the 
original arguments, {{printHelp}}, {{runDefault}}, the configuration dump, the 
placeholders); a test helper instead of {{populateCommand}}/{{parseArgs}} in 
the tests.
# *A plugin SPI without picocli*, on picocli: a new {{Plugin}} method 
registering command classes with names and aliases; {{customize(CommandLine, 
...)}} deprecated but working in 4.24. Tell the forage, kit and Citrus 
maintainers.
# *The mojo reads a list of commands* in code (used by {{CamelJBangMain}} too), 
not the source text. The generated output does not change.
# *The switch*, one PR, mostly scripted: aesh pinned via {{aesh-bom}} and 
{{aesh-processor}}; the exit codes mapped in one place on the base command; 
installing a missing plugin on first use without matching picocli's message 
text; the grouped command list of the help via {{HelpSectionProvider}}; {{camel 
config}} via {{DefaultValueProvider}}; completion via aesh's generator; the 
shell and the TUI shell panel on a command registry of aesh; booleans boxed 
where needed.
# *Cleanup*: remove picocli and {{jline-picocli}}, the old SPI (or its bridge), 
upgrade-guide entry (plugin SPI, regenerate the completion script).

h2. Open decisions

* Release: proposal is steps 1-5 in 4.24 (old SPI deprecated), the switch in 
4.25, so forage, kit and Citrus have a release to move.
* Plugin compatibility: a bridge for the old picocli SPI for one release 
(picocli optional), or a break.
* Citrus: ask to port citrus-jbang to aesh, or keep the test plugin on a 
picocli bridge.
* aesh risks (bus factor, jbang#2504, churn): acceptable with an exact version 
and the golden guard of step 2.

_Plan by Claude Code on behalf of davsclaus (Claus Ibsen)_


  was:
[https://www.jbang.dev/learn/from-picocli-to-sh-how-porting-jbang-s-cli-made-everything-better/]

 


> camel-jbang - Port from picolli to aesh
> ---------------------------------------
>
>                 Key: CAMEL-23810
>                 URL: https://issues.apache.org/jira/browse/CAMEL-23810
>             Project: Camel
>          Issue Type: Improvement
>            Reporter: Claus Ibsen
>            Assignee: Claus Ibsen
>            Priority: Major
>             Fix For: 4.24.0
>
>
> Port the Camel CLI (dsl/camel-jbang) from picocli to aesh, as JBang did: 
> [https://www.jbang.dev/learn/from-picocli-to-sh-how-porting-jbang-s-cli-made-everything-better/]
>  (jbangdev/jbang#2453).
> Starts from the state after CAMEL-25388 (exit codes 0/1/2/3/70/124, 
> CAMEL-25389) and CAMEL-24724 stage 1 and 2 (run and export are the 
> picocli-free camel-jbang-run engine), and keeps the exit code contract.
> h2. What reaches beyond the command layer
> * *The plugin SPI is picocli*: {{Plugin.customize(CommandLine, 
> CamelJBangMain)}} is public, and plugins outside Camel implement it: forage 
> (Kaoto), kit, and the test plugin mounts the picocli commands of Citrus 
> ({{org.citrusframework.jbang.cli}}) with a picocli execution strategy.
> * *The metadata and docs mojo reads the source*: 
> {{PrepareCamelJBangCommandsMojo}} regex-parses the {{addSubcommand}} chains 
> of {{CamelJBangMain}} and the picocli annotations (Roaster). The 175 pages 
> under {{jbang-commands/}} and the JSON that AskTools uses come from it.
> * *{{camel shell}} and the shell panel of the TUI* use jline's 
> {{PicocliCommandRegistry}}.
> h2. Size (main, 2026-10-31)
> 164 {{@Command}}, 861 {{@Option}}, 355 boolean options (160 {{arity="0..1"}}, 
> 89 {{fallbackValue="true"}}), 59 {{@Mixin}}, 5 converters, 17 parameter 
> consumers ({{DebugConsumer}} looks ahead), 42 completion candidate classes, 
> {{scope=INHERIT}} on {{--profile}}, user configuration via 
> {{PicocliPropertiesDefaultProvider}}, {{originalArgs()}} to start the CLI 
> again in another process ({{Run}}, {{Debug}}, {{InfraRun}}), 96 test files 
> using picocli directly.
> h2. aesh (checked 2026-10-31)
> * 3.18.6 ({{org.aesh:aesh}}, {{aesh-processor}}, {{aesh-bom}}), Apache-2.0, 
> Java 8 baseline. Annotation processor (no reflection, one registry per jar), 
> {{@Mixin}}, negatable, {{fallbackValue}}/{{optionalValue}}, {{inherited}}, 
> converters, completers, {{DefaultValueProvider}}, 
> {{CommandResult.valueOf(int)}}, {{MutableCommandRegistry}} for commands added 
> at runtime, AsciiDoc doc and bash/zsh/fish completion generators.
> * No picocli compatibility layer: every annotation is rewritten (JBang: one 
> PR, 134 files).
> * Risks: jbang#2504 (primitive boolean options) still open, JBang worked 
> around it with boxed {{Boolean}}; bus factor about 1; about 40 releases in 
> 2026 with API churn ({{@GroupCommandDefinition}} removed in 3.15); stricter 
> parsing than picocli around attached values ({{-R-Xmx4G}}, {{-D k=v}}). Pin 
> an exact version.
> h2. Plan
> As stage 2 of CAMEL-24724: a guard first, seams while still on picocli, then 
> one switch. Not per command group (two parsers in one command tree).
> # *Measure* the startup of {{camel --help}}, {{camel ps}}, {{camel version}} 
> on the JVM and the share of picocli (part may be the eager creation of 143 
> subcommands and the plugins, which picocli could do lazily too). A decision 
> point: if the gain is small, the reasons are completion, the native launcher 
> and staying aligned with JBang.
> # *A golden guard of the CLI surface*, on picocli: the committed metadata 
> JSON and pages, plus a {{CliParseGoldenTest}} recording command lines per 
> command, the field values after parsing, the exit code and the help (booleans 
> {{0..1}}, {{--profile}}, the lookahead consumers, {{split}}, converters, user 
> configuration, {{$\{camel-version\}}}). The port keeps it unchanged, except 
> the differences listed on purpose.
> # *Seams in core*, on picocli, no behaviour change: the uses of {{spec}} and 
> {{ParseResult}} behind {{CamelCommand}} helpers ({{isOptionGiven}}, the 
> original arguments, {{printHelp}}, {{runDefault}}, the configuration dump, 
> the placeholders); a test helper instead of {{populateCommand}}/{{parseArgs}} 
> in the tests.
> # *A plugin SPI without picocli*, on picocli: a new {{Plugin}} method 
> registering command classes with names and aliases; {{customize(CommandLine, 
> ...)}} deprecated but working in 4.24. Tell the forage, kit and Citrus 
> maintainers.
> # *The mojo reads a list of commands* in code (used by {{CamelJBangMain}} 
> too), not the source text. The generated output does not change.
> # *The switch*, one PR, mostly scripted: aesh pinned via {{aesh-bom}} and 
> {{aesh-processor}}; the exit codes mapped in one place on the base command; 
> installing a missing plugin on first use without matching picocli's message 
> text; the grouped command list of the help via {{HelpSectionProvider}}; 
> {{camel config}} via {{DefaultValueProvider}}; completion via aesh's 
> generator; the shell and the TUI shell panel on a command registry of aesh; 
> booleans boxed where needed.
> # *Cleanup*: remove picocli and {{jline-picocli}}, the old SPI (or its 
> bridge), upgrade-guide entry (plugin SPI, regenerate the completion script).
> h2. Open decisions
> * Release: proposal is steps 1-5 in 4.24 (old SPI deprecated), the switch in 
> 4.25, so forage, kit and Citrus have a release to move.
> * Plugin compatibility: a bridge for the old picocli SPI for one release 
> (picocli optional), or a break.
> * Citrus: ask to port citrus-jbang to aesh, or keep the test plugin on a 
> picocli bridge.
> * aesh risks (bus factor, jbang#2504, churn): acceptable with an exact 
> version and the golden guard of step 2.
> _Plan by Claude Code on behalf of davsclaus (Claus Ibsen)_



--
This message was sent by Atlassian Jira
(v10.3.26#10030026)

Reply via email to