crap4code is a Python-hosted CRAP analyzer for Python, JavaScript/TypeScript, and Rust.
It is designed for both humans and coding agents that need a verifiable way to:
- measure cyclomatic complexity
- map coverage onto real function ranges
- compute CRAP scores where coverage is trustworthy
- rank risky functions
- get deterministic recommendations about where to add tests or simplify code
The operator model intentionally leans toward unclebob/crap4clj and unclebob/crap4java:
- keep the CLI simple
- make coverage refresh explicit and auditable
- treat missing coverage as indeterminate, not as fake precision
- use threshold-based exits for CI and agent loops
python -m pip install -e .[dev]The same command works on Windows (cmd / pwsh), macOS, and Linux. After installation you get a crap4code console script. You can also invoke portably with:
# Windows PowerShell or cmd
python -m crap4code.main init
python -m crap4code.main scan --report-only# POSIX shells
python -m crap4code.main init
python -m crap4code.main scan --report-onlyWrite a sample config (safe: refuses to overwrite unless you pass --force):
# Windows
crap4code init
# or
crap4code init --force --config .crap4code.toml# POSIX
crap4code initScan with table output (human readable, sorted by risk):
crap4code scan
crap4code scan --lang python
crap4code scan --lang typescript --changed --base-ref origin/main
crap4code scan --changed --report-only --baseline baseline.json # progress on just the functions from a prior full scanScan with machine-readable JSON (for agents / CI):
crap4code scan --format json
crap4code scan --format html > report.html # beautiful shareable browser reportRead an existing report without re-running any coverage commands (very useful on Windows while tuning):
crap4code scan --report-onlyTargeted remediation after adding tests (regenerate coverage externally, then print one function):
cargo llvm-cov -p my-crate --test my_test --lcov --output-path /tmp/cov.lcov
crap4code scan src/my_module.rs \
--lang rust \
--report-only \
--coverage-report /tmp/cov.lcov \
--coverage-format lcov \
--function my_risky_fn \
--format compactSee docs/user-guide/usage.md for the full targeted-workflow guide and docs/user-guide/README.md for organized walkthroughs.
crap4code looks for a repo-local .crap4code.toml by default (next to your source tree). This is the single source of truth for paths, coverage commands, and report locations. Repo-local config makes behavior easy for humans and coding agents to audit in CI or agent loops.
Each language section can define:
pathscoverage_commandcoverage_reportcoverage_formatstale_artifacts
Coverage strategy (deterministic, no invention of data):
- if
coverage_commandis configured and--report-onlyis not used, the tool deletes stale artifacts, runs the command (via platform shell), then ingests the report - if no command runs but a report exists, the tool ingests the report
- if no trustworthy report exists, coverage is reported as
indeterminateand CRAP staysN/A(core guarantee)
Run crap4code init (or crap4code init --force) to get a heavily-commented sample .crap4code.toml. The generated file contains the authoritative explanation of the shell execution model for coverage_command strings, cross-platform guidance, and examples. Read the comments in the generated file — they are the primary durable documentation for this area.
- For detailed, organized explanations of core concepts (CRAP metric, coverage reports & formats, what 'paths' means, 'no matching source files', warnings, indeterminate coverage, etc.), usage workflows (including after a break), and troubleshooting, see
docs/user-guide/(start withdocs/user-guide/README.mdas the guide index — it has a hierarchical table of contents with back-links — then concepts.md and configuration.md).
See also the "Windows and Cross-Platform Notes" section below for PATH, shell, and case-sensitivity realities.
Table output includes: