diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ffb15e3..e47f630 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -16,10 +16,10 @@ jobs: matrix: python-version: ["3.11", "3.12"] steps: - - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: persist-credentials: false - - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5 + - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 with: python-version: ${{ matrix.python-version }} - name: Show SQLite version (FTS5 trigram needs >= 3.34) @@ -41,10 +41,10 @@ jobs: matrix: os: [ubuntu-latest, windows-latest] steps: - - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: persist-credentials: false - - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5 + - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 with: python-version: "3.12" - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 @@ -57,10 +57,10 @@ jobs: name: Windows public pull, resolution, and fill safety runs-on: windows-latest steps: - - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: persist-credentials: false - - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5 + - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 with: python-version: "3.12" - name: Install package and public entry points diff --git a/provenance/status.py b/provenance/status.py index 56e1031..0b4ffed 100644 --- a/provenance/status.py +++ b/provenance/status.py @@ -8,16 +8,21 @@ Usage: prov-status (runs under $PROVENANCE_HOME, default current dir) """ +import argparse import csv import json -import sys from collections import Counter -from provenance import common as C +from provenance import __version__, common as C -def main(): - C.cli_help(__doc__) +def main(argv=None): + parser = argparse.ArgumentParser( + description=__doc__, + formatter_class=argparse.RawDescriptionHelpFormatter, + ) + parser.add_argument("--version", action="version", version=__version__) + parser.parse_args(argv) root = C.data_root() inbox = root / "inbox" print(f"Provenance status — data root: {root}") diff --git a/tests/test_status_cli.py b/tests/test_status_cli.py new file mode 100644 index 0000000..185f0b7 --- /dev/null +++ b/tests/test_status_cli.py @@ -0,0 +1,48 @@ +#!/usr/bin/env python3 +"""CLI contract tests for prov-status.""" +import contextlib +import io +import sys +import unittest +from pathlib import Path +from unittest import mock + +ROOT = Path(__file__).resolve().parent.parent +sys.path.insert(0, str(ROOT)) + +from provenance import status + + +class TestStatusCLI(unittest.TestCase): + def test_version_is_exact_and_does_not_resolve_data_root(self): + stdout = io.StringIO() + stderr = io.StringIO() + + with mock.patch.object(status.C, "data_root") as data_root: + with contextlib.redirect_stdout(stdout), contextlib.redirect_stderr(stderr): + with self.assertRaises(SystemExit) as raised: + status.main(["--version"]) + + self.assertEqual(raised.exception.code, 0) + self.assertEqual(stdout.getvalue(), "0.17.0\n") + self.assertEqual(stderr.getvalue(), "") + data_root.assert_not_called() + + def test_unknown_argument_is_a_usage_error(self): + stdout = io.StringIO() + stderr = io.StringIO() + + with mock.patch.object(status.C, "data_root") as data_root: + with contextlib.redirect_stdout(stdout), contextlib.redirect_stderr(stderr): + with self.assertRaises(SystemExit) as raised: + status.main(["--unknown"]) + + self.assertEqual(raised.exception.code, 2) + self.assertEqual(stdout.getvalue(), "") + self.assertIn("usage:", stderr.getvalue()) + self.assertIn("unrecognized arguments: --unknown", stderr.getvalue()) + data_root.assert_not_called() + + +if __name__ == "__main__": + unittest.main()