diff --git a/browser_cli/cli.py b/browser_cli/cli.py index 3291e9b..2b49fa0 100755 --- a/browser_cli/cli.py +++ b/browser_cli/cli.py @@ -8,6 +8,8 @@ import os import json import stat import shutil +import re +from importlib.metadata import PackageNotFoundError, version as package_version from pathlib import Path from rich.console import Console @@ -53,7 +55,38 @@ def _native_host_script_path() -> Path: return _native_host_wrapper_path().with_name("native_host.py") +def _project_version() -> str: + pyproject_path = Path(__file__).resolve().parent.parent / "pyproject.toml" + try: + content = pyproject_path.read_text(encoding="utf-8") + match = re.search(r'^version\s*=\s*"([^"]+)"', content, re.MULTILINE) + if match: + return match.group(1) + except OSError: + pass + + try: + return package_version("browser-cli") + except PackageNotFoundError: + return "unknown" + + +def _print_version(ctx, param, value): + if not value or ctx.resilient_parsing: + return + click.echo(_project_version()) + ctx.exit() + + @click.group() +@click.option( + "-V", "--version", + is_flag=True, + is_eager=True, + expose_value=False, + callback=_print_version, + help="Show the browser-cli version and exit.", +) @click.option( "--browser", default=None, metavar="ALIAS", help="Browser profile alias to target (required when multiple browsers are active).", diff --git a/tests/test_cli.py b/tests/test_cli.py new file mode 100644 index 0000000..759a6bb --- /dev/null +++ b/tests/test_cli.py @@ -0,0 +1,33 @@ +from pathlib import Path + +from click.testing import CliRunner +from unittest.mock import patch + +from browser_cli.cli import main, _project_version + + +def _expected_version() -> str: + pyproject = Path(__file__).resolve().parent.parent / "pyproject.toml" + for line in pyproject.read_text(encoding="utf-8").splitlines(): + if line.startswith("version = "): + return line.split('"')[1] + raise AssertionError("version not found in pyproject.toml") + + +def test_short_version_option(): + result = CliRunner().invoke(main, ["-V"]) + assert result.exit_code == 0 + assert result.output.strip() == _expected_version() + + +def test_long_version_option(): + result = CliRunner().invoke(main, ["--version"]) + assert result.exit_code == 0 + assert result.output.strip() == _expected_version() + + +def test_project_version_falls_back_to_installed_package_metadata(): + with patch("browser_cli.cli.Path.read_text", side_effect=OSError), patch( + "browser_cli.cli.package_version", return_value="9.9.9" + ): + assert _project_version() == "9.9.9"