CRAP (Change Risk Anti-Pattern) metric for Go projects.
Combines cyclomatic complexity with test coverage to identify functions and methods that are both complex and under-tested - the riskiest code to change.
Install or run with go run:
go run github.com/unclebob/crap4go/cmd/crap4go@latestFrom a Go module:
crap4go # deletes old coverage, runs go test ./..., analyzescrap4go automatically deletes stale coverage reports, runs:
go test ./... -coverprofile=target/coverage/coverage.outand then analyzes the results.
Source-file analysis runs in parallel and defaults to half the available logical CPUs. Override it when needed:
crap4go --max-workers 4CRAP Report
===========
Function Package CC Cov% CRAP
-------------------------------------------------------------------------------------
Widget.Run widget 12 45.0% 130.2
simple widget 1 100.0% 1.0
Pass module name fragments as arguments to filter:
crap4go internal/combat movement # only files matching those path fragmentscrap4go reads Go coverage profiles from target/coverage/coverage.out.
Coverage is matched to functions by source file and line range. If go test
emits module-qualified source paths, crap4go also matches by path suffix so
normal local paths still resolve.
Files skipped during analysis:
_test.gofilestarget/vendor/.git/
CRAP(fn) = CC² x (1 - coverage)³ + CC
- CC = cyclomatic complexity (decision points + 1)
- coverage = fraction of covered Go coverage statements in the function range
| Score | Risk |
|---|---|
| 1-5 | Low - clean code |
| 5-30 | Moderate - refactor or add tests |
| 30+ | High - complex and under-tested |
Decision points that increase cyclomatic complexity:
ifforrangeswitchandtype switchcase clausesselectcommunication clauses&&||
crap4go includes a SKILL.md for use as a Claude Code skill. Add it to your
project's .claude/settings.json:
{
"skills": [
"https://github.com/unclebob/crap4go/blob/master/SKILL.md"
]
}Then ask Claude Code for a "CRAP report" and it will know how to set up and run the tool.
go test ./... # run tests
go run ./cmd/crap4go # run on own source
go run ./cmd/crap4go internal/coverage # filter to one moduleCopyright (c) Robert C. Martin. All rights reserved.