[
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)