Skip to content

refactor(cli): split cli.py into one module per command - #725

Merged
ian-flores merged 1 commit into
mainfrom
structure-cli-package
Sep 23, 2026
Merged

ian-flores merged 1 commit into
mainfrom
structure-cli-package

Conversation

@ian-flores

Copy link
Copy Markdown
Collaborator

Turns src/vip/cli.py (2137 lines) into src/vip/cli/ with one module per subcommand actually registered in main(): verify.py (run_verify and its helpers: credential checks, temp-config generation, xdist and marker handling; lines 34-658), report.py (run_report, Quarto render, report-template resolution; lines 666-870), status.py (run_status, _collect_status; lines 873-971), install.py (run_install, run_uninstall; lines 974-1172), scaffold.py (run_scaffold and scaffold-source resolution; lines 1178-1306), cleanup.py (run_cleanup, the Workbench session sweep, cleanup config loading; lines 1309-1546), auth.py (mint_connect_key; lines 138-157), and version.py (run_version, version details). app.py holds the argparse.ArgumentParser construction, _reorder_help_args, and main(), including the single except VipError handler errors-cli-single-handler (#717) added around args.func(args) at cli.py:2129-2133. _resolve_effective_ca_bundle is used by verify, install (run_uninstall) and cleanup, so it moves to a shared _common.py; the report-template helpers (_REPORT_TEMPLATE_FILES, _copy_report_templates, _ensure_report_templates) are used only by run_report today, and run_scaffold's _resolve_scaffold_source reuses only their ExitStack pattern, not the helpers, so they stay in report.py. The vip = "vip.cli:main" console-script entry point is unchanged because vip/cli/__init__.py re-exports main and every run_* function. The CI path filters in five workflows move from src/vip/cli.py to src/vip/cli/**, and the src/vip/cli.py row in AGENTS.md's module table and the comment at pyproject.toml:163 point at the new locations.

__main__.py keeps python -m vip.cli working (four selftests invoke it). The source-checkout fallbacks in _ensure_report_templates and _resolve_scaffold_source gain one .parent because the modules sit one directory deeper; without it they resolve to src/ instead of the repo root and 27 selftests fail. An AST check confirms the other 42 top-level definitions are byte-identical to main's cli.py and these two differ only by that .parent and its comment. Stale cli.py references in comments and docs now point at the new modules: AGENTS.md (module table row, the auth_cache_path() note, the proxy paragraph, the install-flow-smoke path list), copilot-setup-steps.yml, plugin.py, auth/cache.py, auth/flows.py, auth/scheme.py and test_auth_scheme.py (the latter two cited cli.py:391, already stale, now vip.cli._common._resolve_effective_ca_bundle), test_cli_url_scheme.py, and a test_cli_verify.py docstring.

Patch targets retargeted (the only selftest edits): main() binds func=run_verify etc. from its own module's namespace, so patch("vip.cli.run_verify") (test_cli_verify.py:722, :1606), patch("vip.cli.run_cleanup") (test_cli_cleanup.py:462), setattr(vip.cli, "run_version", ...) (3 in test_errors.py), setattr(cli, "run_uninstall", ...) (install/test_cli_uninstall.py:330) and setattr(vip.cli, "_cleanup_workbench_sessions", ...) (4 in test_cli_cleanup.py: :129, :149, :179, :228) move to vip.cli.app/vip.cli.cleanup. patch("vip.cli.subprocess.run") / patch("vip.cli.sys.exit") (3 in test_cli_verify.py) and setattr(cli.subprocess, "run", ...) (8 in test_cli_report.py) patch the shared stdlib modules through an attribute path; they move to vip.cli.verify.subprocess / vip.cli.report.subprocess so they do not depend on the package __init__ happening to import subprocess. 22 sites across 5 files. One non-patch selftest edit: test_auth_cache.py's inline-cache-path invariant read vip.cli.__file__, which is now __init__.py and would pass vacuously, so it reads vip.cli.cleanup (where auth_cache_path() is called) instead.

Module-level state: none (cli.py has no global statements).

#627 exposure: high. #627 adds 334 lines to cli.py (a new vip trace subcommand, run_trace, and --controls handling in run_report) and already has two conflict hunks against main in cli.py, both where #717 replaced print(...); sys.exit(...) with a raised VipError (run_verify's --format validation and run_report's missing-results check); #627 adds new sys.exit sites in the old style there. After this split, every one of those lines has to be re-applied by hand into the new modules.

Verified with uvx ruff@0.15.0 check ., uvx ruff@0.15.0 format --check ., uv run --all-extras mypy src/vip src/vip_tests selftests, uv run pytest selftests/, uv run pytest src/vip_tests/ --collect-only -q, and vip --help plus each subcommand's --help compared byte-for-byte against main.

Live gate

The gate ran as workflow_dispatch runs on this branch (9d9440e) instead of local just test-local-full and the local mock-IdP lanes.

Copilot AI lite review requested due to automatic review settings September 23, 2026 14:26

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

The package omits previously exposed CLI constants, and the verify.py exception contract needs updating.

Get a fresh assessment by requesting another Copilot review.

Review effort: Lite
Findings: 1 High severity

Open (1)
What changed in this PR

Refactors the monolithic CLI into command-specific modules while preserving entry points and behavior.

Changes:

  • Splits CLI commands and shared helpers into src/vip/cli/.
  • Updates tests, documentation, packaging references, and CI path filters.
  • Preserves console-script and python -m vip.cli execution.
File Reviewed changes
src/​vip/​plugin.py Updated CLI path documentation.
src/​vip/​cli/​version.py Extracted version command.
src/​vip/​cli/​verify.py Extracted verify command and helpers. Finding (nit, 1 vote; line 103): the docstring promises SystemExit, but _normalize_categories raises ConfigError; update the exception contract.
src/​vip/​cli/​status.py Extracted status command.
src/​vip/​cli/​scaffold.py Extracted scaffold command and source resolution.
src/​vip/​cli/​report.py Extracted report command and template helpers.
src/​vip/​cli/​install.py Extracted install and uninstall commands.
src/​vip/​cli/​cleanup.py Extracted cleanup operations and session handling.
src/​vip/​cli/​auth.py Extracted connect-key minting.
src/​vip/​cli/​app.py Added parser construction and command dispatch.
src/​vip/​cli/​_common.py Centralized CA-bundle resolution.
src/​vip/​cli/​__main__.py Preserved module execution support.
src/​vip/​cli/​__init__.py Re-exports CLI APIs. Finding (critical, 3 votes; line 21): VALID_CATEGORIES and VALID_FORMATS are no longer re-exported, breaking existing imports; re-export them or document the breaking change.
src/​vip/​cli.py Removed the monolithic CLI implementation.
src/​vip/​auth/​scheme.py Updated CLI helper references.
src/​vip/​auth/​flows.py Updated CLI path references.
src/​vip/​auth/​cache.py Updated cleanup module references.
selftests/​test_errors.py Retargeted dispatch patches.
selftests/​test_cli_verify.py Retargeted verify patches.
selftests/​test_cli_url_scheme.py Updated CLI references.
selftests/​test_cli_report.py Retargeted report patches.
selftests/​test_cli_cleanup.py Retargeted cleanup patches.
selftests/​test_auth_scheme.py Updated helper references.
selftests/​test_auth_cache.py Updated the module-path invariant.
selftests/​install/​test_cli_uninstall.py Retargeted uninstall patches.
pyproject.toml Updated CLI path documentation.
AGENTS.md Documented the new CLI layout.
.github/​workflows/​workbench-smoke.yml Updated CLI path filters.
.github/​workflows/​packagemanager-smoke.yml Updated CLI path filters.
.github/​workflows/​mock-idp-e2e.yml Updated CLI path filters.
.github/​workflows/​install-flow-smoke.yml Updated CLI path filters.
.github/​workflows/​copilot-setup-steps.yml Updated CLI references.
.github/​workflows/​connect-smoke.yml Updated CLI path filters.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/vip/cli/__init__.py
Comment on lines +21 to +29
from vip.cli.verify import (
_OPT_IN_CATEGORIES,
DEFAULT_TEST_TIMEOUT_SECONDS,
_default_marker_expr,
_extra_keep_from_args,
_generate_temp_config,
_normalize_categories,
run_verify,
)
@ian-flores
ian-flores marked this pull request as ready for review September 23, 2026 14:56
@ian-flores
ian-flores merged commit 4b63529 into main Sep 23, 2026
73 checks passed
@ian-flores
ian-flores deleted the structure-cli-package branch September 23, 2026 14:57
@github-actions

Copy link
Copy Markdown
Contributor
PR Preview Action v1.8.1
Preview removed because the pull request was closed.
2026-09-23 14:57 UTC

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants