Skip to content

go-crap-tracker

go-crap-tracker is a distributed, asynchronous scan tracker for go-crap. It schedules repository scans over NATS JetStream, runs go test coverage + go-crap scan in worker processes, stores the results in Postgres, and streams live status updates to an embedded web UI over SSE.

Point it at a repository URL, and it will clone the repo, run the test suite to produce a coverage profile, and compute CRAP scores for every function — all without re-cloning on repeat scans.

What It Does

  • Schedules scans — submit a repo URL (plus an optional branch/tag/commit) via the CLI, the REST API, or the web UI.
  • Distributes work — jobs are published to NATS JetStream and consumed by any available worker in a queue group.
  • Reuses work — a shared, Postgres-locked repository cache means repeat scans of the same commit skip both the clone and the go test run.
  • Stores history — every analysis is persisted in Postgres with a deterministic ID, so you can track CRAP scores over time.
  • Streams live updates — the web UI and any SSE subscriber watch task state change in real time.

Architecture

┌─────────────────┐     ┌─────────────────────┐     ┌──────────────────┐
│     serve       │────▶│  NATS JetStream     │────▶│     worker(s)    │
│  (control plane)│◀────│  (jobs + events)    │◀────│  (scan engine)   │
│  API / UI / SSE │     └─────────────────────┘     └──────────────────┘
│  reconciler     │                                       │
│  migrations     │                                       │
└─────────────────┘                                       │
        │                                                 │
        ▼                                                 ▼
┌──────────────────────────────────────────────────────────────────┐
│                        Postgres                                  │
│  scan_tasks │ repo_analyses │ repo_configs │ repo_locks │ repos  │
└──────────────────────────────────────────────────────────────────┘
Component Role
serve HTTP API, web UI, SSE, reconciler, auto-migrations
worker NATS consumer; clones repos into a shared cache, runs go test + go-crap scan, saves results
NATS streams crap_jobs_scan (jobs), crap_events (status updates)
Postgres Durable task store + analysis results with deterministic IDs

Key Concepts

Task Lifecycle

A scan task moves through a small state machine. Workers claim a queued task, run the analysis, and mark it terminal. Failed tasks retry up to three times, and a reconciler expires tasks stuck in running.

Task Lifecycle

Repo Cache

Workers share one cache directory (typically a mounted PVC). Clones and coverage profiles survive pod restarts and are reused across workers. Per-repo locks live in Postgres so any worker on any pod can take them.

Repo Cache

Per-Repo Overrides

Pin a branch, customise go test args, or tune go-crap flags per repository, stored in Postgres and applied to every scan of that repo.

Repo Command

Quick Start

# Build
make build

# Control plane (HTTP API, UI, SSE, reconciler, migrations)
./go-crap-tracker serve

# A worker in another terminal
./go-crap-tracker worker

Schedule a scan:

curl -X POST http://localhost:8080/api/tasks \
  -H 'Content-Type: application/json' \
  -d '{"repo_url":"https://github.com/golang/example","ref":"HEAD"}'

Then open the web UI at http://localhost:8080/ and watch the task move through its lifecycle.

Get Started →

Components at a Glance

Command Description
serve Start the control plane: HTTP API, UI, SSE, reconciler, migrations
worker Start a scan worker (NATS consumer)
publish Generate the Hugo report index and per-repo detail pages
repo Manage the shared repository cache and per-repo config
version Show version (--simple for scripting)

Commands Reference

Requirements

  • Go 1.21+
  • Postgres 16+
  • NATS with JetStream enabled
  • The go-crap binary on PATH
  • A public Git repository URL to scan

Installation