diff --git a/src/orchestrator/cli.py b/src/orchestrator/cli.py index 4659e13..c5eee91 100644 --- a/src/orchestrator/cli.py +++ b/src/orchestrator/cli.py @@ -60,6 +60,10 @@ def setup_logging(verbose: bool = False): @click.group() +# `package_name` reads the version from installed distribution metadata, so +# this does not import the package -- the CLI stays hermetic and no +# credential-touching import runs just to answer `--version`. +@click.version_option(package_name="py-orc", prog_name="orchestrator") @click.option("--log-level", type=click.Choice(["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"], case_sensitive=False), diff --git a/tests/test_cli_hermetic_and_quiet.py b/tests/test_cli_hermetic_and_quiet.py index e1387a3..af1e063 100644 --- a/tests/test_cli_hermetic_and_quiet.py +++ b/tests/test_cli_hermetic_and_quiet.py @@ -73,6 +73,42 @@ def _run_cli(args, cwd, home): ) +# --------------------------------------------------------------------------- +# 0. the CLI can state its own version +# --------------------------------------------------------------------------- + +def test_cli_reports_its_version(tmp_path): + """`--version` is the first thing anyone runs against a release. + + A release rehearsal against the built wheel found this missing entirely: + `orchestrator --version` failed with "No such option". There is no other + way to ask an installed copy what it is. + """ + import orchestrator + + result = _run_cli(["--version"], tmp_path, _decoy_home(tmp_path)) + + assert result.returncode == 0, f"--version failed: {result.stderr}" + assert orchestrator.__version__ in result.stdout, ( + f"version {orchestrator.__version__!r} missing from {result.stdout!r}" + ) + + +def test_version_does_not_read_credentials(tmp_path): + """Asking the version must not touch the user's provider credentials. + + The version is read from distribution metadata rather than by importing + the package, so nothing on the credential path runs. + """ + home = _decoy_home(tmp_path) + result = _run_cli(["--version"], tmp_path, home) + + assert result.returncode == 0 + combined = result.stdout + result.stderr + assert DECOY_ANTHROPIC not in combined + assert DECOY_OPENAI not in combined + + # --------------------------------------------------------------------------- # 1. hermetic boundary # ---------------------------------------------------------------------------