processor

package
v4.0.0 Latest Latest
Warning

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

Go to latest
Published: Aug 24, 2026 License: MIT Imports: 46 Imported by: 0

Documentation

Overview

Code generated by scripts/include.go using 'go generate'. DO NOT EDIT.

Index

Constants

View Source
const (
	TString int = iota + 1
	TSlcomment
	TMlcomment
	TComplexity
	TComplexityPostfix
)

Used by trie structure to store the types

View Source
const (
	ByteTypeBlank   byte = 0
	ByteTypeCode    byte = 1
	ByteTypeComment byte = 2
	ByteTypeString  byte = 3
)

ByteType constants for per-byte content classification. When FileJob.ClassifyContent is true, CountStats populates FileJob.ContentByteType with one of these values per byte.

View Source
const (
	SBlank             int64 = 1
	SCode              int64 = 2
	SComment           int64 = 3
	SCommentCode       int64 = 4 // Indicates comment after code
	SMulticomment      int64 = 5
	SMulticommentCode  int64 = 6 // Indicates multi comment after code
	SMulticommentBlank int64 = 7 // Indicates multi comment ended with blank afterward
	SString            int64 = 8
	SDocString         int64 = 9
)

The below are used as identifiers for the code state machine

View Source
const CouplingMaxFilesPerCommit = 30

CouplingMaxFilesPerCommit is the default size cap: commits touching more than this many files are excluded from PAIR counting (each file still counts toward its own commit total). A commit touching hundreds of files is a sweep — initial import, vendored dump, gofmt, a license-header change — that carries no logical-coupling signal yet costs O(k²) pairs. 0 disables the cap.

View Source
const CouplingMinShared = 2

CouplingMinShared is the floor on co-change count for a pair to appear in any output. A pair that changed together only once is almost always a coincidence, not coupling, so the noise is dropped at the source. Raw counts below this are still accumulated; they're just not reported.

View Source
const DefaultReportName = "scc-report.html"

DefaultReportName is the file name used when --report is invoked without a path (pflag's NoOptDefVal). main.go wires this in as the bare-flag default; runReport compares ReportOut to it to decide whether the user supplied an explicit path or relied on the default.

View Source
const SheBang string = "#!"

SheBang is a global constant for indicating a shebang file header

View Source
const SimilarStringThreshold float64 = 0.75
View Source
const UnknownLanguage string = "Unknown"

UnknownLanguage is the category files are counted under when --count-unsupported is set and scc does not recognise the file's language. It has no language features so such files are counted as plain text (no comments or complexity).

Variables

View Source
var AllowListExtensions = []string{}

AllowListExtensions is a list of extensions which are allowed to be processed

View Source
var AverageWage int64 = 56286

AverageWage is the average wage in dollars used for the COCOMO cost estimate

View Source
var BloomTable [256]uint64
View Source
var ByAuthor = false

ByAuthor toggles the author-rollup git-history report

View Source
var ByteOrderMarks = [][]byte{
	{254, 255},
	{255, 254},
	{0, 0, 254, 255},
	{255, 254, 0, 0},
	{43, 47, 118, 56},
	{43, 47, 118, 57},
	{43, 47, 118, 43},
	{43, 47, 118, 47},
	{43, 47, 118, 56, 45},
	{247, 100, 76},
	{221, 115, 102, 115},
	{14, 254, 255},
	{251, 238, 40},
	{132, 49, 149, 51},
}

ByteOrderMarks are taken from https://en.wikipedia.org/wiki/Byte_order_mark#Byte_order_marks_by_encoding These indicate that we cannot count the file correctly so we can at least warn the user

View Source
var Ci = false

Ci indicates if running inside a CI so to disable box drawing characters

View Source
var Cocomo = false

Cocomo toggles the COCOMO calculation

View Source
var CocomoProjectType = "organic"

CocomoProjectType allows the flipping between project types which impacts the calculation

View Source
var Cognitive = false

Cognitive toggles cognitive (nesting-weighted) complexity calculation

View Source
var Complexity = false

Complexity toggles complexity calculation

View Source
var CostComparison = false

CostComparison enables both COCOMO and LOCOMO output for side-by-side comparison

View Source
var CountAs = ""

CountAs is a rule for mapping known or new extensions to other rules

View Source
var CountAsPattern []string

CountAsPattern holds the raw repeatable --count-as-pattern flag values. Each is parsed into a CountRule at setup. Library users may set CountRules directly.

View Source
var CountIgnore = false

CountIgnore should we count ignore files?

View Source
var CountRules []CountRule

CountRules is the typed input set either directly by library users or by the CLI after parsing CountAsPattern. Setup happens in setupCountRules.

View Source
var CountUnsupported = false

CountUnsupported when set counts files scc does not recognise under an "Unknown" category, treating them as plain text. See issue #464.

View Source
var Coupling = false

Coupling toggles the change-coupling git-history report (file pairs that change together)

View Source
var CouplingFor = ""

CouplingFor, when non-empty, switches the coupling report to the file-oriented "blast radius" view for the given path: what tends to change when that file changes.

View Source
var CouplingWeighted = false

CouplingWeighted ranks coupling by degree × the pair's (smaller) file complexity instead of raw co-change, so pairs of genuinely complex files outrank generated/data-file churn. Implies Coupling. Honours the Cognitive global for its complexity source, matching --hotspots.

View Source
var CurrencySymbol = ""

CurrencySymbol allows setting the currency symbol for cocomo project cost estimation

View Source
var Debug = false

Debug enables debug logging output

View Source
var DirFilePaths = []string{}

DirFilePaths is not set via flags but by arguments following the flags for file or directory to process

View Source
var DirectoryWalkerJobWorkers = 8

DirectoryWalkerJobWorkers is the number of workers which will walk the directory tree

View Source
var DisableCheckBinary = false

DisableCheckBinary toggles checking for binary files using NUL bytes

View Source
var Dryness = false

Dryness toggles checking for binary files using NUL bytes

View Source
var Duplicates = false

Duplicates enables duplicate file detection

View Source
var EAF float64 = 1.0

EAF is the effort adjustment factor derived from the cost drivers, i.e. 1.0 if rated nominal

View Source
var Exclude = []string{}

Exclude is a regular expression which is used to exclude files from being processed

View Source
var ExcludeFilename = []string{}

ExcludeFilename is a list of filenames which should be ignored

View Source
var ExcludeListExtensions = []string{}

ExcludeListExtensions is a list of extensions which should be ignored

View Source
var ExtensionToLanguage = map[string][]string{}

ExtensionToLanguage is loaded from the JSON that is in constants.go

View Source
var FileListQueueSize = runtime.NumCPU()

FileListQueueSize is the queue of files found and ready to be read into memory

View Source
var FileOutput = ""

FileOutput sets the file that output should be written to

View Source
var FileProcessJobWorkers = runtime.NumCPU() * 4

FileProcessJobWorkers is the number of workers that process the file collecting stats

View Source
var FileSummaryJobQueueSize = runtime.NumCPU()

FileSummaryJobQueueSize is the queue used to hold processed file statistics before formatting

View Source
var FilenameToLanguage = map[string]string{}

FilenameToLanguage similar to ExtensionToLanguage loaded from the JSON in constants.go

View Source
var Files = false

Files indicates if there should be file output or not when formatting

View Source
var FoldAuthors = true

FoldAuthors enables the name+domain identity folding fallback applied after the mailmap. Toggled off via --no-fold-authors.

View Source
var Format = ""

Format sets the output format of the formatter

View Source
var FormatMulti = ""

FormatMulti is a rule for defining multiple output formats

View Source
var GcFileCount = 10000

GcFileCount is the number of files to process before turning the GC back on

View Source
var Generated = false

Generated enables generated file detection

View Source
var GeneratedMarkers []string

GeneratedMarkers defines head markers for generated file detection

View Source
var GitIgnore = false

GitIgnore disables .gitignore checks

View Source
var GitModuleIgnore = false

GitModuleIgnore disables .gitmodules checks

View Source
var HBorder = false

Draw horizontal borders between sections.

View Source
var HistoryBuckets = 60

HistoryBuckets is the time-bucket resolution for the timeline reports. Wired to --buckets in main.go; default 60.

View Source
var HistoryDepth = 1000

HistoryDepth is the maximum number of commits the history engine walks. 0 means "entire history". Wired to --depth in main.go.

View Source
var Hotspots = false

Hotspots toggles the hotspots git-history report

View Source
var Ignore = false

Ignore disables ignore file checks

View Source
var IgnoreFiles = []string{}

IgnoreFiles are paths to additional ignore files supplied via --ignore-file. They are applied as a low priority base layer in the order supplied so a later file can override an earlier one, and any in-tree .gitignore/.ignore/.sccignore discovered while walking overrides all of them.

View Source
var IgnoreGenerated = false

IgnoreGenerated ignore printing counts for generated files

View Source
var IgnoreMinified = false

IgnoreMinified ignore printing counts for minified files

View Source
var IgnoreMinifiedGenerate = false

IgnoreMinifiedGenerate printing counts for minified/generated files

View Source
var IncludeSymLinks = false

IncludeSymLinks if set true will count symlink files

View Source
var LanguageFeatures = map[string]LanguageFeature{}

LanguageFeatures contains the processed languages from processLanguageFeature

View Source
var LanguageFeaturesMutex = sync.Mutex{}

LanguageFeaturesMutex is the shared mutex used to control getting and setting of language features used rather than sync.Map because it turned out to be marginally faster

View Source
var Languages = false

Languages indicates if the command line should print out the supported languages

View Source
var LargeByteCount int64 = 1000000

LargeByteCount number of bytes before being counted as a large file based on https://github.com/pinpt/ripsrc/blob/master/ripsrc/fileinfo/fileinfo.go#L44

View Source
var LargeLineCount int64 = 40000

LargeLineCount number of lines before being counted as a large file based on https://github.com/pinpt/ripsrc/blob/master/ripsrc/fileinfo/fileinfo.go#L44

View Source
var Locomo = false

Locomo toggles the LOCOMO (LLM Output COst MOdel) calculation

View Source
var LocomoBaseInputPerLine float64 = 20

LocomoBaseInputPerLine is the base number of input tokens per output line

View Source
var LocomoComplexityWeight float64 = 5

LocomoComplexityWeight is the scaling weight applied to sqrt(complexity density) for input tokens

View Source
var LocomoConfig = ""

LocomoConfig is the power-user config string "tokensPerLine,baseInputPerLine,complexityWeight,iterations,iterationWeight"

View Source
var LocomoCyclesOverride float64

LocomoCyclesOverride is the user-supplied iteration factor override (--locomo-cycles)

View Source
var LocomoCyclesSet = false

LocomoCyclesSet indicates whether --locomo-cycles was explicitly set

View Source
var LocomoInputPrice float64

LocomoInputPrice is the cost per 1M input tokens (overrides preset)

View Source
var LocomoInputPriceSet = false
View Source
var LocomoIterationWeight float64 = 2

LocomoIterationWeight is the scaling weight for complexity-driven retries

View Source
var LocomoIterations float64 = 1.5

LocomoIterations is the base number of iteration/retry attempts

View Source
var LocomoOutputPrice float64

LocomoOutputPrice is the cost per 1M output tokens (overrides preset)

View Source
var LocomoOutputPriceSet = false
View Source
var LocomoPresetName = "medium"

LocomoPresetName is the LLM model preset for pricing and throughput defaults

View Source
var LocomoReviewMinutesPerLine float64 = 0.01

LocomoReviewMinutesPerLine is the human review time per line of code in minutes

View Source
var LocomoTPS float64

LocomoTPS is the output tokens per second (overrides preset)

View Source
var LocomoTPSSet = false
View Source
var LocomoTokensPerLine float64 = 10

LocomoTokensPerLine is the average number of output tokens per line of code

View Source
var MaxMean = false

MaxMean sets the calculation of the max and mean line length

View Source
var Minified = false

Minified enables minified file detection

View Source
var MinifiedGenerated = false

MinifiedGenerated enables minified/generated file detection

View Source
var MinifiedGeneratedLineByteLength = 255

MinifiedGeneratedLineByteLength number of bytes per average line to determine file is minified/generated

View Source
var More = false

More enables wider output with more information in formatter

View Source
var NoLarge = false

NoLarge if set true will ignore files over a certain number of lines or bytes

View Source
var Overhead float64 = 2.4

Overhead is the overhead multiplier for corporate overhead (facilities, equipment, accounting, etc.)

View Source
var PathDenyList = []string{}

PathDenyList sets the paths that should be skipped

View Source
var Percent = false

Percent toggles checking for binary files using NUL bytes

View Source
var RemapAll = ""

RemapAll allows remapping of all files with a string to search the content for

View Source
var RemapUnknown = ""

RemapUnknown allows remapping of unknown files with a string to search the content for

View Source
var ReportOut = ""

ReportOut is the output path supplied via --report. Empty means report mode is off; any other value (including DefaultReportName when the user passed a bare `--report`) flips Process() into the HTML-report branch.

View Source
var ReportSkip = ""

ReportSkip is the raw comma-separated value supplied via --report-skip. Process() parses it into ReportSkipNames before the report runs.

View Source
var ReportSkipNames = map[string]bool{}

ReportSkipNames is the parsed, lower-cased set of section names supplied via --report-skip. Wired from main.go (spec 05). CollectReportData reads this through ReportSkipped to decide which *Result pointers to nil out before returning.

View Source
var ReportTitle = ""

ReportTitle is the override for the repo name used in the report banner (spec 05). Empty means "auto-detect".

View Source
var SLOCCountFormat = false

SLOCCountFormat prints a more SLOCCount like COCOMO calculation

View Source
var SQLProject = ""

SQLProject is used to store the name for the SQL insert formats but is optional

View Source
var SccIgnore = false

SccIgnore disables sccignore file checks

View Source
var ShebangLookup = map[string][]string{}

ShebangLookup loaded from the JSON in constants.go contains shebang lookups

View Source
var Size = false

Size toggles the Size calculation

View Source
var SizeUnit = "si"

SizeUnit determines what size calculation is used for megabytes

View Source
var SortBy = ""

SortBy sets which column output in formatter should be sorted by

View Source
var Timeline = false

Timeline selects an over-time view. With ByAuthor, runs the author timeline report (plan 04); alone, runs the languages-over-time report (plan 05). With Hotspots set, the combination errors out.

View Source
var Trace = false

Trace enables trace logging output which is extremely verbose

View Source
var UlocMode = false

UlocMode toggles checking for binary files using NUL bytes

View Source
var Verbose = false

Verbose enables verbose logging output

View Source
var Version = "4.0.0"

Version indicates the version of the application

Functions

func BloomHash

func BloomHash(b byte) uint64

func ConfigureGc

func ConfigureGc()

ConfigureGc needs to be set outside of ProcessConstants because it should only be enabled in command line mode https://github.com/boyter/scc/issues/32

func ConfigureLazy

func ConfigureLazy(lazy bool)

ConfigureLazy is a simple setter used to turn on lazy loading used only by command line

func CountStats

func CountStats(fileJob *FileJob)

CountStats will process the fileJob If the file contains anything even just a newline its line count should be >= 1. If the file has a size of 0 its line count should be 0. Newlines belong to the line they started on so a file of \n means only 1 line This is the 'hot' path for the application and needs to be as fast as possible

func CouplingForJSONReport

func CouplingForJSONReport(repoPath, target string, limit int) (string, error)

CouplingForJSONReport walks history and returns the directional coupling for a single target file as JSON — the MCP entry point. limit > 0 caps the partner list (ranked by Degree, highest first); limit <= 0 returns every partner.

target accepts the same forms as --coupling-for and is validated against HEAD before the walk, so a caller passing a bad path gets an immediate error rather than paying for a full traversal first.

func CouplingJSONReport

func CouplingJSONReport(repoPath string, limit int) (string, error)

CouplingJSONReport walks the git history at repoPath and returns the coupling report as a JSON string — the programmatic entry point for the MCP server, which needs the rendered data rather than stdout side effects. A limit > 0 caps the pair list (strongest first); limit <= 0 returns every pair.

func DetectLanguage

func DetectLanguage(name string) ([]string, string)

DetectLanguage detects a language based on the filename returns the language extension and error

func DetectSheBang

func DetectSheBang(content []byte) (string, error)

DetectSheBang given some content attempt to determine if it has a #! that maps to a known language and return the language

func DetermineLanguage

func DetermineLanguage(filename string, fallbackLanguage string, possibleLanguages []string, content []byte) string

DetermineLanguage given a filename, fallback language, possible languages and content make a guess to the type. If multiple possible it will guess based on keywords similar to how https://github.com/vmchale/polyglot does

func EnableGc

func EnableGc()

EnableGc restores the garbage collector to the percentage captured by ConfigureGc.

func EstimateCost

func EstimateCost(effortApplied float64, averageWage int64, overhead float64) float64

EstimateCost calculates the cost in dollars applied using generic COCOMO weighted values based on the average yearly wage

func EstimateEffort

func EstimateEffort(sloc int64, eaf float64) float64

EstimateEffort calculate the effort applied using generic COCOMO weighted values

func EstimateScheduleMonths

func EstimateScheduleMonths(effortApplied float64) float64

EstimateScheduleMonths estimates the effort in months based on the result from EstimateEffort

func GetMostSimilarFlags

func GetMostSimilarFlags(flagSet *pflag.FlagSet, flag string) []string

func HotspotsJSONReport

func HotspotsJSONReport(repoPath string, limit int) (string, error)

HotspotsJSONReport walks the git history at repoPath and returns the hotspots report as a JSON string. It is the programmatic entry point used by the MCP server, which needs the rendered data rather than the stdout/file side effects of runHotspotsReport. A limit > 0 caps the number of files in the output (highest-scoring first); limit <= 0 returns every scored file. HistoryDepth and the mailmap folding behave exactly as on the CLI path.

func LanguageDatabase

func LanguageDatabase() map[string]Language

LanguageDatabase provides access to the internal language database useful for consuming applications wanting to consume and use

func LoadLanguageFeature

func LoadLanguageFeature(loadName string)

LoadLanguageFeature will load a single feature as requested given the name

func LocomoComplexityDensity

func LocomoComplexityDensity(complexity, code int64) float64

LocomoComplexityDensity calculates complexity/code with a guard for division by zero

func LocomoComplexityFactor

func LocomoComplexityFactor(complexityDensity, complexityWeight float64) float64

LocomoComplexityFactor calculates the input token scaling factor based on complexity density Uses sqrt scaling to prevent runaway compounding

func LocomoIterationFactor

func LocomoIterationFactor(complexityDensity, baseIterations, iterationWeight float64) float64

LocomoIterationFactor calculates the iteration/retry multiplier based on complexity density Uses sqrt scaling to prevent runaway compounding

func PrintDebug

func PrintDebug(msg string)

PrintDebug is an exported wrapper around printDebug so package main can flush buffered config discovery messages once Debug has been set.

func PrintError

func PrintError(msg string)

PrintError is an exported wrapper around printError so package main (config discovery, etc.) can emit ungated stderr errors using the same formatting.

func PrintLanguages

func PrintLanguages(dst io.Writer)

func PrintTrace

func PrintTrace(msg string)

PrintTrace is an exported wrapper around printTrace so package main can flush buffered config discovery messages once Trace has been set.

func Process

func Process()

Process is the main entry point of the command line it sets everything up and starts running

func ProcessConstants

func ProcessConstants()

ProcessConstants is responsible for setting up the language features based on the JSON file that is stored in constants Needs to be called at least once in order for anything to actually happen

func RenderReport

func RenderReport(d ReportData, outPath string) error

RenderReport renders the share card first (so the result can be embedded as og:image in the main template) and then writes the page to outPath.

func ReportSkipped

func ReportSkipped(section string) bool

ReportSkipped reports whether the given section name was listed in --report-skip. Section names are case-insensitive — callers can pass either case.

func StringSimilarRatio

func StringSimilarRatio(s1, s2 string) float64

StringSimilarRatio calculates the similarity ratio between s1 and s2.

The function is based on the Levenshtein distance. The ratio is calculated using the formula:

1 - (Levenshtein Distance / length of the longer string).

It returns a float64 between 0.0 (completely dissimilar) and 1.0 (identical). Based on experience, a ratio >= SimilarStringThreshold can generally be considered to indicate that two strings are highly similar.

Note: The comparison is case-sensitive. For example, "hello" and "HELLO" will be treated as completely different strings (their similarity ratio is 0).

Types

type AuthorRow

type AuthorRow struct {
	Name            string
	Email           string
	Code            int64
	Comment         int64
	Complexity      int64
	Files           int
	OwnsPercent     float64
	InWindowPercent float64
	LastCommit      time.Time
	Sentinel        bool
}

AuthorRow is one row of the authors rollup table. Mirrors authorRow but public for template consumers.

type AuthorTimelineBucket

type AuthorTimelineBucket struct {
	Commits   int
	CodeDelta int64
}

AuthorTimelineBucket is one bucket of an author's timeline series.

type AuthorTimelineResult

type AuthorTimelineResult struct {
	Window  HistoryWindow
	Bucket  Bucketing
	Rows    []AuthorTimelineRow
	Buckets int
}

AuthorTimelineResult mirrors the author-timeline observer output.

type AuthorTimelineRow

type AuthorTimelineRow struct {
	Name         string
	Email        string
	TotalCommits int
	CodeDelta    int64
	Series       []AuthorTimelineBucket
}

AuthorTimelineRow is one row of the author timeline table.

type AuthorsResult

type AuthorsResult struct {
	Window       HistoryWindow
	Rows         []AuthorRow
	BusFactor    int
	BusAuthors   []string
	BusCovered   float64
	InWindowCode int64
}

AuthorsResult mirrors the data the authors tabular formatter consumes. The Sentinel pseudo-row (`(before window)`) is included in Rows; consumers filter or call it out separately.

type Bar

type Bar struct {
	X     int
	W     int
	H     int
	Y     int
	Count int64
	Label string
}

Bar is one bar in a histogram. Used by bucketBars for the line-length chart. X is the SVG x-coordinate, W and H are width/height in user units.

type BaselineFile

type BaselineFile struct {
	Path       string
	Language   string
	LineTypes  []LineType
	Complexity []int // 1-based line numbers that fired a complexity tick
}

BaselineFile is one file from the window's start-commit tree, classified by scc's engine. Carries per-line type and complexity placement so observers can attribute lines that survive untouched from before the window.

type BaselineObserver

type BaselineObserver interface {
	Seed(BaselineSnapshot)
}

BaselineObserver is an optional extension to CommitObserver. When an observer implements it, the engine builds the baseline snapshot before the walk and calls Seed once. Observers that don't need the baseline (e.g. Hotspots) skip the expense by not implementing the interface.

type BaselineSnapshot

type BaselineSnapshot struct {
	Files   map[string]BaselineFile
	Mailmap *mailmap
}

BaselineSnapshot is the optional pre-walk state handed to observers that implement BaselineObserver. Files holds the classified contents of the window's start-commit tree (empty when the window covers all history); Mailmap is the parsed .mailmap from the HEAD tree, if present.

type Bucketing

type Bucketing struct {
	From  time.Time
	To    time.Time
	N     int
	Width time.Duration
}

Bucketing divides [From, To] into N equal time slices. Used by the timeline reports (plans 04 and 05) to map per-commit timestamps to a fixed-resolution per-bucket series independent of terminal width.

func NewBucketing

func NewBucketing(from, to time.Time, n int) Bucketing

NewBucketing constructs a Bucketing covering [from, to] divided into n equal-width slices. n must be > 0; n <= 0 is normalised to 1 so callers can pass user input unchecked. A degenerate window (from == to or to before from) yields Width=0; all commits land in bucket 0 / N-1.

func (Bucketing) Index

func (b Bucketing) Index(t time.Time) int

Index returns the 0..N-1 bucket slot for commit time t. Times before From clamp to 0 (defensive — should not happen given the walk window). Times at or after To clamp to N-1.

func (Bucketing) Start

func (b Bucketing) Start(i int) time.Time

Start returns the wall-clock start time of bucket i. Indexes outside [0, N) are clamped.

type CheckDuplicates

type CheckDuplicates struct {
	// contains filtered or unexported fields
}

CheckDuplicates is used to hold hashes if duplicate detection is enabled it comes with a mutex that should be locked while a check is being performed then added

func (*CheckDuplicates) Add

func (c *CheckDuplicates) Add(key int64, hash []byte)

Add is a non thread safe add a key into the duplicates check need to use mutex inside struct before calling this

func (*CheckDuplicates) Check

func (c *CheckDuplicates) Check(key int64, hash []byte) bool

Check is a non thread safe check to see if the key exists already need to use mutex inside struct before calling this

func (*CheckDuplicates) Clear

func (c *CheckDuplicates) Clear()

Clear drops every recorded hash, taking the mutex itself. Called between runs so a second in-process invocation does not treat the first run's files as duplicates of themselves.

type CocomoResult

type CocomoResult struct {
	ProjectType     string
	SumCode         int64
	EstimatedEffort float64 // person-months
	EstimatedCost   float64 // dollars
	ScheduleMonths  float64
	PeopleRequired  float64
	AverageWage     int64
	Overhead        float64
	EAF             float64
	CurrencySymbol  string
}

CocomoResult is the structured output of the basic COCOMO model so callers can render it however they need (HTML report, tabular, JSON). The summary-line tabular output is produced by calculateCocomo from these values.

func (CocomoResult) PrettyCost

func (r CocomoResult) PrettyCost() string

PrettyCost renders EstimatedCost as a currency-prefixed, comma-separated integer (e.g. "$1,234,567"). Used by the HTML report's headline template where the trailing decimals add noise without value.

type CommitInfo

type CommitInfo struct {
	Hash   plumbing.Hash
	Author string
	Email  string
	When   time.Time
}

CommitInfo is the per-commit metadata handed to observers.

type CommitObserver

type CommitObserver interface {
	Observe(c CommitInfo, changes []FileChange)
	Finalise(window HistoryWindow, head HeadSnapshot)
}

CommitObserver is implemented by each report's accumulator. The engine invokes Observe once per commit oldest-first, then Finalise once with the window metadata and a snapshot of the HEAD tree (latest language / complexity per surviving file).

type CompiledHeuristic

type CompiledHeuristic struct {
	Re       *regexp.Regexp
	Literals [][]byte
	Anchored bool
}

CompiledHeuristic is the runtime form of a Heuristic with its regex compiled and its literals pre-converted to bytes for matching.

type CountRule

type CountRule struct {
	Engine       MatchEngine // MatchGlob (the default) or MatchRegex
	Pattern      string      // glob or regex source
	Name         string      // new category display name
	BaseLanguage string      // existing language whose counting rules are cloned
}

CountRule is the typed, library-facing form of a --count-as-pattern rule. It matches files by their path and relabels them to a new named category whose counting rules are cloned from an existing base language.

type CouplingCount

type CouplingCount struct {
	A        string // lexicographically smaller surviving path
	B        string // lexicographically larger surviving path
	Shared   int    // commits in which BOTH changed
	CommitsA int    // commits in which A changed (window total)
	CommitsB int    // commits in which B changed (window total)

	// HEAD complexity of each file (cyclomatic, or cognitive when the Cognitive
	// global is on), populated at Finalise. Only consumed by the weighted
	// ranking; zero for data/generated files that carry no complexity signal.
	ComplexityA int64
	ComplexityB int64
}

CouplingCount is the raw, unopinionated co-change record for one unordered file pair: how often each file changed across the window, and how often they changed in the same commit. scc emits these integers; any ratio a consumer wants — symmetric degree, or the directional P(B changes | A changed) that answers "blast radius" — is a division the consumer chooses, not scc.

func (CouplingCount) Degree

func (c CouplingCount) Degree() float64

Degree is the symmetric coupling ratio shared/(a+b−shared) as a 0–100 percentage — the standard temporal-coupling "degree". It is a convenience for the human-facing table only; the raw counts sit beside it so the number is never a black box. Returns 0 when the union is empty.

func (CouplingCount) WeightedScore

func (c CouplingCount) WeightedScore() float64

WeightedScore ranks a pair by co-change volume × the pair's smaller file complexity — the same shape --hotspots uses (complexity × commits), applied to a pair. Two effects fall out of it:

  • min-complexity means a pair only scores when BOTH files are complex, so a complex file coupled to a zero-complexity data/generated file (JSON, HTML, Markdown) drops away — the churn-noise the raw view surfaces at the top.
  • Shared (raw volume), not Degree, is the co-change term. Degree rewards a thin 2-shared-commit pair that always moved together with a coincidental 100%; multiplied by high test-file complexity that buries the real work. Volume keeps the heavyweight couplings on top and matches --hotspots.

type CouplingPairRow

type CouplingPairRow struct {
	FileA  string
	FileB  string
	Shared int
	Degree float64
}

CouplingPairRow is one file pair. Public so report consumers don't depend on the private CouplingCount type.

type CouplingPartner

type CouplingPartner struct {
	Path          string
	Shared        int // commits changing BOTH target and this partner
	PartnerCommit int // partner's window commit total
	TargetCommit  int // target's window commit total

	// HEAD complexity of the partner and the target, populated by partnersFor.
	// Only consumed by the weighted ranking.
	PartnerComplexity int64
	TargetComplexity  int64
}

CouplingPartner is one file that co-changes with a chosen target file.

Couple answers "if I change the target, how likely am I to touch this too". On its own it is confounded by the partner's base rate: a file that changes in most commits scores a near-perfect Couple against ANY target, purely because it is always there. Such a hub shows HIGH Couple and LOW Reverse — e.g. a target touched 3 times, always alongside a file touched 158 times, gives Couple 100% / Reverse 1.9%.

Degree is the base-rate-corrected view and is what rows are ranked by; the two directional numbers are kept as supporting detail.

func (CouplingPartner) Couple

func (p CouplingPartner) Couple() float64

Couple is P(partner changes | target changed) = Shared / TargetCommit, the directional blast-radius probability: edit the target, expect to edit this.

func (CouplingPartner) Degree

func (p CouplingPartner) Degree() float64

Degree is the symmetric coupling ratio Shared/(target+partner−Shared) as a 0–100 percentage — the same measure the pairwise --coupling report ranks by, so the two views agree on what "strongly coupled" means.

Unlike Couple it is not fooled by a busy partner: a hub present in every one of the target's commits still scores low here, because its own large commit total sits in the denominator.

func (CouplingPartner) Reverse

func (p CouplingPartner) Reverse() float64

Reverse is P(target changes | partner changed) = Shared / PartnerCommit. A large gap between Reverse and Couple marks an asymmetric (hub-style) link rather than a true peer coupling.

func (CouplingPartner) WeightedScore

func (p CouplingPartner) WeightedScore() float64

WeightedScore mirrors the pairwise weighting for the blast-radius view: co-change volume × the smaller of the target's and partner's complexity, so a file's complex, frequently-co-changing neighbours outrank the trivial ones.

type CouplingResult

type CouplingResult struct {
	Window     HistoryWindow
	Pairs      []CouplingPairRow
	TotalPairs int
	Available  bool
}

CouplingResult mirrors the all-pairs change-coupling data. Pairs is already sorted strongest-first (raw co-change volume — the report never uses the complexity-weighted ranking).

type DonutArc

type DonutArc struct {
	Color      string
	Dasharray  string
	Dashoffset float64
}

DonutArc is the geometry for a single arc segment in a donut chart. Used by donutArcs and consumed via the dasharray/dashoffset SVG attributes on a <circle>. Spec calls for this even though the sample mockup uses a flat composition bar — included for future templates / share-card variants.

type FileChange

type FileChange struct {
	Path             string
	FromPath         string // != Path on a detected rename; "" on a pure add
	Language         string
	AddedRanges      []LineRange
	RemovedRanges    []LineRange
	LineTypes        []LineType
	RemovedLineTypes []LineType // old-blob line types, for code-filtered removals
	Complexity       []int
	NewBlob          []byte
}

FileChange is one changed file inside a commit. AddedRanges/RemovedRanges describe the diff against the first parent; LineTypes and Complexity are scc's classifier output for the new blob (one LineType per line, one entry in Complexity per line that fired a complexity tick).

type FileJob

type FileJob struct {
	Language             string
	PossibleLanguages    []string // Used to hold potentially more than one language which populates language when determined
	Filename             string
	Extension            string
	Location             string
	Symlocation          string
	Content              []byte `json:"-"`
	Bytes                int64
	Lines                int64
	Code                 int64
	Comment              int64
	Blank                int64
	Complexity           int64
	Cognitive            int64   // nesting-weighted complexity; JSON emission is gated on the Cognitive global via MarshalJSON
	ComplexityLine       []int64 `json:"-"`
	CognitiveLine        []int64 `json:"-"` // per-line cognitive weight; populated only when TrackComplexityLines and Cognitive are both enabled
	WeightedComplexity   float64
	Hash                 hash.Hash
	Callback             FileJobCallback `json:"-"`
	Binary               bool
	Minified             bool
	Generated            bool
	EndPoint             int
	Uloc                 int
	LineLength           []int  `json:"-"`
	ClassifyContent      bool   `json:"-"` // When true, CountStats populates ContentByteType
	ContentByteType      []byte `json:"-"` // Per-byte classification, allocated by CountStats when ClassifyContent is true
	TrackComplexityLines bool   `json:"-"` // When true, CountStats populates ComplexityLine
	// contains filtered or unexported fields
}

FileJob is a struct used to hold all of the results of processing internally before sent to the formatter

func (*FileJob) FilterContentByType

func (fj *FileJob) FilterContentByType(keepTypes ...byte) []byte

FilterContentByType returns a copy of Content with bytes not matching any of the given types replaced by spaces. Newlines are always preserved regardless of type. Returns nil if ContentByteType is nil.

func (*FileJob) MarshalJSON

func (fileJob *FileJob) MarshalJSON() ([]byte, error)

MarshalJSON emits FileJob with the Cognitive field present (even when 0) while the Cognitive global is on, and omitted entirely when it is off. A static `omitempty` tag cannot express this because it would also drop a legitimately zero cognitive value on a branch-free file while the metric is active. The unexported alias type carries the same field tags but none of the methods, so marshaling it does not recurse.

type FileJobCallback

type FileJobCallback interface {
	// ProcessLine should return true to continue processing or false to stop further processing and return
	ProcessLine(job *FileJob, currentLine int64, lineType LineType) bool
}

FileJobCallback is an interface that FileJobs can implement to get a per line callback with the line type

type FileReader

type FileReader struct {
	Buffer *bytes.Buffer
}

FileReader is a struct responsible for reading files into its buffer

func NewFileReader

func NewFileReader() FileReader

NewFileReader creates a new file reader responsible for reading a file

func (*FileReader) ReadFile

func (reader *FileReader) ReadFile(path string, size int) ([]byte, error)

ReadFile actually reads the file into a buffer size controlled by LargeByteCount

type HeadFile

type HeadFile struct {
	Path       string
	Language   string
	Complexity int64
	Cognitive  int64 // nesting-weighted complexity; zero unless the Cognitive global is on
}

HeadFile is one file in the HEAD tree, classified by scc's engine.

type HeadSnapshot

type HeadSnapshot struct {
	Files map[string]HeadFile
}

HeadSnapshot is the set of files in HEAD, keyed by path.

type Heuristic

type Heuristic struct {
	// Pattern is the regex evaluated against the file content.
	Pattern string `json:"pattern"`
	// Literals is the set of substrings of which at least one must be present
	// (case sensitive) for Pattern to have any chance of matching. When empty
	// the regex is always run, so a pattern is never silently disabled.
	Literals []string `json:"literals"`
	// Anchored, when true, requires each literal to sit at the start of a line
	// preceded only by spaces or tabs. This mirrors the (?m)^[ \t]* prefix used
	// by the keyword patterns and avoids false positives such as the substring
	// "entry" satisfying a check for the "try" keyword.
	Anchored bool `json:"anchored"`
}

Heuristic is a regex pattern used to disambiguate shared file extensions (for example .h between C / C++ / Objective-C) along with a cheap set of necessary string literals. The expensive regex is only run when one of Literals is present in the content, which is a fast reject for the overwhelmingly common case where the file is not the language being guessed. See guessByHeuristics.

type HistoryWindow

type HistoryWindow struct {
	Depth   int
	Commits int
	From    time.Time
	To      time.Time
	Head    plumbing.Hash
}

HistoryWindow describes the commit window the engine walked.

type HotspotRow

type HotspotRow struct {
	File         string
	Language     string
	Complexity   int64
	Commits      int
	LinesChanged int64
	Authors      int
	CodeChurn    int64
	CommentChurn int64
	Score        float64
}

HotspotRow is one row of the hotspots table. Pulled out so report consumers don't depend on the private hotspotsRecord type.

type HotspotsResult

type HotspotsResult struct {
	Window    HistoryWindow
	Records   []HotspotRow
	TotalRaw  int
	Available bool
}

HotspotsResult mirrors the data the tabular hotspot formatter consumes. Records is already sorted by Score desc.

type Json2

type Json2 struct {
	LanguageSummary         []LanguageSummary `json:"languageSummary"`
	EstimatedCost           float64           `json:"estimatedCost"`
	EstimatedScheduleMonths float64           `json:"estimatedScheduleMonths"`
	EstimatedPeople         float64           `json:"estimatedPeople"`

	// LOCOMO fields (only populated when --locomo or --cost-comparison is enabled)
	EstimatedLLMCost                  *float64 `json:"estimatedLLMCost,omitempty"`
	EstimatedLLMInputTokens           *float64 `json:"estimatedLLMInputTokens,omitempty"`
	EstimatedLLMOutputTokens          *float64 `json:"estimatedLLMOutputTokens,omitempty"`
	EstimatedLLMGenerationSeconds     *float64 `json:"estimatedLLMGenerationSeconds,omitempty"`
	EstimatedLLMReviewHours           *float64 `json:"estimatedLLMReviewHours,omitempty"`
	EstimatedLLMPreset                *string  `json:"estimatedLLMPreset,omitempty"`
	EstimatedLLMAverageComplexityMult *float64 `json:"estimatedLLMAverageComplexityMultiplier,omitempty"`
	EstimatedLLMCycles                *float64 `json:"estimatedLLMCycles,omitempty"`
}

type LangTimelineResult

type LangTimelineResult struct {
	Window  HistoryWindow
	Bucket  Bucketing
	Rows    []LangTimelineRow
	Buckets int
}

LangTimelineResult mirrors the language-timeline observer output.

type LangTimelineRow

type LangTimelineRow struct {
	Language      string
	StartingLines int64
	CodeNow       int64
	Change        int64
	SharePercent  float64
	Deltas        []int64
	Trajectory    []int64
}

LangTimelineRow is one row of the language timeline table.

type Language

type Language struct {
	LineComment                     []string    `json:"line_comment"`
	ComplexityChecks                []string    `json:"complexitychecks"`
	ComplexityChecksPostfix         []string    `json:"complexitychecks_postfix"`
	ComplexityChecksPostfixExcludes []string    `json:"complexitychecks_postfix_excludes"`
	Extensions                      []string    `json:"extensions"`
	MultiLine                       [][]string  `json:"multi_line"`
	Quotes                          []Quote     `json:"quotes"`
	Keywords                        []string    `json:"keywords"`
	Heuristics                      []Heuristic `json:"heuristics"`
	FileNames                       []string    `json:"filenames"`
	SheBangs                        []string    `json:"shebangs"`
	ExtensionFile                   bool        `json:"extensionFile"`
	NestedMultiLine                 bool        `json:"nestedmultiline"`
}

Language is a struct which contains the values for each language stored in languages.json

type LanguageFeature

type LanguageFeature struct {
	Complexity            *Trie
	MultiLineComments     *Trie
	MultiLine             [][]string // in case someone needs the actual value
	SingleLineComments    *Trie
	LineComment           []string // in case someone needs the actual value
	Strings               *Trie
	Tokens                *Trie
	Nested                bool
	PostfixExcludes       [][]byte
	ComplexityCheckMask   byte
	SingleLineCommentMask byte
	MultiLineCommentMask  byte
	StringCheckMask       byte
	ProcessMask           byte
	Keywords              []string
	KeywordBytes          [][]byte
	Heuristics            []CompiledHeuristic
	Quotes                []Quote
}

LanguageFeature is a struct which represents the conversion from Language into what is used for matching

type LanguageSummary

type LanguageSummary struct {
	Name               string
	Bytes              int64
	CodeBytes          int64
	Lines              int64
	Code               int64
	Comment            int64
	Blank              int64
	Complexity         int64
	Cognitive          int64 // nesting-weighted complexity; JSON emission is gated on the Cognitive global via MarshalJSON
	Count              int64
	WeightedComplexity float64
	Files              []*FileJob
	LineLength         []int
	ULOC               int
	CodePercent        *float64 `json:",omitempty"`
	CommentPercent     *float64 `json:",omitempty"`
	BlankPercent       *float64 `json:",omitempty"`
	LinePercent        *float64 `json:",omitempty"`
	ComplexityPercent  *float64 `json:",omitempty"`
	BytePercent        *float64 `json:",omitempty"`
	FilePercent        *float64 `json:",omitempty"`
}

LanguageSummary is used to hold summarized results for a single language

func ProcessResult

func ProcessResult() ([]LanguageSummary, error)

ProcessResult runs the same pipeline as Process but returns structured results instead of formatting to stdout. Useful for programmatic consumers like MCP servers.

func (LanguageSummary) MarshalJSON

func (l LanguageSummary) MarshalJSON() ([]byte, error)

MarshalJSON gates the language-level Cognitive field on the Cognitive global, mirroring FileJob.MarshalJSON: present (even at 0) when the metric is on, omitted when off. See FileJob.MarshalJSON for the rationale.

type LineLengthBucket

type LineLengthBucket struct {
	Start int // inclusive
	End   int // exclusive; 0 means "no upper bound" (the tail bucket)
	Count int64
	Label string // e.g. "0–20", "120+"
}

LineLengthBucket is one bar in the line-length histogram. Edges are inclusive-left, exclusive-right except for the open-ended tail bucket.

type LineLengthOutlier

type LineLengthOutlier struct {
	File       string
	Language   string
	LineLength int
}

LineLengthOutlier is one entry in the longest-lines callout list.

type LineLengthResult

type LineLengthResult struct {
	Buckets    []LineLengthBucket
	Mean       float64
	Max        int
	Outliers   []LineLengthOutlier
	TotalLines int64
}

LineLengthResult is the line-length histogram and summary statistics.

type LineRange

type LineRange struct {
	Start int
	Count int
}

LineRange is a half-open line span [Start, Start+Count) in 1-based line numbers. A FileChange carries one entry per contiguous run of added (or removed) lines emitted by go-git's diff.

type LineType

type LineType int32

LineType what type of line are processing

const (
	LINE_BLANK LineType = iota
	LINE_CODE
	LINE_COMMENT
)

These are not meant to be CAMEL_CASE but as it us used by an external project we cannot change it

type LocomoPreset

type LocomoPreset struct {
	Name        string
	InputPrice  float64 // cost per 1M input tokens
	OutputPrice float64 // cost per 1M output tokens
	TPS         float64 // output tokens per second
}

LocomoPreset defines the pricing and throughput for an LLM tier. Presets are tier-based (large/medium/small/local) rather than model-specific, so they don't go stale as specific models are retired or renamed.

func GetLocomoPreset

func GetLocomoPreset(name string) LocomoPreset

GetLocomoPreset returns the preset for the given name, falling back to medium

type LocomoResult

type LocomoResult struct {
	InputTokens           float64
	OutputTokens          float64
	Cost                  float64
	GenerationSeconds     float64
	ReviewHours           float64
	AverageComplexityMult float64
	IterationFactor       float64
	Preset                string
}

LocomoResult holds the computed estimates from the LOCOMO model

func LocomoEstimate

func LocomoEstimate(sumCode, sumComplexity int64) LocomoResult

LocomoEstimate computes the full LOCOMO estimate for a project

type MailmapObserver

type MailmapObserver interface {
	SetMailmap(*mailmap)
}

MailmapObserver is an optional extension to CommitObserver. The engine always parses the repo's .mailmap from HEAD — one small blob — and hands it to observers that implement this, before the walk. Unlike BaselineObserver it does NOT trigger the expensive start-tree classification, so observers that only need author folding (e.g. Hotspots, the author timeline) can implement it cheaply.

type MatchEngine

type MatchEngine int

MatchEngine selects how a CountRule pattern is interpreted. Glob is the default; regex is opt-in via the re: prefix.

const (
	// MatchGlob is the default. The pattern is a glob ('*' and '?') translated
	// to an anchored regex and matched as a full match against the path.
	MatchGlob MatchEngine = iota
	// MatchRegex treats the pattern as a raw (unanchored) RE2 regex. Opt in
	// with the re: prefix.
	MatchRegex
)

type OpenClose

type OpenClose struct {
	Open  []byte
	Close []byte
}

OpenClose is used to hold an open/close pair for matching such as multi line comments

type Quote

type Quote struct {
	Start        string `json:"start"`
	End          string `json:"end"`
	IgnoreEscape bool   `json:"ignoreEscape"` // To enable turning off the \ check for C# @"\" string examples https://github.com/boyter/scc/issues/71
	DocString    bool   `json:"docString"`    // To enable docstring check for Python where "If the triple quote string starts following a newline with only white-space characters in front and ends followed by only a newline or white-space characters it is a comment" https://github.com/boyter/scc/issues/62
}

Quote is a struct which holds rules and start/end values for string quotes

type ReportData

type ReportData struct {
	// Metadata
	RepoName     string
	GeneratedAt  time.Time
	SccVersion   string
	Duration     time.Duration
	GitAvailable bool

	// Default rollup (always present)
	Summary []LanguageSummary
	Totals  Totals

	// Optional analyses — nil/empty if skipped or unavailable.
	ULOC             *ULOCResult
	LineLength       *LineLengthResult
	Hotspots         *HotspotsResult
	Coupling         *CouplingResult
	Authors          *AuthorsResult
	LanguageTimeline *LangTimelineResult
	AuthorTimeline   *AuthorTimelineResult
	Files            []*FileJob

	// Cost
	Cocomo *CocomoResult
	Locomo *LocomoResult

	// Rendered share-card SVG (data: URL safe). Populated by RenderReport
	// before the main template runs so it can be embedded as og:image.
	CardSVG template.HTML
}

ReportData is the in-memory aggregate produced by CollectReportData. The HTML template consumes one of these values per report run.

func CollectReportData

func CollectReportData(path string) (ReportData, error)

CollectReportData orchestrates the full scc analysis surface for one report. It walks the tree once for default counts, runs the git-history observers (when git is available), computes cost estimates, and returns a ReportData ready for HTML templating.

IMPORTANT: this function mutates the package-level analysis flags (UlocMode, MaxMean, Files) while it runs. The previous values are snapshotted and restored via defer, but callers should not assume the flags retain their on-entry values during the call.

type Totals

type Totals struct {
	Files      int64
	Lines      int64
	Code       int64
	Comment    int64
	Blank      int64
	Complexity int64
	Bytes      int64
}

Totals captures the headline numbers shown in the report's Overview strip. Mirrors the sums computed by the tabular formatter (sumFiles / sumLines / …) but pulled into a struct so the template can read them by name.

type Trie

type Trie struct {
	Type  int
	Close []byte
	Table [256]*Trie
}

Trie is a structure used to store matches efficiently

func (*Trie) Insert

func (root *Trie) Insert(tokenType int, token []byte)

Insert inserts a string into the trie for matching

func (*Trie) InsertClose

func (root *Trie) InsertClose(tokenType int, openToken, closeToken []byte)

InsertClose closes off a string in the trie

func (*Trie) Match

func (root *Trie) Match(token []byte) (int, int, []byte)

Match checks the created trie structure for a match

type ULOCLanguage

type ULOCLanguage struct {
	Language string
	ULOC     int
}

ULOCLanguage is one row of the per-language ULOC slice. Sorted by ULOC descending, then name ascending.

type ULOCResult

type ULOCResult struct {
	Global      int
	PerLanguage []ULOCLanguage
	TotalLines  int64
	Dryness     float64
}

ULOCResult is the unique-lines-of-code rollup. Maps are converted to a stable slice here so the template can range deterministically.

Jump to

Keyboard shortcuts

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