metric

package
v1.2.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 20, 2026 License: MIT Imports: 9 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func CalcDesign

func CalcDesign(commits []git.Commit, archPatterns []string) map[string]float64

CalcDesign scores architecture contributions weighted by lines changed. A commit touching architecture files scores the sum of (insertions + deletions) for those architecture files, giving more credit to substantial design work.

func CalcLines

func CalcLines(commits []git.Commit, excludePatterns []string) (added map[string]int, deleted map[string]int)

CalcLines returns per-author total lines added and deleted (excluding excluded patterns).

func CalcModuleSurvival

func CalcModuleSurvival(blameLines []git.BlameLine, tau float64, now time.Time) map[string]float64

CalcModuleSurvival computes per-module survival rate. For each module, it calculates the ratio of time-decayed blame sum to raw blame count, yielding a 0-1 survival rate. This measures how well a module's code endures over time, independent of who wrote it.

func CalcProduction

func CalcProduction(commits []git.Commit, excludePatterns []string) map[string]float64

func CalcQuality

func CalcQuality(commits []git.Commit) map[string]float64

func GetFixCommits

func GetFixCommits(commits []git.Commit) []git.Commit

func IsExcluded

func IsExcluded(filename string, patterns []string) bool

IsExcluded checks if a filename matches any of the exclude patterns.

func ModuleOf

func ModuleOf(path string) string

ModuleOf extracts a module identifier from a file path. Uses the first 3 directory components (e.g. "app/domain/payment"). For shallower paths, uses the parent directory.

Types

type ChangePressure

type ChangePressure map[string]float64

ChangePressure maps module path → pressure value (commits / blame lines).

func CalcChangePressure

func CalcChangePressure(commits []git.Commit, blameLines []git.BlameLine) ChangePressure

CalcChangePressure computes per-module change pressure. pressure = commits_touching_module / blame_lines_in_module

func (ChangePressure) MedianPressure

func (cp ChangePressure) MedianPressure() float64

MedianPressure returns the median pressure value across all modules.

type CochangeResult

type CochangeResult struct {
	Pairs         []ModulePair   // sorted by coupling descending
	ModuleCommits map[string]int // module → total commits touching it
}

CochangeResult holds the complete co-change analysis.

func CalcCochange

func CalcCochange(commits []git.Commit) CochangeResult

CalcCochange computes co-change coupling between modules.

For each commit, it identifies which modules are touched, then counts how often each pair of modules appears together. The coupling coefficient uses the Jaccard index: co-change / (commits_A + commits_B - co-change).

This is effectively an auto-generated Design Structure Matrix (DSM), the modular design framework proposed by Baldwin & Clark. High coupling between modules that should be independent signals a leaky boundary — a structural risk invisible from code alone.

type DebtData

type DebtData struct {
	Generated map[string]int
	Cleaned   map[string]int
}

func CalcDebt

func CalcDebt(ctx context.Context, repoPath string, fixCommits []git.Commit, maxSample int, debtThreshold int, blameTimeoutSec int, resolve ResolveFunc, progressFn ProgressFunc, verboseFn VerboseFunc) (map[string]float64, *DebtData)

CalcDebt calculates debt cleanup scores on a 0-100 scale. 50 = neutral (equal generation and cleanup, or insufficient data) >50 = net cleaner, <50 = net debt creator Formula: 50 + 50 * (cleaned - generated) / (cleaned + generated)

type ModuleOwnership

type ModuleOwnership struct {
	Module      string
	TotalLines  int
	AuthorCount int
	TopAuthor   string
	TopShare    float64 // 0.0-1.0
	Entropy     float64 // Shannon entropy (higher = more distributed)
	Level       string  // "SOLE_OWNER", "CONCENTRATED", "HEALTHY", "FRAGMENTED"
}

ModuleOwnership represents the ownership distribution of a single module. This is the structural inverse of Indispensability: instead of asking "how indispensable is this person?", it asks "how is this module's knowledge distributed?"

A module with SOLE_OWNER or CONCENTRATED ownership is a structural risk — if that person leaves, the module enters Dead Zone. A module with HEALTHY ownership has distributed knowledge — resilient. A module with FRAGMENTED ownership has no clear owner — coordination risk.

func CalcOwnershipFragmentation

func CalcOwnershipFragmentation(blameLines []git.BlameLine) []ModuleOwnership

CalcOwnershipFragmentation analyzes blame-line distribution per module. Uses ModuleOf() (3-level path) for consistency with ChangePressure.

This complements CalcIndispensability: Indispensability measures person-level risk ("this person owns too much"), while OwnershipFragmentation measures module-level risk ("this module's knowledge is too concentrated/scattered").

type ModulePair

type ModulePair struct {
	ModuleA       string
	ModuleB       string
	CochangeCount int     // number of commits touching both modules
	Coupling      float64 // Jaccard coefficient: co-change / union
}

ModulePair represents a co-change relationship between two modules. When two modules frequently appear in the same commit, they have implicit coupling — a structural dependency invisible in import graphs.

type ModuleRisk

type ModuleRisk struct {
	Module    string
	TopAuthor string
	Share     float64
	Level     string // "CRITICAL" or "HIGH"
}

func CalcIndispensability

func CalcIndispensability(blameLines []git.BlameLine, criticalThreshold, highThreshold float64) (map[string]float64, []ModuleRisk)

type ProgressFunc

type ProgressFunc func(done, total int)

ProgressFunc reports debt analysis progress (done, total fix commits)

type RawScores

type RawScores struct {
	Production       map[string]float64
	Quality          map[string]float64
	Survival         map[string]float64
	RawSurvival      map[string]float64 // non-decayed blame line count
	RobustSurvival   map[string]float64 // survival in high change-pressure modules
	DormantSurvival  map[string]float64 // survival in low change-pressure modules
	Design           map[string]float64
	Breadth          map[string]float64
	DebtCleanup      map[string]float64
	Indispensability map[string]float64
	TotalCommits     map[string]int // total commit count per author (across all repos in domain)
	LinesAdded       map[string]int // total lines added per author
	LinesDeleted     map[string]int // total lines deleted per author
}

func NewRawScores

func NewRawScores() *RawScores

func (*RawScores) Authors

func (r *RawScores) Authors() []string

type ResolveFunc

type ResolveFunc func(string) string

ResolveFunc maps a git author name to its canonical name

type SurvivalResult

type SurvivalResult struct {
	Decayed map[string]float64 // time-weighted survival (total)
	Raw     map[string]float64 // raw blame line count (no decay)
	Robust  map[string]float64 // survival in high-pressure modules
	Dormant map[string]float64 // survival in low-pressure modules
}

SurvivalResult holds both time-decayed and raw (non-decayed) blame counts, plus robust/dormant survival split based on change pressure.

func CalcSurvival

func CalcSurvival(blameLines []git.BlameLine, tau float64, now time.Time) SurvivalResult

func CalcSurvivalWithPressure

func CalcSurvivalWithPressure(blameLines []git.BlameLine, tau float64, now time.Time, pressure ChangePressure, threshold float64) SurvivalResult

CalcSurvivalWithPressure splits survival into robust (high-pressure modules) and dormant (low-pressure modules) based on change pressure threshold.

type VerboseFunc

type VerboseFunc func(msg string)

VerboseFunc logs detailed per-operation info (message string)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL