From 27d3825ee609160c2d3371d961dce697242b78d3 Mon Sep 17 00:00:00 2001 From: Wolfvin Date: Sun, 28 Jun 2026 22:23:21 +0000 Subject: [PATCH] =?UTF-8?q?fix(check):=20accept=20positional=20workspace?= =?UTF-8?q?=20arg=20=E2=80=94=20closes=20#78?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The check command's add_args() did not register a positional workspace argument, but the CI quality-gate workflow calls: python3 scripts/codelens.py check . --severity high --sarif argparse rejected the '.' with 'unrecognized arguments: .', failing CI for every PR. Fix: add parser.add_argument("workspace", nargs="?", default=None) to scripts/commands/check.py, matching the convention of all other CodeLens commands. 3 regression tests added to tests/test_cli.py::TestCheckCommandArgs: - test_check_accepts_positional_workspace - test_check_workspace_optional - test_check_full_cli_invocation_with_positional Verified: - 'codelens check /tmp --severity high --format json' now produces JSON output instead of argparse error - All 3 new tests pass --- scripts/commands/check.py | 2 ++ tests/test_cli.py | 68 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+) mode change 100644 => 100755 scripts/commands/check.py mode change 100644 => 100755 tests/test_cli.py diff --git a/scripts/commands/check.py b/scripts/commands/check.py old mode 100644 new mode 100755 index 49da828..908c330 --- a/scripts/commands/check.py +++ b/scripts/commands/check.py @@ -10,6 +10,8 @@ def add_args(parser): + parser.add_argument("workspace", nargs="?", default=None, + help="Path to workspace root (auto-detected if omitted)") parser.add_argument('--severity', choices=['critical', 'high', 'medium', 'low'], default='high', help='Minimum severity to fail the gate (default: high)') diff --git a/tests/test_cli.py b/tests/test_cli.py old mode 100644 new mode 100755 index 83cce8b..c572507 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -263,3 +263,71 @@ def test_list_backend_only(self): finally: import shutil shutil.rmtree(ws, ignore_errors=True) + + +# ─── check command positional workspace arg (issue #78) ───────────────── + + +class TestCheckCommandArgs: + """Regression guard for issue #78: ``check`` command must accept an + optional positional ``workspace`` argument so the CI quality-gate + workflow command ``codelens check . --severity high --sarif`` works. + + Before the fix, ``check`` only defined optional flags (``--severity``, + ``--max-findings``, etc.) and no positional, so argparse rejected the + ``.`` argument with ``error: unrecognized arguments: .``, failing CI + for every PR. + """ + + def test_check_accepts_positional_workspace(self): + """``check`` add_args must register a positional ``workspace``.""" + import argparse + from commands.check import add_args + + parser = argparse.ArgumentParser() + add_args(parser) + + # With positional + args = parser.parse_args(["/tmp/test", "--severity", "high"]) + assert args.workspace == "/tmp/test" + assert args.severity == "high" + + def test_check_workspace_optional(self): + """``check`` without positional must still parse (workspace=None).""" + import argparse + from commands.check import add_args + + parser = argparse.ArgumentParser() + add_args(parser) + + args = parser.parse_args(["--severity", "high"]) + assert args.workspace is None + assert args.severity == "high" + + def test_check_full_cli_invocation_with_positional(self): + """End-to-end: ``codelens check --severity high`` must not raise.""" + import subprocess + import sys + + ws = _create_sample_workspace() + try: + cmd_scan(ws) # build registry so check has something to read + proc = subprocess.run( + [sys.executable, "scripts/codelens.py", + "check", ws, "--severity", "high", "--format", "json"], + capture_output=True, text=True, timeout=60, + env={**os.environ, "PYTHONPATH": "scripts"}, + ) + # ``check`` exits 1 when gate fails (which it likely will on the + # sample workspace) — that's fine, we only care that argparse + # no longer rejects the positional. + assert "unrecognized arguments" not in proc.stderr, ( + f"argparse still rejects positional workspace: {proc.stderr}" + ) + # Output should be valid JSON (gate result), not a usage error + assert proc.stdout.strip().startswith("{"), ( + f"expected JSON output, got: {proc.stdout[:200]}" + ) + finally: + import shutil + shutil.rmtree(ws, ignore_errors=True)