lizard-complexity
Run Lizard against production source to enforce per-function cyclomatic complexity (CCN), NLOC, and parameter-count thresholds - language-agnostic (30+ languages). Scoped to production code via `-x"./tests/*"`; test complexity is reviewed separately. Use when a codebase spans several languages and needs one complexity gate across all of them, or when a function has grown unreviewable and the team wants a numeric threshold in CI.
Install with skills.sh (any agent)
npx skills add testland/qa --skill lizard-complexitylizard-complexity
Lizard analyzes source code per function for NLOC (non-comment LoC), CCN (cyclomatic complexity), token count, and parameter count across 30+ languages including C/C++, Java, Python, JavaScript, Go, Rust, TypeScript, Swift, Kotlin (per the Lizard README (opens in new window)). Default CCN warning threshold is 15.
When to use
Step 1 - Install
pip install lizardOr run the standalone script:
python lizard.py path/to/codePer the Lizard README (opens in new window), no external deps required.
Step 2 - Baseline scan
lizard src/Default output groups by file with per-function NLOC/CCN/token/param counts. Default warning threshold: CCN ≥ 15.
Step 3 - Set production-only thresholds
lizard src/ \
-x"./tests/*" \
-x"./vendor/*" \
-C 10 \
-L 100 \
-a 5| Flag | Meaning |
|---|---|
-x PATTERN | Exclude (must include tests/** for production-only scope) |
-C N | CCN warning threshold (default 15; tighten to 10 for new codebases) |
-L N | Max function NLOC (default 1000; tighten to 80 - 100) |
-a N | Max parameter count (5 = "if you need more, pass an object") |
Step 4 - CSV/XML for CI
# CSV for grep / jq pipelines
lizard src/ -x"./tests/*" -C 10 --csv > lizard.csv
# XML for CI parsers (cppncss-style)
lizard src/ -x"./tests/*" -C 10 -X > lizard.xml
# HTML for human review
lizard src/ -x"./tests/*" -C 10 -H > lizard.htmlStep 5 - Fail CI on warnings
lizard src/ -x"./tests/*" -C 10 -L 100 -a 5 -w
EXIT=$?
if [ "$EXIT" -ne 0 ]; then
echo "Complexity threshold breached. See report."
exit 1
fi-w prints warnings only (clang/gcc style). Lizard exits non-zero when any function exceeds the configured threshold.
Step 6 - Per-language scope
# Only Python
lizard src/ -l python -C 10
# Only TypeScript + JS
lizard src/ -l typescript -l javascript -C 10Useful when a polyglot repo has language-specific budgets (e.g., Python tolerates higher CCN than C).
Anti-patterns
| Anti-pattern | Why it fails | Fix |
|---|---|---|
| Run on whole repo including tests | Test setup helpers ("create user with 12 fields") look complex; tests get refactored away from clarity | Always exclude tests/, spec/ (Step 3) |
| Set CCN threshold to default (15) | Too lax for new code | Start at 10 for new code; track existing code as baseline |
| Block PRs on absolute count | Legacy code can't add a single line | Diff-only: scan PR-changed functions only with git diff --name-only filter |
| Refactor for CCN at expense of clarity | Splitting a clear linear function into 4 helpers raises overall complexity | Use CCN as a smell signal, not a hard rule |
| Skip parameter-count guard | "God functions" with 12 args slip through | -a 5 enforces object-arg style |
Limitations
References
Related skills
codeclimate-config
Configure Code Climate Quality (now Qlty) for repository-wide quality gates - duplication, complexity, similar-code, exclude_patterns. Covers both legacy `.codeclimate.yml` (Code Climate Velocity / GitHub integration) and the new `.qlty/qlty.toml` per the Qlty platform migration. Use when a repo needs duplication and complexity thresholds enforced on PRs, or when an existing `.codeclimate.yml` must be migrated to Qlty without losing its plugin and exclude settings.
knip-dead-code
Run Knip against a JS/TS project to detect unused files, unused dependencies, unused exports, and unused class/enum members. Scoped to production code; tests are entry-point-aware via Knip's framework plugins. Use after a feature or route is deleted and the project still compiles, or when `package.json` has accumulated dependencies nobody can account for.
madge-deps
Run Madge against a JS/TS production source tree to detect circular dependencies, find orphan modules, and visualize the module graph. Scoped to production code via `excludeRegExp` for test files. Use when a build compiles but throws `Cannot read property X of undefined` on a module that is clearly imported, or when a repo needs a CI gate that blocks new import cycles.
sonarqube-maintainability-gate
Run SonarQube/SonarCloud against production code to surface Code Smells, Bugs, and Maintainability ratings - the maintainability lens rather than the security lens. Production-only scope via sonar.exclusions; test code is reviewed separately. Use when a team wants maintainability and technical-debt ratings gating PRs, or when an existing SonarQube project reports numbers nobody has tied to a quality gate.