mirror of
https://github.com/anchore/syft.git
synced 2026-11-01 15:06:36 +01:00
117 lines
3.4 KiB
Go
117 lines
3.4 KiB
Go
package bus
|
|
|
|
import (
|
|
"context"
|
|
|
|
"github.com/wagoodman/go-partybus"
|
|
"github.com/wagoodman/go-progress"
|
|
|
|
"github.com/anchore/clio"
|
|
"github.com/anchore/syft/internal/redact"
|
|
"github.com/anchore/syft/syft/event"
|
|
"github.com/anchore/syft/syft/event/monitor"
|
|
)
|
|
|
|
func Exit() {
|
|
Publish(clio.ExitEvent(false))
|
|
}
|
|
|
|
func ExitWithInterrupt() {
|
|
Publish(clio.ExitEvent(true))
|
|
}
|
|
|
|
func Report(report string) {
|
|
if len(report) == 0 {
|
|
return
|
|
}
|
|
report = redact.Apply(report)
|
|
Publish(partybus.Event{
|
|
Type: event.CLIReport,
|
|
Value: report,
|
|
})
|
|
}
|
|
|
|
func Notify(message string) {
|
|
Publish(partybus.Event{
|
|
Type: event.CLINotification,
|
|
Value: message,
|
|
})
|
|
}
|
|
|
|
type catalogerTaskProgressKey struct{}
|
|
|
|
// WithCatalogerTaskProgress returns a context whose cataloger tasks report into prog rather than
|
|
// starting a row of their own.
|
|
//
|
|
// Nested cataloging runs under such a context: re-running the cataloger pipeline against the
|
|
// contents of an archive is work that belongs to the progress of the task driving the recursion, not
|
|
// a second start of every cataloger. Starting rows again per archive floods a consumer's display,
|
|
// and where the new row carries an ID the consumer has already seen (every package cataloger does -
|
|
// the ID is the cataloger name) it replaces the live row for that ID. The replaced row is then never
|
|
// rendered again, its completion is never observed, and a UI that waits on every row it started - as
|
|
// the syft CLI does - blocks forever on teardown.
|
|
func WithCatalogerTaskProgress(ctx context.Context, prog *monitor.TaskProgress) context.Context {
|
|
return context.WithValue(ctx, catalogerTaskProgressKey{}, prog)
|
|
}
|
|
|
|
// catalogerTaskProgressFromContext returns the progress that cataloger tasks started under this
|
|
// context report into, or nil when they should start one of their own.
|
|
func catalogerTaskProgressFromContext(ctx context.Context) *monitor.TaskProgress {
|
|
prog, _ := ctx.Value(catalogerTaskProgressKey{}).(*monitor.TaskProgress)
|
|
return prog
|
|
}
|
|
|
|
func StartCatalogerTask(ctx context.Context, info monitor.GenericTask, size int64, initialStage string) *monitor.TaskProgress {
|
|
if parent := catalogerTaskProgressFromContext(ctx); parent != nil {
|
|
// the stage is shared, so what this cataloger is working on shows up on the row already on
|
|
// screen; the count is not, so this task completing does not complete the row it reports into
|
|
return &monitor.TaskProgress{
|
|
AtomicStage: parent.AtomicStage,
|
|
Manual: progress.NewManual(size),
|
|
}
|
|
}
|
|
|
|
t := &monitor.TaskProgress{
|
|
AtomicStage: progress.NewAtomicStage(initialStage),
|
|
Manual: progress.NewManual(size),
|
|
}
|
|
|
|
Publish(partybus.Event{
|
|
Type: event.CatalogerTaskStarted,
|
|
Source: info,
|
|
Value: progress.StagedProgressable(t),
|
|
})
|
|
|
|
return t
|
|
}
|
|
|
|
func StartPullSourceTask(info monitor.GenericTask, size int64, initialStage string) *monitor.TaskProgress {
|
|
t := &monitor.TaskProgress{
|
|
AtomicStage: progress.NewAtomicStage(initialStage),
|
|
Manual: progress.NewManual(size),
|
|
}
|
|
|
|
Publish(partybus.Event{
|
|
Type: event.PullSourceStarted,
|
|
Source: info,
|
|
Value: progress.StagedProgressable(t),
|
|
})
|
|
|
|
return t
|
|
}
|
|
|
|
func StartIndexingFiles(path string) *monitor.TaskProgress {
|
|
t := &monitor.TaskProgress{
|
|
AtomicStage: progress.NewAtomicStage(""),
|
|
Manual: progress.NewManual(-1),
|
|
}
|
|
|
|
Publish(partybus.Event{
|
|
Type: event.FileIndexingStarted,
|
|
Source: path,
|
|
Value: progress.StagedProgressable(t),
|
|
})
|
|
|
|
return t
|
|
}
|