davsclaus opened a new pull request, #27909:
URL: https://github.com/apache/camel/pull/27909

   The first step of 
[CAMEL-25388](https://issues.apache.org/jira/browse/CAMEL-25388): the Camel CLI 
gets one documented set of exit codes, errors go to stderr, and one handler 
ends a command that throws. Scripts and AI agents can then tell apart "it 
worked", "you called it wrong", "nothing matches" and "it timed out" without 
parsing text.
   
   ### Exit codes (`CliExitCode`)
   
   | Code | Meaning | Why this number |
   |---|---|---|
   | 0 | Success | |
   | 1 | Failed: the command ran, but the outcome is negative | grep/diff: 1 = 
"no" |
   | 2 | Usage error | picocli, argparse, clap, Go `flag` |
   | 3 | Not found (file, integration, route, component, service) or an 
ambiguous name | LSB `status`: not running |
   | 70 | Internal error, printed with its stack trace | `EX_SOFTWARE` in 
sysexits.h |
   | 124 | Timed out | GNU `timeout` |
   
   Each code is the one most tools already use for that meaning, so an agent or 
a script can read it without our docs. Codes from 126 up are left to the shell 
and signals (130 Ctrl+C, 137 SIGKILL, 143 SIGTERM). `camel --help` lists the 
codes.
   
   Two changes from the Jira text:
   - **Timeout is 124, not 4.** 124 is what models and scripts already read as 
a timeout, and 4 is JBang's own "internal error" code. The semantic commands 
(4.23.0) used 4; the upgrade guide says so.
   - **`CAMEL_CLI_DEBUG=true`, not `CAMEL_DEBUG`**, prints the stack trace of 
every error. `CAMEL_DEBUG` reads like the `camel debug` command or 
`camel.debug.*`.
   
   ### Changes
   - `CliExitCode`, `CliException` and `CliExecutionExceptionHandler` (also 
picocli's exit-code mapper). A `CliException` prints one `ERROR:` line on 
stderr. A missing file (`NoSuchFileException`, `FileNotFoundException`, 
`ResourceDoesNotExist`) is 3. Any other exception, or an `Error` that escapes 
picocli, is 70 with the stack trace. `--verbose` or `CAMEL_CLI_DEBUG=true` 
prints the stack trace of every error.
   - `Printer` gets a diagnostics channel: `printErr`, `printWarn`, `printTip` 
and `printDiagnostic` go to stderr. `StringPrinter` keeps `getOutput()` 
(everything, in order) and adds `getStdout()` and `getStderr()`. Printers of 
in-process callers (TUI, `camel ask`, MCP) still get everything, so they see 
errors as before.
   - `Error:` lines printed on stdout now go to stderr (dataweave, memory-leak, 
sql, LLM client, kubernetes delete, generate rest, test init). `printErr("WARN: 
...")` becomes `printWarn`, tips become `printTip`, and the DataWeave summary 
moves off `printErr`. The legacy settings migration notice, which runs before 
every command, no longer lands in stdout or JSON.
   - Commands that exited with 255 (`return -1`) or ad hoc codes use the 
contract: bind, debug (the debugged integration's exit code when it ends), 
dependency update, eval expression, infra log, transform message, update run, 
generate schema. `cmd sql` returns 124 on timeout. `camel run` returns 0 
instead of relying on `Integer.MIN_VALUE & 0xFF` when stopped from outside.
   - Parent commands print their full help, with sub-commands (`camel catalog`, 
`cmd`, `eval`, `transform`, and the kubernetes/generate/test/validate plugins). 
Commands that run a default sub-command (`config`, `dependency`, `get`, 
`infra`, `plugin`, `top`, `update`, `version`) pass on its exit code instead of 
always returning 0.
   - The first use of a known plugin command (e.g. `camel kubernetes`) installs 
the plugin and runs the command, instead of asking to re-run and exiting 0. 
Without plugin discovery the fallback exits 1. The "Plugins (not installed)" 
banner goes to stderr, and only in an interactive terminal.
   - MCP `camel_version_list` parses stdout only and reports stderr when it 
fails.
   
   ### Docs
   - New page **Camel CLI - Exit Codes and Output** 
(`camel-jbang-exit-codes.adoc`), linked from the nav and the CLI overview.
   - 4.24 upgrade guide entry listing every exit code that changed.
   
   ### Tests
   - `ExitCodeContractTest` runs the CLI through `CamelJBangMain.execute`: 
success, each `CliException` code, verbose stack traces, internal errors 
(exception and `Error`), a missing file, an unknown option or command (2), 
parent help and exit codes, root help, and the plugin fallback.
   - `PrinterTest`: the two channels in `StringPrinter`, the system printer 
(stdout/stderr), `QuietPrinter`, and custom printers of in-process callers.
   - Updated: `TransformDataWeaveTest` (stdout/stderr, 2, 3, the summary off 
stdout), `InfraLogTest`, `BindTest`, `SemanticCommandTest` (124).
   - `mvn test` passes: camel-jbang-core (1916 tests), plugin-validate (16), 
plugin-test (6), plugin-kubernetes (153), camel-jbang-mcp (468), camel-launcher 
(223), plugin-tui (2154); plugin-generate compiles.
   - Run as a real process: `camel transform dataweave` exits 2 with only 
`ERROR:` on stderr; a missing `--input` exits 3; `--expression` prints the 
conversion on stdout and the summary on stderr; `camel catalog` lists its 
sub-commands; an unknown command or option exits 2; `camel infra log` with 
nothing running exits 3; `camel --help` ends with the exit codes.
   
   ### Not in this PR
   The rest of CAMEL-25388 is separate PRs: the connector replying to actions 
(CAMEL-25390), `ActionClient`/`ProcessFinder`/`--timeout` (CAMEL-25391), the 
JSON contract (CAMEL-25392), and per-command fixes such as "no match exits 0" 
(CAMEL-25393 to 25399). PR #27715's parser note under `--json` moves to 
`printWarn` in whichever of the two PRs lands second.
   
   _Claude Code on behalf of davsclaus_
   
   🤖 Generated with [Claude Code](https://claude.com/claude-code)
   
   https://claude.ai/code/session_01DDRLJAyf8cDXSg8iX785My
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to