Skip to content

WillBooster/code-gauge

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

22 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

code-gauge

Test Test rust semantic-release

A command-line tool for measuring code metrics with tree-sitter. It scans a project and reports high-risk files, functions, and React components so you can spot code that is worth refactoring. A programmatic API is also available.

Getting started

# Run without installing
npx code-gauge path/to/project

# Or install globally
npm install -g code-gauge
code-gauge path/to/project

The CLI scans JavaScript, JSX, TypeScript, TSX, Python, Go, Rust, Java, Ruby, C, and C++ files. By default it skips generated, vendor, test, and tool directories, prints a summary, and lists the highest-risk findings. TypeScript project metrics and React component classification turn on automatically when a tsconfig.json is found.

Options

Option Description
--config <path> Use this config file instead of the auto-detected code-gauge.config.json.
--include-tests Include test files and test directories.
--tsconfig <path> Use this tsconfig.json instead of the auto-detected one.
--max-findings <n> Maximum number of findings to print (default: 20).
--largest-files <n> List the n largest files by code LOC (config key: largestFiles).
--json Print machine-readable JSON.
--fail-on-risk Exit with code 1 when any high-risk finding is reported.
--fail-on-error Exit with code 1 when any file or directory cannot be scanned.
--<metric>-threshold <n> Override a risk threshold (see below).

Risk thresholds

A finding is reported when a measured value is greater than or equal to its threshold. Every threshold can be set on the command line (e.g. --file-loc-threshold 400) or in a config file; the command line wins over the config file, which wins over the defaults.

code-gauge looks for code-gauge.config.json by walking up from the target directory (override with --config). The following config reproduces every built-in default:

{
  "thresholds": {
    "fileLoc": 500,
    "functionLoc": 120,
    "componentLoc": 350,
    "cognitive": 25,
    "cyclomatic": 20,
    "call": 50,
    "import": 25,
    "fanOut": 10,
    "parameter": 8,
    "duplicateBlock": 2,
    "duplicationRatioPercent": 30,
    "transitiveDependency": 25,
    "structuralBreadth": 8,
    "structuralCoordination": 300,
    "stateMutation": 50,
    "duplicateSymbolGroup": 5
  },
  "languageThresholds": {
    "python": { "stateMutation": 90, "structuralCoordination": 350 },
    "ruby": { "stateMutation": 90, "structuralCoordination": 350 },
    "react": { "import": 30 }
  },
  "maxFindings": 20,
  "includeTests": false,
  "failOnRisk": false,
  "failOnError": false
}
Threshold CLI flag Reports when a …
fileLoc --file-loc-threshold file's code LOC is large.
functionLoc --function-loc-threshold function's physical LOC span is large.
componentLoc --component-loc-threshold React component's physical LOC span is large.
cognitive --cognitive-threshold function's cognitive complexity is high.
cyclomatic --cyclomatic-threshold function's cyclomatic complexity is high.
call --call-threshold function makes many calls.
import --import-threshold file has many unique import sources.
fanOut --fan-out-threshold function calls many other in-file functions.
parameter --parameter-threshold function declares many parameters.
duplicateBlock --duplicate-block-threshold file contains copy-pasted code blocks.
duplicationRatioPercent --duplication-ratio-percent-threshold large percentage of a file's code lines is duplicated.
transitiveDependency --transitive-dependency-threshold file transitively reaches many local files.
structuralBreadth --structural-breadth-threshold file coordinates many structural concerns.
structuralCoordination --structural-coordination-threshold file's structural coordination score is high.
stateMutation --state-mutation-threshold file mutates state heavily.
duplicateSymbolGroup --duplicate-symbol-group-threshold file shares many duplicated symbols with others.

Per-language thresholds

Some metrics distribute very differently by language or file type, so a single global threshold either over-flags one language or under-flags another. languageThresholds overrides individual thresholds for a profile without repeating the whole set. Each file resolves its thresholds as base → its language profile → the react profile (the last applies when the file contains a React component), so later profiles win.

Valid profile keys are javascript, jsx, typescript, tsx, python, go, rust, java, ruby, c, cpp, and react. Built-in overrides raise stateMutation and structuralCoordination for Python and Ruby (every binding is an assignment, so these run far higher than in TypeScript) and raise import for React files (which pull in many components). Anything you specify is merged on top of the built-in overrides, so { "python": { "stateMutation": 8 } } restores the global value for Python while keeping the other built-in adjustments.

{
  "languageThresholds": {
    "python": { "stateMutation": 120 },
    "react": { "componentLoc": 400, "import": 35 }
  }
}

Command-line --<metric>-threshold flags set the global base only; use the config file for per-language tuning.

Metrics

  • Physical LOC, code lines, comment-only lines, and blank lines
  • Function and class counts
  • Cyclomatic and cognitive complexity (per function and maximum)
  • Nesting depth
  • Intra-file call graph metrics: call counts, fan-in/fan-out, recursion, call depth, and parameter counts
  • Within-file duplication: copy-pasted blocks and statement runs matched on normalized tokens (identifiers anonymized consistently, literals by kind), plus duplicated line count and ratio (distinct from cross-file duplicate symbol names)
  • File coupling (imports/exports) and cohesion (shared function identifiers)
  • Architecture metrics: transitive local dependencies, structural coordination and breadth, state mutation, and cross-file duplicate symbols
  • TypeScript type-shape metrics: annotations, aliases, interfaces, generics, unions, intersections, assertions, and conditional types
  • Halstead metrics and the maintainability index

Supported languages

Built-in parsers cover JavaScript, JSX, TypeScript, TSX, Python, Go, Rust, Java, Ruby, C, and C++. Additional tree-sitter grammars can be registered with TreeMeasurer.registerLanguage.

Native (Rust) backend

Measurement is also implemented as a Rust addon that produces bit-identical metrics roughly 13x faster than the TypeScript backend (the tree-sitter grammar crates are pinned to the same versions as the npm grammar packages). With a Rust toolchain installed, build it once:

yarn build-native

measureCode and the CLI pick up native/code-gauge.node automatically and fall back to the TypeScript implementation when the addon is missing (for example, on npm installs) or when a custom language has been registered. Set CODE_GAUGE_NATIVE=0 to force the TypeScript backend, and compare both with yarn benchmark (requires yarn build first). isNativeBackendAvailable() reports which backend is in use.

Programmatic API

import { measureCode } from 'code-gauge';

const metrics = measureCode(
  `
function score(value) {
  if (value < 0 || value == null) {
    return 0;
  }
  return value > 10 ? 10 : value;
}
`,
  { language: 'javascript' }
);

console.log(metrics.cyclomaticComplexity);

About

A tool for measuring code metrics using tree-sitter

Resources

License

Stars

1 star

Watchers

0 watching

Forks

Packages

 
 
 

Contributors