github.com/anchore/syft@v1.38.2/internal/task/executor.go (about) 1 package task 2 3 import ( 4 "context" 5 "fmt" 6 "runtime/debug" 7 "slices" 8 "time" 9 10 "github.com/anchore/syft/internal/log" 11 "github.com/anchore/syft/internal/sbomsync" 12 "github.com/anchore/syft/internal/unknown" 13 "github.com/anchore/syft/syft/event/monitor" 14 "github.com/anchore/syft/syft/file" 15 "github.com/anchore/syft/syft/sbom" 16 ) 17 18 func RunTask(ctx context.Context, tsk Task, resolver file.Resolver, s sbomsync.Builder, prog *monitor.TaskProgress) error { 19 err := runTaskSafely(ctx, tsk, resolver, s) 20 unknowns, remainingErrors := unknown.ExtractCoordinateErrors(err) 21 if len(unknowns) > 0 { 22 appendUnknowns(s, tsk.Name(), unknowns) 23 } 24 if remainingErrors != nil { 25 prog.SetError(remainingErrors) 26 } 27 prog.Increment() 28 return remainingErrors 29 } 30 31 func appendUnknowns(builder sbomsync.Builder, taskName string, unknowns []unknown.CoordinateError) { 32 if accessor, ok := builder.(sbomsync.Accessor); ok { 33 accessor.WriteToSBOM(func(sb *sbom.SBOM) { 34 for _, u := range unknowns { 35 if sb.Artifacts.Unknowns == nil { 36 sb.Artifacts.Unknowns = map[file.Coordinates][]string{} 37 } 38 unknownText := formatUnknown(u.Reason.Error(), taskName) 39 existing := sb.Artifacts.Unknowns[u.Coordinates] 40 // don't include duplicate unknowns 41 if slices.Contains(existing, unknownText) { 42 continue 43 } 44 sb.Artifacts.Unknowns[u.Coordinates] = append(existing, unknownText) 45 } 46 }) 47 } 48 } 49 50 func runTaskSafely(ctx context.Context, t Task, resolver file.Resolver, s sbomsync.Builder) (err error) { 51 // handle individual cataloger panics 52 defer func() { 53 if e := recover(); e != nil { 54 err = fmt.Errorf("%v at:\n%s", e, string(debug.Stack())) 55 } 56 }() 57 58 start := time.Now() 59 res := t.Execute(ctx, resolver, s) 60 log.WithFields("task", t.Name(), "elapsed", time.Since(start)).Info("task completed") 61 return res 62 }