docs/requirements/cli-exit-codes.md
Shells, CI runners, and parent make rules read Bear's exit code to
decide whether a run succeeded. Bear runs in several modes, and what the
exit code means differs by mode: a mode that runs a build reports the
build's fate, while a mode that only transforms data reports whether Bear
could do that transformation. This requirement collects the whole
exit-code contract in one place, so a caller never has to reconstruct it
from the individual mode requirements.
The governing principle is one line: when Bear runs a build it proxies the build's outcome; when Bear runs standalone it reports whether it could do its own job. Everything below follows from that.
Common to all modes:
0.interception-events-format owns the
event-file usage errors).0. In build-running modes the
signal is first relayed to the build; delivery and process-tree teardown
are governed by cli-signal-forwarding.Build-running modes (bear -- <build>, bear intercept -- <build>):
0 for success is preserved, and any non-zero code is preserved. Codes
in the portable range (0-255 on Unix) are propagated byte-for-byte.output-json-compilation-database).Standalone filter modes (bear semantic, bear parse-sh):
0, even when the output is empty because the input yielded nothing
(semantic: every candidate entry was dropped by validation; parse-sh: the
input named no commands, or none it named was recognized as a compiler).interception-events-format
for the shared skip-and-continue rule.128 + signal_number shell convention is not followed, so a caller
inspecting only Bear's exit code cannot distinguish signal termination
from an ordinary build failure. The build itself still receives the real
signal; see cli-signal-forwarding.bear running under another bear) are
unsupported and their exit-code behaviour is undefined; the exclusion
is owned by cli-signal-forwarding.Given a build that exits successfully:
When the user runs
bear -- true, thenbearexits0; likewisebear intercept -- trueexits0.
Given a build that exits with a non-zero code:
When the user runs
bear -- sh -c "exit 42", thenbearexits42, the build's code byte-for-byte; likewisebear intercept -- sh -c "exit 42"exits42.
Given a build stopped by a signal:
When a termination signal is sent to
bearwhile the build runs, thenbearexits non-zero.
Given a build that compiles successfully but whose database cannot be written (the output path exists as a directory):
When the user runs the build under
bear, thenbearexits non-zero even though the build itself succeeded.
Given a build that exits 0 but where every candidate entry fails output
validation (the validation rules are owned by
output-json-compilation-database):
When the user runs the build under
bear, then the database is written as an empty array andbearexits0-- the build's code, unchanged by the drops.
Given a semantic run over a conforming events file:
When the user runs
bear semantic --input events.json, thenbearexits0.
Given a semantic run over a conforming events file whose every event is
understood but yields an entry that fails output validation (for example,
a compiler event whose recorded working directory is the empty string):
When the user runs
bear semantic --input events.json, then the database is written as an empty array andbearexits0.
Given a semantic run over non-empty input in which every line is
non-conforming:
When the user runs
bear semanticon it, thenbearexits non-zero.
Given a parse-sh run over shell text with at least one line inside the
supported shell subset:
When the user runs
bear parse-shon it, thenbearexits0.
Given a parse-sh run over shell text that parses cleanly but names no
recognized compiler (a lone mv line):
When the user runs
bear parse-shon it, then the database is written empty andbearexits0.
Given a parse-sh run over non-empty input in which every line is an
unsupported construct:
When the user runs
bear parse-shon it, thenbearexits non-zero.
Given a filter run whose named input file does not exist:
When the user runs
bear semantic --input nonexistent.json(orbear parse-shon a missing file), thenbearexits non-zero.
Given a malformed invocation:
When the user runs
bearwith no build command, or with an unknown argument, thenbearexits non-zero and prints usage or the specific error before running anything.
Given a help request:
When the user runs
bear --help(or a subcommand's--help), thenbearexits0and prints usage.