github.com/kastenhq/syft@v0.0.0-20230821225854-0710af25cdbe/cmd/syft/cli/convert/convert.go (about) 1 package convert 2 3 import ( 4 "context" 5 "fmt" 6 "io" 7 "os" 8 9 "github.com/wagoodman/go-partybus" 10 11 "github.com/anchore/stereoscope" 12 "github.com/kastenhq/syft/cmd/syft/cli/eventloop" 13 "github.com/kastenhq/syft/cmd/syft/cli/options" 14 "github.com/kastenhq/syft/cmd/syft/internal/ui" 15 "github.com/kastenhq/syft/internal/bus" 16 "github.com/kastenhq/syft/internal/config" 17 "github.com/kastenhq/syft/internal/log" 18 "github.com/kastenhq/syft/syft" 19 "github.com/kastenhq/syft/syft/formats" 20 "github.com/kastenhq/syft/syft/sbom" 21 ) 22 23 func Run(_ context.Context, app *config.Application, args []string) error { 24 log.Warn("convert is an experimental feature, run `syft convert -h` for help") 25 26 writer, err := options.MakeSBOMWriter(app.Outputs, app.File, app.OutputTemplatePath) 27 if err != nil { 28 return err 29 } 30 31 // could be an image or a directory, with or without a scheme 32 userInput := args[0] 33 34 var reader io.ReadCloser 35 36 if userInput == "-" { 37 reader = os.Stdin 38 } else { 39 f, err := os.Open(userInput) 40 if err != nil { 41 return fmt.Errorf("failed to open SBOM file: %w", err) 42 } 43 defer func() { 44 _ = f.Close() 45 }() 46 reader = f 47 } 48 49 eventBus := partybus.NewBus() 50 stereoscope.SetBus(eventBus) 51 syft.SetBus(eventBus) 52 subscription := eventBus.Subscribe() 53 54 return eventloop.EventLoop( 55 execWorker(reader, writer), 56 eventloop.SetupSignals(), 57 subscription, 58 stereoscope.Cleanup, 59 ui.Select(options.IsVerbose(app), app.Quiet)..., 60 ) 61 } 62 63 func execWorker(reader io.Reader, writer sbom.Writer) <-chan error { 64 errs := make(chan error) 65 go func() { 66 defer close(errs) 67 defer bus.Exit() 68 69 s, _, err := formats.Decode(reader) 70 if err != nil { 71 errs <- fmt.Errorf("failed to decode SBOM: %w", err) 72 return 73 } 74 75 if s == nil { 76 errs <- fmt.Errorf("no SBOM produced") 77 return 78 } 79 80 if err := writer.Write(*s); err != nil { 81 errs <- fmt.Errorf("failed to write SBOM: %w", err) 82 } 83 }() 84 return errs 85 }