code complexity & repetition analysis tool
1# Example Usage
2
3This page demonstrates common Mccabre workflows with real examples.
4
5## Example Files
6
7The `examples/` directory contains sample files demonstrating different issues:
8
9- **complex.js** - High cyclomatic complexity
10- **long.py** - Many lines of code with comments
11- **not_dry.go** - Duplicated code (clones)
12
13## Analyzing the Examples
14
15### Full Analysis
16
17```bash
18mccabre analyze examples/
19```
20
21**Output:**
22
23```text
24================================================================================
25MCCABRE CODE ANALYSIS REPORT
26================================================================================
27
28SUMMARY
29--------------------------------------------------------------------------------
30Total files analyzed: 3
31Total physical LOC: 215
32Total logical LOC: 165
33Average complexity: 10.33
34Maximum complexity: 18
35High complexity files: 1
36Clone groups detected: 2
37
38FILE METRICS
39--------------------------------------------------------------------------------
40FILE: examples/complex.js
41 Cyclomatic Complexity: 18 (moderate)
42 Physical LOC: 49
43 Logical LOC: 42
44 Comment lines: 2
45 Blank lines: 5
46
47FILE: examples/long.py
48 Cyclomatic Complexity: 8 (low)
49 Physical LOC: 95
50 Logical LOC: 62
51 Comment lines: 18
52 Blank lines: 15
53
54FILE: examples/not_dry.go
55 Cyclomatic Complexity: 6 (low)
56 Physical LOC: 71
57 Logical LOC: 61
58 Comment lines: 5
59 Blank lines: 5
60
61DETECTED CLONES
62--------------------------------------------------------------------------------
63Clone Group #1 (length: 30 tokens, 3 occurrences)
64 - examples/not_dry.go:12-26
65 - examples/not_dry.go:30-44
66 - examples/not_dry.go:48-62
67```
68
69### Complexity Only
70
71```bash
72mccabre complexity examples/complex.js
73```
74
75Shows that `complex.js` has high cyclomatic complexity due to many conditional branches.
76
77### Clone Detection Only
78
79```bash
80mccabre clones examples/not_dry.go
81```
82
83Identifies the three nearly-identical functions in `not_dry.go`.
84
85## Real-World Scenarios
86
87### Scenario 1: Pre-Commit Check
88
89Ensure code quality before committing:
90
91```bash
92#!/bin/sh
93# .git/hooks/pre-commit
94
95echo "Checking code complexity..."
96
97# Get list of staged Rust files
98FILES=$(git diff --cached --name-only --diff-filter=ACM | grep '\.rs$')
99
100if [ -n "$FILES" ]; then
101 mccabre complexity $FILES --threshold 15
102 if [ $? -ne 0 ]; then
103 echo "❌ Complexity check failed!"
104 exit 1
105 fi
106fi
107
108echo "✅ Complexity check passed!"
109```
110
111### Scenario 2: Finding Refactoring Targets
112
113Combine complexity and clone detection:
114
115```bash
116# Find high-complexity files
117echo "=== High Complexity Files ==="
118mccabre complexity src/ --json | \
119 jq -r '.files[] | select(.cyclomatic.file_complexity > 15) | .path'
120
121# Find duplicated code
122echo "\n=== Code Clones ==="
123mccabre clones src/ --min-tokens 25
124```
125
126Then refactor the flagged files.
127
128### Scenario 3: Tracking Technical Debt
129
130Weekly complexity tracking:
131
132```bash
133#!/bin/bash
134# weekly-report.sh
135
136DATE=$(date +%Y-%m-%d)
137REPORT_DIR="reports"
138
139mkdir -p "$REPORT_DIR"
140
141# Generate report
142mccabre analyze src/ --json > "$REPORT_DIR/report-$DATE.json"
143
144# Extract key metrics
145echo "Complexity Report - $DATE"
146jq '.summary' "$REPORT_DIR/report-$DATE.json"
147
148# Compare with last week
149LAST_WEEK=$(ls -t $REPORT_DIR/report-*.json | sed -n 2p)
150if [ -n "$LAST_WEEK" ]; then
151 echo "\nChange from last week:"
152 jq -s '.[1].summary.avg_complexity - .[0].summary.avg_complexity' \
153 "$LAST_WEEK" "$REPORT_DIR/report-$DATE.json"
154fi
155```
156
157### Scenario 5: Code Review Automation
158
159Automatically comment on PRs with complexity issues:
160
161```bash
162#!/bin/bash
163# pr-comment.sh
164
165# Run analysis
166mccabre analyze src/ --json > complexity.json
167
168# Extract high complexity files
169HIGH_COMPLEXITY=$(jq -r '.files[] | select(.cyclomatic.file_complexity > 15) |
170 "- `\(.path)`: Complexity \(.cyclomatic.file_complexity)"' complexity.json)
171
172if [ -n "$HIGH_COMPLEXITY" ]; then
173 # Post comment to GitHub PR (requires gh CLI)
174 gh pr comment --body "## ⚠️ Complexity Warning
175
176Files with high complexity:
177$HIGH_COMPLEXITY
178
179Consider refactoring before merging."
180fi
181```
182
183### Scenario 5: Compare Branches
184
185Compare complexity between branches:
186
187```bash
188#!/bin/bash
189# compare-branches.sh
190
191MAIN_BRANCH="main"
192FEATURE_BRANCH=$(git branch --show-current)
193
194# Analyze main
195git checkout "$MAIN_BRANCH"
196mccabre analyze src/ --json > /tmp/main-complexity.json
197
198# Analyze feature
199git checkout "$FEATURE_BRANCH"
200mccabre analyze src/ --json > /tmp/feature-complexity.json
201
202# Compare
203echo "=== Complexity Comparison ==="
204echo "Main branch avg: $(jq '.summary.avg_complexity' /tmp/main-complexity.json)"
205echo "Feature branch avg: $(jq '.summary.avg_complexity' /tmp/feature-complexity.json)"
206
207# Check if complexity increased
208MAIN_AVG=$(jq '.summary.avg_complexity' /tmp/main-complexity.json)
209FEATURE_AVG=$(jq '.summary.avg_complexity' /tmp/feature-complexity.json)
210
211if (( $(echo "$FEATURE_AVG > $MAIN_AVG * 1.1" | bc -l) )); then
212 echo "❌ Complexity increased by more than 10%!"
213 exit 1
214else
215 echo "✅ Complexity is acceptable"
216fi
217```
218
219## Filtering and Processing
220
221### Find Files Above Threshold
222
223```bash
224# JSON output piped to jq
225mccabre complexity src/ --json | \
226 jq '.files[] | select(.cyclomatic.file_complexity > 10) | .path'
227```
228
229### Count Clone Groups
230
231```bash
232mccabre clones src/ --json | jq '.clones | length'
233```
234
235### Generate HTML
236
237```bash
238# Create HTML from JSON
239mccabre analyze src/ --json | \
240 jq -r '.files[] | "<tr><td>\(.path)</td><td>\(.cyclomatic.file_complexity)</td></tr>"' | \
241 (echo "<html><table>" && cat && echo "</table></html>") > report.html
242```
243
244### Summary Statistics
245
246```bash
247# Extract just the summary
248mccabre analyze src/ --json | jq '.summary'
249```
250
251### Generate and Save Configuration
252
253Create a config file for your project:
254
255```bash
256# Save default config to current directory
257mccabre dump-config -o mccabre.toml
258
259# Generate config for a specific project structure
260cd my-project/
261mccabre dump-config -o .
262
263# Copy config from one project to another
264mccabre dump-config -c ../project-a/mccabre.toml -o ./mccabre.toml
265```
266
267## Tips and Tricks
268
269### Syntax Highlighting
270
271By default, code blocks in `analyze` and `clones` output are syntax highlighted. To disable:
272
273```bash
274# Disable syntax highlighting for cleaner output
275mccabre analyze src/ --no-highlight
276
277# Useful for piping to files or when colors aren't supported
278mccabre clones src/ --no-highlight > report.txt
279```
280
281### Incremental Analysis
282
283Analyze only changed files:
284
285```bash
286# Files changed in last commit
287git diff --name-only HEAD~1 | grep '\.rs$' | xargs mccabre complexity
288```
289
290### Watch Mode
291
292Continuously monitor (requires `watch` or `entr`):
293
294```bash
295# Using entr
296ls src/**/*.rs | entr mccabre complexity src/
297```
298
299### Focus on New Code
300
301Analyze only files in your feature branch:
302
303```bash
304git diff --name-only main...HEAD | grep '\.rs$' | xargs mccabre analyze
305```
306
307## Next Steps
308
309- Read about [Cyclomatic Complexity](./cyclomatic-complexity.md)
310- Learn about [Clone Detection](./clone-detection.md)
311- Configure [thresholds](./configuration.md)
312- Check the [CLI Reference](./cli-reference.md)