Adjust the terminal progress reporter a little

Mostly to reduce the amount of OSC 9;4 sequences written to stdout.
This commit is contained in:
Bjørn Erik Pedersen
2025-10-02 12:13:47 +02:00
parent 7fd6762c16
commit 510d98b778
4 changed files with 42 additions and 29 deletions
+1 -1
View File
@@ -1763,7 +1763,7 @@ func (sa *sitePagesAssembler) assembleResources() error {
if !sa.h.isRebuild() {
if ps.hasRenderableOutput() {
// For multi output pages this will not be complete, but will have to do for now.
sa.h.buildProgress.numPagesToRender.Add(1)
sa.h.progressReporter.numPagesToRender.Add(1)
}
}
+33 -21
View File
@@ -101,7 +101,7 @@ type HugoSites struct {
numWorkersSites int
numWorkers int
buildProgress progressReporter
*progressReporter
*fatalErrorHandler
*buildCounters
// Tracks invocations of the Build method.
@@ -112,7 +112,7 @@ type progressReporter struct {
mu sync.Mutex
t time.Time
progress float64
queue []func(*progressReporter) (state terminal.ProgressState, progress float64)
queue []func() (state terminal.ProgressState, progress float64)
state terminal.ProgressState
renderProgressStart float64
numPagesToRender atomic.Uint64
@@ -274,46 +274,58 @@ func (h *HugoSites) codeownersForPage(p page.Page) ([]string, error) {
return h.codeownerInfo.forPage(p), nil
}
func (h *HugoSites) reportProgress(f func(*progressReporter) (state terminal.ProgressState, progress float64)) {
h.buildProgress.mu.Lock()
defer h.buildProgress.mu.Unlock()
func (h *HugoSites) reportProgress(f func() (state terminal.ProgressState, progress float64)) {
h.progressReporter.mu.Lock()
defer h.progressReporter.mu.Unlock()
if h.buildProgress.t.IsZero() {
if h.progressReporter.t.IsZero() {
// Not started yet, queue it up and return.
h.buildProgress.queue = append(h.buildProgress.queue, f)
h.progressReporter.queue = append(h.progressReporter.queue, f)
return
}
handleOne := func(ff func(*progressReporter) (state terminal.ProgressState, progress float64)) {
state, progress := ff(&h.buildProgress)
handleOne := func(skip func(state terminal.ProgressState, progress float64) bool, handle func() (state terminal.ProgressState, progress float64)) {
state, progress := handle()
if skip != nil && skip(state, progress) {
return
}
if h.buildProgress.progress > 0 && h.buildProgress.state == state && progress <= h.buildProgress.progress {
if h.progressReporter.progress > 0 && h.progressReporter.state == state && progress <= h.progressReporter.progress {
// Only report progress forward.
return
}
h.buildProgress.state = state
h.buildProgress.progress = progress
terminal.ReportProgress(h.Log.StdOut(), state, h.buildProgress.progress)
h.progressReporter.state = state
h.progressReporter.progress = progress
terminal.ReportProgress(h.Log.StdOut(), state, h.progressReporter.progress)
}
// Drain queue first.
for _, ff := range h.buildProgress.queue {
handleOne(ff)
skip := func(state terminal.ProgressState, progress float64) bool {
// Skip qued up intermediate states if we already are in normal state.
return h.progressReporter.state == terminal.ProgressNormal && state == terminal.ProgressIntermediate
}
h.buildProgress.queue = nil
for _, ff := range h.progressReporter.queue {
handleOne(skip, ff)
}
h.progressReporter.queue = nil
handleOne(f)
handleOne(nil, f)
}
func (h *HugoSites) onPageRender() {
pagesRendered := h.buildCounters.pageRenderCounter.Add(1)
if pagesRendered <= 100 || pagesRendered%10 == 0 {
h.reportProgress(func(pr *progressReporter) (terminal.ProgressState, float64) {
numPagesToRender := h.progressReporter.numPagesToRender.Load()
n := numPagesToRender / 30
if n == 0 {
n = 1
}
if pagesRendered%n == 0 {
h.reportProgress(func() (terminal.ProgressState, float64) {
pr := h.progressReporter
if pr.renderProgressStart == 0.0 && pr.state == terminal.ProgressNormal {
pr.renderProgressStart = h.buildProgress.progress
pr.renderProgressStart = pr.progress
}
numPagesToRender := pr.numPagesToRender.Load()
pagesProgress := pr.renderProgressStart + float64(pagesRendered)/float64(numPagesToRender)*(1.0-pr.renderProgressStart)
return terminal.ProgressNormal, pagesProgress
})
+7 -7
View File
@@ -64,8 +64,8 @@ func (h *HugoSites) Build(config BuildCfg, events ...fsnotify.Event) error {
// Don't show progress for fast builds.
d := debounce.New(250 * time.Millisecond)
d(func() {
h.buildProgress.Start()
h.reportProgress(func(*progressReporter) (state terminal.ProgressState, progress float64) {
h.progressReporter.Start()
h.reportProgress(func() (state terminal.ProgressState, progress float64) {
// We don't know how many files to process below, so use the intermediate state as the first progress.
return terminal.ProgressIntermediate, 1.0
})
@@ -76,7 +76,7 @@ func (h *HugoSites) Build(config BuildCfg, events ...fsnotify.Event) error {
infol := h.Log.InfoCommand("build")
defer loggers.TimeTrackf(infol, time.Now(), nil, "")
defer func() {
h.reportProgress(func(*progressReporter) (state terminal.ProgressState, progress float64) {
h.reportProgress(func() (state terminal.ProgressState, progress float64) {
return terminal.ProgressHidden, 1.0
})
h.buildCounter.Add(1)
@@ -166,14 +166,14 @@ func (h *HugoSites) Build(config BuildCfg, events ...fsnotify.Event) error {
if err := h.process(ctx, infol, conf, init, events...); err != nil {
return fmt.Errorf("process: %w", err)
}
h.reportProgress(func(*progressReporter) (state terminal.ProgressState, progress float64) {
return terminal.ProgressNormal, 0.2
h.reportProgress(func() (state terminal.ProgressState, progress float64) {
return terminal.ProgressNormal, 0.15
})
if err := h.assemble(ctx, infol, conf); err != nil {
return fmt.Errorf("assemble: %w", err)
}
h.reportProgress(func(*progressReporter) (state terminal.ProgressState, progress float64) {
return terminal.ProgressNormal, 0.25
h.reportProgress(func() (state terminal.ProgressState, progress float64) {
return terminal.ProgressNormal, 0.20
})
return nil
+1
View File
@@ -360,6 +360,7 @@ func newHugoSites(cfg deps.DepsCfg, d *deps.Deps, pageTrees *pageTrees, sites []
data: lazy.New(),
gitInfo: lazy.New(),
},
progressReporter: &progressReporter{},
}
// Assemble dependencies to be used in hugo.Deps.