Skip to content

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:

codefang run -a history/devs --format json .
codefang run -a history/devs --format yaml .
codefang run -a history/burndown --format plot .
codefang run -a history/burndown --format binary .

Combining analyzers

When running multiple history analyzers together, they share the same commit walk, making combined runs significantly faster than running each analyzer separately.