feat(cli): python -m bmad_loop + entry-point/exit-code smoke tests (#240)#249
Conversation
…semantics (#240) Add src/bmad_loop/__main__.py delegating to cli.main(), mirroring the cli.py __main__ guard, so the package runs as a module alongside the installed `bmad-loop` console script. Add tests/test_entry_point.py: - subprocess smoke tests (`python -m bmad_loop --version`/`--help` and one `validate --json`) that spawn a real interpreter via sys.executable — the deliberate exception to the in-process cli.main() tests, so packaging regressions (startup import cycles, broken script wiring) become visible. - characterization tests pinning today's CLI exit codes: typed errors (BmadConfigError/SprintStatusError/PolicyError/GitError) and the broad backstop -> 1, argparse usage error -> 2. No behavior changes — the tests pin current semantics as the guard rail for the exit-code-taxonomy work (#241) and the cli.py composition extraction (#243).
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (3)
WalkthroughAdds ChangesModule Entry Point
Estimated code review effort: 2 (Simple) | ~10 minutes Sequence Diagram(s)sequenceDiagram
participant PythonInterpreter
participant bmad_loop.__main__
participant bmad_loop.cli.main
PythonInterpreter->>bmad_loop.__main__: execute python -m bmad_loop
bmad_loop.__main__->>bmad_loop.cli.main: invoke main()
bmad_loop.cli.main-->>bmad_loop.__main__: return exit code
bmad_loop.__main__-->>PythonInterpreter: sys.exit(exit code)
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Closes #240 (findings F-7/F-8 of the brownfield CLI/TUI refactor assessment). Session 2 of the refactor program — the first code PR; the exit-code characterization tests here are the guard rail everything later leans on.
What
src/bmad_loop/__main__.py— a thin module entry delegating tocli.main(), mirroring thecli.py__main__guard.python -m bmad_loop …now works alongside the installedbmad-loopconsole script (pyproject.toml[project.scripts]). Both share one dispatch path.Subprocess smoke tests (
tests/test_entry_point.py::test_module_*) — every existing CLI test callscli.main()in-process, so startup import cycles and broken script wiring are invisible to the suite. These three spawn a real interpreter viasys.executable -m bmad_loop:--version→bmad-loop <version>on stdout, rc 0--help→ usage on stdout, rc 0validate --jsonin an empty project → rc 1 (bmad-config gate fails) but stdout is still a whole parseable documentThey are the deliberate exception to the in-process pattern (per the issue's trap note), and are xdist-safe:
sys.executable+ a per-test tempcwd/--project, no shared writable state.Exit-code characterization tests (
test_exit_*) pinning today's rc semantics at thecli.pydispatch tail:BmadConfigError/SprintStatusError/PolicyError/GitError) → 1except Exceptionbackstop → 1SystemExit, raised before the dispatch try)No behavior changes
__main__.pyis additive; the tests pin current semantics as the guard rail for the exit-code-taxonomy work (#241) and thecli.pycomposition extraction (#243). Nothing existing changes behavior.Verification
uv run pytest -q -n auto— green except one pre-existing failure on cleanorigin/main(test_tui_app.py::test_validate_findings_multiline_message_keeps_column_alignment), a TUI column-alignment test unrelated to this diff (this branch changes onlyCHANGELOG.md+ the two new files).trunk check --no-fix— no issues on the modified files.## [Unreleased]line forpython -msupport.Summary by CodeRabbit
New Features
python -m bmad_loop.bmad-loopcommand.Bug Fixes
Tests
Documentation