github.com/noqcks/syft@v0.0.0-20230920222752-a9e2c4e288e5/cmd/syft/cli/commands/convert.go (about) 1 package commands 2 3 import ( 4 "fmt" 5 "io" 6 "os" 7 8 "github.com/spf13/cobra" 9 10 "github.com/anchore/clio" 11 "github.com/anchore/syft/cmd/syft/cli/options" 12 "github.com/anchore/syft/internal" 13 "github.com/anchore/syft/internal/log" 14 "github.com/anchore/syft/syft/formats" 15 ) 16 17 const ( 18 convertExample = ` {{.appName}} {{.command}} img.syft.json -o spdx-json convert a syft SBOM to spdx-json, output goes to stdout 19 {{.appName}} {{.command}} img.syft.json -o cyclonedx-json=img.cdx.json convert a syft SBOM to CycloneDX, output is written to the file "img.cdx.json"" 20 {{.appName}} {{.command}} - -o spdx-json convert an SBOM from STDIN to spdx-json 21 ` 22 ) 23 24 type ConvertOptions struct { 25 options.Config `yaml:",inline" mapstructure:",squash"` 26 options.MultiOutput `yaml:",inline" mapstructure:",squash"` 27 options.UpdateCheck `yaml:",inline" mapstructure:",squash"` 28 } 29 30 //nolint:dupl 31 func Convert(app clio.Application) *cobra.Command { 32 id := app.ID() 33 34 opts := &ConvertOptions{ 35 UpdateCheck: options.DefaultUpdateCheck(), 36 } 37 38 return app.SetupCommand(&cobra.Command{ 39 Use: "convert [SOURCE-SBOM] -o [FORMAT]", 40 Short: "Convert between SBOM formats", 41 Long: "[Experimental] Convert SBOM files to, and from, SPDX, CycloneDX and Syft's format. For more info about data loss between formats see https://github.com/anchore/syft#format-conversion-experimental", 42 Example: internal.Tprintf(convertExample, map[string]interface{}{ 43 "appName": id.Name, 44 "command": "convert", 45 }), 46 Args: validateConvertArgs, 47 PreRunE: applicationUpdateCheck(id, &opts.UpdateCheck), 48 RunE: func(cmd *cobra.Command, args []string) error { 49 return RunConvert(opts, args[0]) 50 }, 51 }, opts) 52 } 53 54 func validateConvertArgs(cmd *cobra.Command, args []string) error { 55 return validateArgs(cmd, args, "an SBOM argument is required") 56 } 57 58 func RunConvert(opts *ConvertOptions, userInput string) error { 59 log.Warn("convert is an experimental feature, run `syft convert -h` for help") 60 61 writer, err := opts.SBOMWriter() 62 if err != nil { 63 return err 64 } 65 66 var reader io.ReadCloser 67 68 if userInput == "-" { 69 reader = os.Stdin 70 } else { 71 f, err := os.Open(userInput) 72 if err != nil { 73 return fmt.Errorf("failed to open SBOM file: %w", err) 74 } 75 defer func() { 76 _ = f.Close() 77 }() 78 reader = f 79 } 80 81 s, _, err := formats.Decode(reader) 82 if err != nil { 83 return fmt.Errorf("failed to decode SBOM: %w", err) 84 } 85 86 if s == nil { 87 return fmt.Errorf("no SBOM produced") 88 } 89 90 if err := writer.Write(*s); err != nil { 91 return fmt.Errorf("failed to write SBOM: %w", err) 92 } 93 94 return nil 95 }