Imported from ragnarok22/django-doctor (
AGENTS.md). Install upstream withnpx skills add ragnarok22/django-doctor. Copyright stays with the author.
Agent Notes
Commands
- Use
uvfor all project commands:uv sync,uv run ...,uv build. - Before finishing code changes, run tests, formatter, and lint:
uv run pytest && uv run ruff format . && uv run ruff check .. - Coverage command:
uv run pytest --cov. - Focused test example:
uv run pytest tests/test_cli.py::test_json_returns_valid_json. - CLI smoke checks:
uv run django-doctor . --verbose,uv run django-doctor . --json,uv run django-doctor . --score. uv run django-doctoronly works becausepyproject.tomlhas[tool.uv] package = trueand Hatchling build metadata; keep those if editing packaging.
Architecture
- Console entrypoint is
django_doctor.cli:main; public API entrypoint isdjango_doctor.api:diagnose. django_doctor/cli.pyshould only parse options, validate conflicts, render reports, and translate exceptions to exit codes; scanner/rule logic belongs undercore/orrules/.django_doctor.core.scanner.run_scanselects files, buildsScanContext, runs registered rules, sorts diagnostics, scores, and returnsDoctorResult.- Add new rules by implementing
Rule.check(context)underdjango_doctor/rules/...and registering the class indjango_doctor/rules/registry.py. - Result shapes live in
django_doctor/core/diagnostics.py; JSON output should come from Pydantic serialization, not hand-built dicts in the CLI.
CLI Gotchas
- The scan command is a single Typer command, not a normal subcommand group; tests invoke it with
CliRunner(app, [...]). django-doctor installis manually dispatched inmain()before Typer runs, so test it throughinstall_command()or the installed script, notCliRunner(app, ["install"]).--diffsupports an optional base by preprocessing argv in_preprocess_args; directCliRunner(app, ["--diff"])bypasses that wrapper.- JSON and score output must use raw
sys.stdout.write; Rich can wrap long JSON strings and make stdout invalid JSON. - With
--json --annotations, annotations must go to stderr so stdout remains parseable JSON.
Behavior To Preserve
- Exit codes are fixed in
django_doctor/core/exit_codes.py:0success,1fail-on threshold,2usage/config/git error,3runtime error. --json,--json-compact, and--scoreare mutually exclusive;--diff,--staged, and--fullconflict as documented.- Scoring penalizes unique triggered rule IDs, not total diagnostic occurrences.
- Diff/staged scans use subprocess git helpers in
django_doctor/core/git.pyand filter throughcore/files.pyto ignore deleted, binary, symlinked, excluded, and irrelevant files. - Diagnostics should use paths relative to the scanned root and deterministic sorting via
diagnostic_sort_key.
Docs
- Update
README.mdwhen changing CLI flags, output shape, exit codes, config keys, or implemented rules. - Keep the generated install content in
django_doctor/cli.py(_agents_md,_usage_md,_rules_md) aligned with implemented rules and recommended commands.