Skip to content

specmatic/priospot

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

63 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

PrioSpot

Maven Central Docker Hub Docker Pulls Gradle Plugin Portal GitHub Release License

PrioSpot (Prioritize Hotspots) is a language-agnostic hotspot engine that computes C3 (churn + complexity + coverage) and generates interactive SVG treemap reports to help you visualize and prioritize hotspots in your code.

Why This Matters

Most teams don't prioritize Tech-debt. If at all they do, they prioritize work by intuition, noisy bug reports, or whoever shouts loudest. That misses hidden risk.

PrioSpot helps you answer:

  • Which files are most likely to hurt us next?
  • Where should we spend refactoring/testing effort first?
  • Which hotspots are risky because of low coverage, high complexity, and frequent churn together?

Why this is useful:

  • Focuses engineering effort on high-risk code paths instead of broad, low-impact cleanup
  • Makes refactoring prioritization objective and repeatable
  • Gives a shared visual language for product, QA, and engineering discussions
  • Works across large multi-module repositories with one consolidated view

PrioSpot Treemap Example

Requirements

  • JDK 17+
  • Gradle 8.10+ (or use wrapper)

Quickstart (Gradle plugin)

plugins {
    kotlin("jvm") version "2.0.21"
    id("io.specmatic.priospot") version "1.0.0"
}

priospot {
    projectName.set("sample-kotlin-service")
    projectVersion.set("1.2.0")
    churnDays.set(30)
    outputDir.set(layout.buildDirectory.dir("reports/priospot"))
}

Run:

./gradlew priospot

Notes:

  • If sourceRoots, coverageReports, or complexityReports are not configured, the Gradle plugin auto-discovers submodule defaults where present:
    • src/main/kotlin, src/test/kotlin
    • build/reports/kover/report.xml
    • build/reports/detekt/detekt.xml
  • Missing configured coverage/complexity report files are treated as warnings; unmatched files use defaults:
    • coverage defaults to 0/1 for non-test sources
    • coverage defaults to 1/1 for src/test/** sources
    • complexity is derived from Kotlin source when report entries are missing; if source-derived complexity is unavailable, defaults to MAX-CCN=1000

Optional explicit override (when defaults do not fit your build):

priospot {
    sourceRoots.set(listOf("src/main/kotlin", "src/test/kotlin"))
    coverageReports.set(listOf("build/reports/kover/report.xml"))
    complexityReports.set(listOf("build/reports/detekt/detekt.xml"))
    coverageTask.set("koverXmlReport")
    complexityTask.set("detekt")
}

JaCoCo Integration (Gradle)

PrioSpot accepts JaCoCo XML reports. If you use the JaCoCo plugin, point PrioSpot to the JaCoCo XML output and (optionally) make priospot depend on jacocoTestReport.

plugins {
    kotlin("jvm") version "2.0.21"
    jacoco
    id("io.specmatic.priospot") version "1.0.0"
}

tasks.jacocoTestReport {
    reports {
        xml.required.set(true)
        html.required.set(false)
        csv.required.set(false)
    }
}

priospot {
    projectName.set("sample-kotlin-service")
    sourceRoots.set(listOf("src/main/kotlin", "src/test/kotlin"))
    coverageReports.set(listOf("build/reports/jacoco/test/jacocoTestReport.xml"))
    complexityReports.set(listOf("build/reports/detekt/detekt.xml"))
    coverageTask.set("jacocoTestReport")
    complexityTask.set("detekt")
}

Run:

./gradlew test jacocoTestReport priospot

Notes:

  • Auto-discovery currently defaults to Kover (build/reports/kover/report.xml), so JaCoCo users should set coverageReports explicitly.
  • In multi-module builds, provide all JaCoCo XML report paths via coverageReports.

Expected outputs in build/reports/priospot:

  • priospot.json
  • priospot-interactive-treemap.svg
  • coverage-interactive-treemap.svg
  • complexity-interactive-treemap.svg
  • churn-interactive-treemap.svg

Quick Start (Jar and Docker)

Download the CLI from either:

Use the CLI Jar

From Maven Central:

java -jar priospot.jar --help

Use the Docker Image

A Docker image is also published with releases. Use the image/tag from the release notes and run it by mounting your repository:

docker run --rm \
  -v "$PWD:/usr/src/app" \
  specmatic/priospot \
  analyze \
  --project-name sample \
  --source-roots src/main/kotlin \
  --coverage-report build/reports/kover/report.xml \
  --complexity-report build/reports/detekt/detekt.xml \
  --output-json build/reports/priospot/priospot.json

Config File Keys

Supported keys (for host integrations):

  • projectName
  • projectVersion
  • baseNamespace (optional)
  • sourceRoots
  • coverageReports
  • complexityReports
  • churnDays
  • churnLog (optional)
  • outputDir
  • emitCompatibilityXml (default false)
  • deterministicTimestamp (optional)
  • coverageTask (optional)
  • complexityTask (optional)
  • defaultCoverageNumerator (optional, default 0.0)
  • defaultCoverageDenominator (optional, default 1.0)
  • defaultMaxCcn (optional, default 1000)

Treemap UX

  • File box area is proportional to file NCSS
  • No in-box labels by default (better density at scale); names are shown on hover tooltips
  • Click highlights selected file, full parent package chain, and module boundary
  • Right panel shows selected file path, primary metric, and all file metrics
  • Checkbox in right panel toggles Show test classes; when unchecked, treemap re-renders using only non-test files (src/test/** excluded)
  • Bottom-right legend explains colors for each report type (priospot, coverage, complexity, churn)

Sample Treemaps (Good vs Problem Areas)

Use the fast sample project outputs:

  • assets/priospot-interactive-treemap.svg
  • assets/coverage-interactive-treemap.svg
  • assets/complexity-interactive-treemap.svg
  • assets/churn-interactive-treemap.svg

What "problem" looks like:

  • Large box (high NCSS) + red/black in PrioSpot
  • Red in coverage treemap (low coverage)
  • Darker red in complexity/churn treemaps (hard-to-change + frequently changing)

What "good" looks like:

  • Large box that stays green/yellow in PrioSpot
  • Healthy coverage color for critical large files
  • Lower complexity and churn for foundational modules

How to interpret quickly:

  • Start with priospot-interactive-treemap.svg
  • Click the largest red/black file
  • Check details panel metrics
  • Cross-check same file in coverage, complexity, and churn treemaps
  • Prioritize files that are large + low coverage + high complexity + high churn

Non-Gradle Integration Example

Node wrapper script:

node examples/node-wrapper/run-priospot.mjs analyze --help

Schema

Canonical schema is available at:

  • schema/priospot.schema.json

Development

This section is for contributors and maintainers working on PrioSpot internals.

Modules

  • model: canonical priospot.json and coverage.json domain model
  • ingest-source: source file inventory
  • ingest-churn: git/baseline churn parser and indicators
  • ingest-coverage: coverage normalization and merge
  • ingest-complexity: complexity adapters and merge
  • compute-c3: exact C3 formula implementation
  • report-svg: interactive treemap SVG generator
  • engine: orchestration pipeline and outputs
  • gradle-plugin: host integration exposing a priospot task
  • cli: optional priospot CLI (analyze, report)
  • compat-xml: optional compatibility panopticode.xml exporter

About

PrioSpot (Prioritize Hotspots) is a language-agnostic hotspot engine that computes C3 (churn + complexity + coverage) and generates interactive SVG treemap reports to help you visualize and prioritize hotspots in your code.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages