Analyzers¶
Codefang ships two families of analyzers that extract quantitative insights from your codebase.
Static analyzers operate on source code via UAST (Universal Abstract Syntax Tree) and evaluate structural properties of the code as it exists right now. History analyzers walk Git commit history and track how the codebase evolves over time.
Static analyzers¶
Static analyzers parse source files into a UAST and compute metrics in a single pass. They require no repository history and can run on individual files or entire directory trees.
| Analyzer | ID | Description |
|---|---|---|
| Complexity | static/complexity | Cyclomatic complexity, cognitive complexity, nesting depth |
| Cohesion | static/cohesion | LCOM over function–variable usage, function cohesion |
| Halstead | static/halstead | Program length, vocabulary, volume, difficulty, effort |
| Comments | static/comments | Documentation coverage, comment placement quality |
| Imports | static/imports | Import and dependency analysis |
| Clones | static/clones | Cross-file duplicate function detection via MinHash + LSH |
| Composition | static/composition | File-type breakdown: source, docs, config, vendor, generated, dotfile, image, binary, other |
Running static analyzers¶
Point codefang run at a file or a directory tree; the UAST is built internally per file:
# Single file, single analyzer
codefang run -a static/complexity main.go
# Entire directory tree, single analyzer
codefang run -a static/complexity ./src/
# Entire directory tree, all static analyzers
codefang run -a 'static/*' ./src/
Every static analyzer reads the same walk of the tree, so -a 'static/*' reports exactly the numbers the single runs report: the walk visits directories in lexical order (skipping .git, cache-tagged directories and symlinked directories), admits the files the UAST parser supports and --languages keeps, applies the vendor / generated / --extra-excluded-prefixes policy to the root-relative path, reads each file once (files over 8 MiB by default, --max-parse-file-size, and unreadable files are skipped with one stderr warning each), and applies the generated-content marker (DO NOT EDIT, Code generated, … in the first 512 bytes) unless --include-generated. static/composition classifies every file instead, vendored and generated included. --per-file adds per-file entries to --format json only. See the CLI reference for the full contract.
History analyzers¶
History analyzers iterate over Git commits (oldest to newest) and accumulate statistics about how files, developers, and code structure change over time. They require a Git repository.
| Analyzer | ID | Description |
|---|---|---|
| Burndown | history/burndown | Code survival over time, line ownership tracking |
| Developers | history/devs | Developer activity, language breakdown, bus factor |
| Couples | history/couples | File coupling, co-change patterns |
| File History | history/file-history | Per-file lifecycle and modification tracking |
| Quality | history/quality | Complexity, Halstead, comment, and cohesion metrics over time |
| Sentiment | history/sentiment | Comment sentiment analysis over time |
| Shotness | history/shotness | Structural hotspots (function-level change tracking) |
| Typos | history/typos | Typo detection dataset builder |
| Anomaly | history/anomaly | Z-score temporal anomaly detection |
Running history analyzers¶
Use codefang run with the -a flag:
# Single analyzer
codefang run -a history/burndown .
# Multiple analyzers
codefang run -a history/devs -a history/couples .
# All history analyzers
codefang run -a 'history/*' .
Glob patterns¶
You can select analyzers using glob patterns with the -a flag:
# All static analyzers
codefang run -a 'static/*' ./src/
# All history analyzers
codefang run -a 'history/*' .
# All analyzers (both static and history)
codefang run -a '*' .
Output formats¶
All analyzers support multiple output formats via the --format flag:
Combining analyzers
When running multiple history analyzers together, they share the same commit walk, making combined runs significantly faster than running each analyzer separately.