refactor(collect): make verbose mode emit progress
Verbose is now a real AX-facing behaviour instead of dead documentation. Excavator emits additional progress telemetry when verbose mode is enabled, and the new regression test protects that path. Co-Authored-By: Virgil <virgil@lethean.io>
This commit is contained in:
parent
9a0a1f4435
commit
1bccde8828
3 changed files with 42 additions and 0 deletions
|
|
@ -9,8 +9,10 @@ package collect
|
|||
import (
|
||||
"context"
|
||||
filepath "dappco.re/go/core/scm/internal/ax/filepathx"
|
||||
fmt "dappco.re/go/core/scm/internal/ax/fmtx"
|
||||
|
||||
"dappco.re/go/core/io"
|
||||
core "dappco.re/go/core/log"
|
||||
)
|
||||
|
||||
// Collector is the interface all collection sources implement.
|
||||
|
|
@ -91,6 +93,19 @@ func NewConfigWithMedium(m io.Medium, outputDir string) *Config {
|
|||
}
|
||||
}
|
||||
|
||||
// verboseProgress emits a progress event when verbose mode is enabled.
|
||||
// Usage: verboseProgress(cfg, "excavator", "loading state")
|
||||
func verboseProgress(cfg *Config, source, message string) {
|
||||
if cfg == nil || !cfg.Verbose {
|
||||
return
|
||||
}
|
||||
if cfg.Dispatcher != nil {
|
||||
cfg.Dispatcher.EmitProgress(source, message, nil)
|
||||
return
|
||||
}
|
||||
core.Warn(fmt.Sprintf("%s: %s", source, message))
|
||||
}
|
||||
|
||||
// MergeResults combines multiple results into a single aggregated result.
|
||||
// Usage: MergeResults(...)
|
||||
func MergeResults(source string, results ...*Result) *Result {
|
||||
|
|
|
|||
|
|
@ -43,9 +43,11 @@ func (e *Excavator) Run(ctx context.Context, cfg *Config) (*Result, error) {
|
|||
if cfg.Dispatcher != nil {
|
||||
cfg.Dispatcher.EmitStart(e.Name(), fmt.Sprintf("Starting excavation with %d collectors", len(e.Collectors)))
|
||||
}
|
||||
verboseProgress(cfg, e.Name(), fmt.Sprintf("queueing %d collectors", len(e.Collectors)))
|
||||
|
||||
// Load state if resuming
|
||||
if e.Resume && cfg.State != nil {
|
||||
verboseProgress(cfg, e.Name(), "loading resume state")
|
||||
if err := cfg.State.Load(); err != nil {
|
||||
return result, core.E("collect.Excavator.Run", "failed to load state", err)
|
||||
}
|
||||
|
|
@ -57,6 +59,7 @@ func (e *Excavator) Run(ctx context.Context, cfg *Config) (*Result, error) {
|
|||
if cfg.Dispatcher != nil {
|
||||
cfg.Dispatcher.EmitProgress(e.Name(), fmt.Sprintf("[scan] Would run collector: %s", c.Name()), nil)
|
||||
}
|
||||
verboseProgress(cfg, e.Name(), fmt.Sprintf("scan-only collector: %s", c.Name()))
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
|
@ -70,6 +73,7 @@ func (e *Excavator) Run(ctx context.Context, cfg *Config) (*Result, error) {
|
|||
cfg.Dispatcher.EmitProgress(e.Name(),
|
||||
fmt.Sprintf("Running collector %d/%d: %s", i+1, len(e.Collectors), c.Name()), nil)
|
||||
}
|
||||
verboseProgress(cfg, e.Name(), fmt.Sprintf("dispatching collector %d/%d: %s", i+1, len(e.Collectors), c.Name()))
|
||||
|
||||
// Check if we should skip (already completed in a previous run)
|
||||
if e.Resume && cfg.State != nil {
|
||||
|
|
@ -80,6 +84,7 @@ func (e *Excavator) Run(ctx context.Context, cfg *Config) (*Result, error) {
|
|||
fmt.Sprintf("Skipping %s (already collected %d items on %s)",
|
||||
c.Name(), entry.Items, entry.LastRun.Format(time.RFC3339)), nil)
|
||||
}
|
||||
verboseProgress(cfg, e.Name(), fmt.Sprintf("resume skip: %s", c.Name()))
|
||||
result.Skipped++
|
||||
continue
|
||||
}
|
||||
|
|
@ -115,6 +120,7 @@ func (e *Excavator) Run(ctx context.Context, cfg *Config) (*Result, error) {
|
|||
|
||||
// Save state
|
||||
if cfg.State != nil {
|
||||
verboseProgress(cfg, e.Name(), "saving resume state")
|
||||
if err := cfg.State.Save(); err != nil {
|
||||
if cfg.Dispatcher != nil {
|
||||
cfg.Dispatcher.EmitError(e.Name(), fmt.Sprintf("Failed to save state: %v", err), nil)
|
||||
|
|
|
|||
|
|
@ -203,3 +203,24 @@ func TestExcavator_Run_Good_Events_Good(t *testing.T) {
|
|||
assert.Equal(t, 1, startCount)
|
||||
assert.Equal(t, 1, completeCount)
|
||||
}
|
||||
|
||||
func TestExcavator_Run_Good_VerboseProgress_Good(t *testing.T) {
|
||||
m := io.NewMockMedium()
|
||||
cfg := NewConfigWithMedium(m, "/output")
|
||||
cfg.Limiter = nil
|
||||
cfg.Verbose = true
|
||||
|
||||
var progressCount int
|
||||
cfg.Dispatcher.On(EventProgress, func(e Event) {
|
||||
progressCount++
|
||||
})
|
||||
|
||||
c1 := &mockCollector{name: "source-a", items: 1}
|
||||
e := &Excavator{
|
||||
Collectors: []Collector{c1},
|
||||
}
|
||||
|
||||
_, err := e.Run(context.Background(), cfg)
|
||||
assert.NoError(t, err)
|
||||
assert.GreaterOrEqual(t, progressCount, 2)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue