From f871e2860308f8c6ba454b2a46533ac7013d3546 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabi=C3=A1n=20Silva=20Ortiz?= Date: Wed, 25 Feb 2026 22:01:58 -0300 Subject: [PATCH 1/2] feat: add --version / -V flag to CLI Add standard --version flag as a typer callback so users can run `specify --version` or `specify -V` to get the CLI version. The existing `specify version` subcommand (which shows detailed system info) remains unchanged. Closes #486 Co-Authored-By: Claude Opus 4.6 --- src/specify_cli/__init__.py | 20 +++++++++++++++++- tests/test_ai_skills.py | 42 +++++++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+), 1 deletion(-) diff --git a/src/specify_cli/__init__.py b/src/specify_cli/__init__.py index 5651ac722..a2c413ccc 100644 --- a/src/specify_cli/__init__.py +++ b/src/specify_cli/__init__.py @@ -487,8 +487,26 @@ def show_banner(): console.print(Align.center(Text(TAGLINE, style="italic bright_yellow"))) console.print() +def _version_callback(value: bool): + """Print CLI version and exit.""" + if value: + import importlib.metadata + + try: + ver = importlib.metadata.version("specify-cli") + except Exception: + ver = "unknown" + print(f"specify {ver}") + raise typer.Exit() + + @app.callback() -def callback(ctx: typer.Context): +def callback( + ctx: typer.Context, + version: Optional[bool] = typer.Option( + None, "--version", "-V", help="Show version and exit.", callback=_version_callback, is_eager=True + ), +): """Show banner when no subcommand is provided.""" if ctx.invoked_subcommand is None and "--help" not in sys.argv and "-h" not in sys.argv: show_banner() diff --git a/tests/test_ai_skills.py b/tests/test_ai_skills.py index 3eec4a419..1c8f0f8cf 100644 --- a/tests/test_ai_skills.py +++ b/tests/test_ai_skills.py @@ -632,6 +632,48 @@ def test_ai_skills_flag_appears_in_help(self): assert "agent skills" in plain.lower() +class TestVersionFlag: + """Test --version flag (GitHub issue #486).""" + + def test_version_flag_exits_zero(self): + """--version should exit with code 0.""" + from typer.testing import CliRunner + + runner = CliRunner() + result = runner.invoke(app, ["--version"]) + + assert result.exit_code == 0 + + def test_version_flag_prints_version(self): + """--version should print 'specify '.""" + from typer.testing import CliRunner + + runner = CliRunner() + result = runner.invoke(app, ["--version"]) + + assert result.output.strip().startswith("specify ") + + def test_short_version_flag(self): + """-V should behave the same as --version.""" + from typer.testing import CliRunner + + runner = CliRunner() + result = runner.invoke(app, ["-V"]) + + assert result.exit_code == 0 + assert result.output.strip().startswith("specify ") + + def test_version_flag_appears_in_help(self): + """--version should appear in the help output.""" + from typer.testing import CliRunner + + runner = CliRunner() + result = runner.invoke(app, ["--help"]) + + plain = re.sub(r'\x1b\[[0-9;]*m', '', result.output) + assert "--version" in plain + + class TestParameterOrderingIssue: """Test fix for GitHub issue #1641: parameter ordering issues.""" From 89e33f181e1a15bca43d7d514183676c8a8274cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabi=C3=A1n=20Silva=20Ortiz?= Date: Thu, 26 Feb 2026 14:18:44 -0300 Subject: [PATCH 2/2] refactor: reuse get_speckit_version() and assert -V in help test Address Copilot review suggestions: - Use get_speckit_version() instead of duplicating importlib.metadata logic, which provides a better fallback via pyproject.toml for source-based runs - Assert both --version and -V appear in help output Co-Authored-By: Claude Opus 4.6 --- src/specify_cli/__init__.py | 7 +------ tests/test_ai_skills.py | 3 ++- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/src/specify_cli/__init__.py b/src/specify_cli/__init__.py index a2c413ccc..d9bfe0627 100644 --- a/src/specify_cli/__init__.py +++ b/src/specify_cli/__init__.py @@ -490,12 +490,7 @@ def show_banner(): def _version_callback(value: bool): """Print CLI version and exit.""" if value: - import importlib.metadata - - try: - ver = importlib.metadata.version("specify-cli") - except Exception: - ver = "unknown" + ver = get_speckit_version() print(f"specify {ver}") raise typer.Exit() diff --git a/tests/test_ai_skills.py b/tests/test_ai_skills.py index 1c8f0f8cf..26a3cbf0c 100644 --- a/tests/test_ai_skills.py +++ b/tests/test_ai_skills.py @@ -664,7 +664,7 @@ def test_short_version_flag(self): assert result.output.strip().startswith("specify ") def test_version_flag_appears_in_help(self): - """--version should appear in the help output.""" + """--version and -V should appear in the help output.""" from typer.testing import CliRunner runner = CliRunner() @@ -672,6 +672,7 @@ def test_version_flag_appears_in_help(self): plain = re.sub(r'\x1b\[[0-9;]*m', '', result.output) assert "--version" in plain + assert "-V" in plain class TestParameterOrderingIssue: