Skip to content

umbgtt10/grip4rust

Repository files navigation

cargo-grip4rust

How much can tests grab onto your Rust codebase?

cargo-grip4rust is a static analysis tool that measures testability — how many pure functions, public entry points, and trait seams a codebase exposes for testing. It produces a single grip score (0–100) with a per-module breakdown and a per-function offender list.


The problem

Most engineering orgs measure test coverage — how much code was exercised. But coverage tells you nothing about how hard it was to write those tests. A codebase can have 95% coverage and still be a nightmare to test:

  • Functions that smuggle hidden I/O (time, filesystem, randomness) as ambient dependencies
  • Concrete types everywhere, no trait seams for test doubles
  • Side effects mixed with computation, so you can't test logic without mocking the world
  • Everything private — zero public surface for test entry points

grip measures the root cause, not the symptom.


The formula (Phase 0)

pure_ratio = probably_pure_functions / total_functions

grip = pure_ratio × 100

A function is classified as probably pure when:

  • No &mut parameters
  • Returns a non-() value
  • Contains no unsafe blocks

grip uses a heuristic for purity. It will produce false positives and false negatives. The heuristic is useful directionally: a module scoring 80 has more testability grip than one scoring 20. The limitation is stated explicitly — grip does not claim to detect purity, it estimates it.


Installation

cargo install cargo-grip4rust

Usage

cargo grip4rust [PATH]

Arguments:

Argument Description
[PATH] Path to Rust crate or workspace root (default: .)

Options:

Option Description
--json Emit structured JSON output
--threshold N Exit non-zero if overall grip score < N (CI gate). Alias: --min-score
-h, --help Print help
-V, --version Print version

Output

cargo-grip4rust 0.1.3 -- my-crate
══════════════════════════════════════════════════════

Overall grip score:    71 / 100
Total functions:       20
Probably pure:         12 / 20  (60.0%)

Per module:
  consensus                      grip:  78   pure: 71.4%
  transport                      grip:  83   pure: 78.9%
  timer                          grip:  44   pure: 31.2%  ❌
  state                          grip:  91   pure: 88.3%

Offenders (score < 50):
  timer                          grip:  44  ❌

JSON output (--json) includes the full breakdown, offenders list, and a per-function functions array with each function's name, file path, purity, and visibility — suitable for CI pipelines, dashboards, and editor tooling.


What the score means

Range Meaning
80–100 High grip. Tests can reach most behavior through pure functions.
50–79 Moderate grip. Some modules have impure functions that need refactoring.
20–49 Low grip. Most logic is mixed with side effects or hidden from tests.
0–19 Minimal grip. The codebase resists testing at every level.

Offender list

The functions array in JSON output marks every function with:

  • is_pure — whether it passes the purity heuristic
  • is_public — whether it's visible to test code

Run cargo grip4rust --json | jq '.functions[] | select(.is_pure == false)' to list all impure functions.


Roadmap

grip is being built in phases:

Phase What it adds Version
0 Pure function ratio v0.1.3
1 Trait boundary ratio (seams) v0.2.0
2 Hidden dependency detection v0.3.0
3 Testability Index (grip / braintax) v0.4.0
4 Git history tracking + Quality Index trend v1.0.0

See ROADMAP.md for the full plan.


Limitations

  • Purity is a heuristic. grip classifies functions by signature patterns, not by type inference. It will make mistakes at the margin.
  • No runtime analysis. grip never executes code, runs tests, or instruments builds.
  • No coverage data. grip measures testability, not testing. Use a coverage tool alongside it.

License

MIT — see LICENSE.

About

No description, website, or topics provided.

Resources

License

Code of conduct

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors