Documentation
¶
Overview ¶
Package progress is the scan pipeline's live stage ledger: the frontends and the engine record what they are doing, and a display reads it back.
It is deliberately a LEAF — stdlib only, no repo imports. Every producer is a converter or the analysis engine, several call layers below the command, and a package they can all import must not drag a terminal library into their builds (the cgo C/C++ frontend included). internal/tui holds the rendering and the only golang.org/x/term dependency; the same split internal/scaninfo makes so internal/report can render a scan's telemetry without importing internal/scan.
Counters are PULLED, not pushed. A display polls Stages() on its own clock; nothing here has a callback. The Go lowerer advances once per function — tens of thousands of times, from every worker — so the write path has to be one atomic add, with no channel and no back-pressure policy for a display that falls behind. Elapsed time also has to keep moving while nothing at all is happening, which an event-driven design cannot do on its own.
The registry is process-global and armed for one scan at a time (internal/scan's WithProgress), the same shape as proc.SetTimeouts and buildpolicy.SetAllowed. Unarmed, Start returns nil and every method on a nil *Stage is a no-op, so an instrumented hook costs one nil check when nobody is watching.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Enable ¶
func Enable() (disable func())
Enable arms the registry for one scan and returns the function that disarms it. Disarming stops new registrations but leaves the ledger readable, so a display can render its final summary after the scan has returned.
A second Enable while one is active returns a no-op rather than resetting: two overlapping scans in one process would otherwise interleave into a single meaningless ledger, and silently dropping the second one's stages is the less confusing failure.
Types ¶
type Snapshot ¶
type Snapshot struct {
ID string
Label string
Total int // 0 when the stage has no measurable unit of work
Unit string // what Total counts: "files", "funcs", "rules"
Done int
Offset time.Duration
Elapsed time.Duration
Running bool
Failed bool
// Covered is how much of the stage's input actually made it through, of
// CoverTotal. CoverTotal is 0 when the stage has nothing to report. This is
// what lets a phase row carry its own completeness, instead of a separate
// coverage line the reader has to map back onto the phases.
Covered int
CoverTotal int
}
Snapshot is one stage as a display sees it. Elapsed runs live while the stage is Running and is final once it is not; Offset is when the stage began, measured from the moment the ledger was armed, so a display can show where a stage sat in the run without quantising it to its own frame clock.
type Stage ¶
type Stage struct {
// contains filtered or unexported fields
}
Stage is one named unit of pipeline work, from Start to Done.
func Start ¶
Start registers a stage and starts its clock, returning nil unless the registry is armed. total is the denominator and unit names what it counts — "files", "funcs", "rules". A bare number tells a reader nothing, so the unit is a parameter rather than something the display keeps its own table of: a new stage cannot then be added without saying what it counts. total of 0 means no countable work, and the stage is reported by elapsed time alone.
func (*Stage) Cover ¶
Cover records how much of the stage's input reached the engine. A frontend knows this only once it has collected its results, which is after the last Advance and before Done.
type Warning ¶
Warning is a diagnostic a producer wants shown, already broken into the parts a reader needs: which language it came from, what happened, and where. The display shows these; the raw text a frontend also writes to stderr stays the complete record.