mirror of
https://github.com/anchore/syft.git
synced 2026-10-30 22:12:28 +01:00
Migrate format definitions to sbom package (#864)
This commit is contained in:
+24
-16
@@ -9,6 +9,10 @@ import (
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/anchore/syft/internal/formats/cyclonedx13json"
|
||||
"github.com/anchore/syft/internal/formats/spdx22json"
|
||||
"github.com/anchore/syft/internal/formats/syftjson"
|
||||
|
||||
"github.com/anchore/stereoscope"
|
||||
"github.com/anchore/stereoscope/pkg/image"
|
||||
"github.com/anchore/syft/internal"
|
||||
@@ -17,7 +21,7 @@ import (
|
||||
"github.com/anchore/syft/internal/ui"
|
||||
"github.com/anchore/syft/syft"
|
||||
"github.com/anchore/syft/syft/event"
|
||||
"github.com/anchore/syft/syft/format"
|
||||
"github.com/anchore/syft/syft/sbom"
|
||||
"github.com/anchore/syft/syft/source"
|
||||
"github.com/in-toto/in-toto-golang/in_toto"
|
||||
"github.com/pkg/errors"
|
||||
@@ -49,7 +53,11 @@ const (
|
||||
intotoJSONDsseType = `application/vnd.in-toto+json`
|
||||
)
|
||||
|
||||
var attestFormats = []format.Option{format.SPDXJSONOption, format.CycloneDxJSONOption, format.JSONOption}
|
||||
var attestFormats = []sbom.FormatID{
|
||||
syftjson.ID,
|
||||
spdx22json.ID,
|
||||
cyclonedx13json.ID,
|
||||
}
|
||||
|
||||
var (
|
||||
attestCmd = &cobra.Command{
|
||||
@@ -149,10 +157,10 @@ func attestExec(ctx context.Context, _ *cobra.Command, args []string) error {
|
||||
return fmt.Errorf("unable to generate attestation for more than one output")
|
||||
}
|
||||
|
||||
output := format.ParseOption(appConfig.Output[0])
|
||||
predicateType := assertPredicateType(output)
|
||||
format := syft.FormatByName(appConfig.Output[0])
|
||||
predicateType := formatPredicateType(format)
|
||||
if predicateType == "" {
|
||||
return fmt.Errorf("could not produce attestation predicate for given format: %q. Available formats: %+v", output, attestFormats)
|
||||
return fmt.Errorf("could not produce attestation predicate for given format: %q. Available formats: %+v", formatAliases(format.ID()), formatAliases(attestFormats...))
|
||||
}
|
||||
|
||||
passFunc, err := selectPassFunc(appConfig.Attest.Key)
|
||||
@@ -172,7 +180,7 @@ func attestExec(ctx context.Context, _ *cobra.Command, args []string) error {
|
||||
defer sv.Close()
|
||||
|
||||
return eventLoop(
|
||||
attestationExecWorker(*si, output, predicateType, sv),
|
||||
attestationExecWorker(*si, format, predicateType, sv),
|
||||
setupSignals(),
|
||||
eventSubscription,
|
||||
stereoscope.Cleanup,
|
||||
@@ -180,7 +188,7 @@ func attestExec(ctx context.Context, _ *cobra.Command, args []string) error {
|
||||
)
|
||||
}
|
||||
|
||||
func attestationExecWorker(sourceInput source.Input, output format.Option, predicateType string, sv *sign.SignerVerifier) <-chan error {
|
||||
func attestationExecWorker(sourceInput source.Input, format sbom.Format, predicateType string, sv *sign.SignerVerifier) <-chan error {
|
||||
errs := make(chan error)
|
||||
go func() {
|
||||
defer close(errs)
|
||||
@@ -200,7 +208,7 @@ func attestationExecWorker(sourceInput source.Input, output format.Option, predi
|
||||
return
|
||||
}
|
||||
|
||||
sbomBytes, err := syft.Encode(*s, output)
|
||||
sbomBytes, err := syft.Encode(*s, format)
|
||||
if err != nil {
|
||||
errs <- err
|
||||
return
|
||||
@@ -215,14 +223,14 @@ func attestationExecWorker(sourceInput source.Input, output format.Option, predi
|
||||
return errs
|
||||
}
|
||||
|
||||
func assertPredicateType(output format.Option) string {
|
||||
switch output {
|
||||
case format.SPDXJSONOption:
|
||||
func formatPredicateType(format sbom.Format) string {
|
||||
switch format.ID() {
|
||||
case spdx22json.ID:
|
||||
return in_toto.PredicateSPDX
|
||||
// Tentative see https://github.com/in-toto/attestation/issues/82
|
||||
case format.CycloneDxJSONOption:
|
||||
case cyclonedx13json.ID:
|
||||
// Tentative see https://github.com/in-toto/attestation/issues/82
|
||||
return "https://cyclonedx.org/bom"
|
||||
case format.JSONOption:
|
||||
case syftjson.ID:
|
||||
return "https://syft.dev/bom"
|
||||
default:
|
||||
return ""
|
||||
@@ -293,8 +301,8 @@ func setAttestFlags(flags *pflag.FlagSet) {
|
||||
|
||||
// in-toto attestations only support JSON predicates, so not all SBOM formats that syft can output are supported
|
||||
flags.StringP(
|
||||
"output", "o", string(format.JSONOption),
|
||||
fmt.Sprintf("the SBOM format encapsulated within the attestation, available options=%v", attestFormats),
|
||||
"output", "o", formatAliases(syftjson.ID)[0],
|
||||
fmt.Sprintf("the SBOM format encapsulated within the attestation, available options=%v", formatAliases(attestFormats...)),
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"github.com/anchore/syft/syft"
|
||||
"github.com/anchore/syft/syft/sbom"
|
||||
)
|
||||
|
||||
func formatAliases(ids ...sbom.FormatID) (aliases []string) {
|
||||
for _, id := range ids {
|
||||
switch id {
|
||||
case syft.JSONFormatID:
|
||||
aliases = append(aliases, "syft-json")
|
||||
case syft.TextFormatID:
|
||||
aliases = append(aliases, "text")
|
||||
case syft.TableFormatID:
|
||||
aliases = append(aliases, "table")
|
||||
case syft.SPDXJSONFormatID:
|
||||
aliases = append(aliases, "spdx-json")
|
||||
case syft.SPDXTagValueFormatID:
|
||||
aliases = append(aliases, "spdx-tag-value")
|
||||
case syft.CycloneDxXMLFormatID:
|
||||
aliases = append(aliases, "cyclonedx-xml")
|
||||
case syft.CycloneDxJSONFormatID:
|
||||
aliases = append(aliases, "cyclonedx-json")
|
||||
default:
|
||||
aliases = append(aliases, string(id))
|
||||
}
|
||||
}
|
||||
return aliases
|
||||
}
|
||||
+13
-18
@@ -4,9 +4,10 @@ import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/anchore/syft/internal/formats"
|
||||
"github.com/anchore/syft/internal/output"
|
||||
"github.com/anchore/syft/syft/format"
|
||||
"github.com/anchore/syft/internal/formats/table"
|
||||
|
||||
"github.com/anchore/syft/syft"
|
||||
|
||||
"github.com/anchore/syft/syft/sbom"
|
||||
"github.com/hashicorp/go-multierror"
|
||||
)
|
||||
@@ -19,7 +20,7 @@ func makeWriter(outputs []string, defaultFile string) (sbom.Writer, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
writer, err := output.MakeWriter(outputOptions...)
|
||||
writer, err := sbom.NewWriter(outputOptions...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -28,10 +29,10 @@ func makeWriter(outputs []string, defaultFile string) (sbom.Writer, error) {
|
||||
}
|
||||
|
||||
// parseOptions utility to parse command-line option strings and retain the existing behavior of default format and file
|
||||
func parseOptions(outputs []string, defaultFile string) (out []output.WriterOption, errs error) {
|
||||
func parseOptions(outputs []string, defaultFile string) (out []sbom.WriterOption, errs error) {
|
||||
// always should have one option -- we generally get the default of "table", but just make sure
|
||||
if len(outputs) == 0 {
|
||||
outputs = append(outputs, string(format.TableOption))
|
||||
outputs = append(outputs, string(table.ID))
|
||||
}
|
||||
|
||||
for _, name := range outputs {
|
||||
@@ -40,31 +41,25 @@ func parseOptions(outputs []string, defaultFile string) (out []output.WriterOpti
|
||||
// split to at most two parts for <format>=<file>
|
||||
parts := strings.SplitN(name, "=", 2)
|
||||
|
||||
// the format option is the first part
|
||||
// the format name is the first part
|
||||
name = parts[0]
|
||||
|
||||
// default to the --file or empty string if not specified
|
||||
file := defaultFile
|
||||
|
||||
// If a file is specified as part of the output option, use that
|
||||
// If a file is specified as part of the output formatName, use that
|
||||
if len(parts) > 1 {
|
||||
file = parts[1]
|
||||
}
|
||||
|
||||
option := format.ParseOption(name)
|
||||
if option == format.UnknownFormatOption {
|
||||
format := syft.FormatByName(name)
|
||||
if format == nil {
|
||||
errs = multierror.Append(errs, fmt.Errorf("bad output format: '%s'", name))
|
||||
continue
|
||||
}
|
||||
|
||||
encoder := formats.ByOption(option)
|
||||
if encoder == nil {
|
||||
errs = multierror.Append(errs, fmt.Errorf("unknown format: %s", outputFormat))
|
||||
continue
|
||||
}
|
||||
|
||||
out = append(out, output.WriterOption{
|
||||
Format: *encoder,
|
||||
out = append(out, sbom.WriterOption{
|
||||
Format: format,
|
||||
Path: file,
|
||||
})
|
||||
}
|
||||
|
||||
+6
-3
@@ -6,6 +6,10 @@ import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
|
||||
"github.com/anchore/syft/internal/formats/table"
|
||||
|
||||
"github.com/anchore/syft/syft"
|
||||
|
||||
"github.com/anchore/stereoscope"
|
||||
"github.com/anchore/syft/internal"
|
||||
"github.com/anchore/syft/internal/anchore"
|
||||
@@ -15,7 +19,6 @@ import (
|
||||
"github.com/anchore/syft/internal/version"
|
||||
"github.com/anchore/syft/syft/artifact"
|
||||
"github.com/anchore/syft/syft/event"
|
||||
"github.com/anchore/syft/syft/format"
|
||||
"github.com/anchore/syft/syft/pkg/cataloger"
|
||||
"github.com/anchore/syft/syft/sbom"
|
||||
"github.com/anchore/syft/syft/source"
|
||||
@@ -100,8 +103,8 @@ func setPackageFlags(flags *pflag.FlagSet) {
|
||||
fmt.Sprintf("selection of layers to catalog, options=%v", source.AllScopes))
|
||||
|
||||
flags.StringArrayP(
|
||||
"output", "o", []string{string(format.TableOption)},
|
||||
fmt.Sprintf("report output format, options=%v", format.AllOptions),
|
||||
"output", "o", formatAliases(table.ID),
|
||||
fmt.Sprintf("report output format, options=%v", formatAliases(syft.FormatIDs()...)),
|
||||
)
|
||||
|
||||
flags.StringP(
|
||||
|
||||
+1
-2
@@ -9,7 +9,6 @@ import (
|
||||
"github.com/anchore/syft/internal/bus"
|
||||
"github.com/anchore/syft/internal/formats/syftjson"
|
||||
"github.com/anchore/syft/internal/log"
|
||||
"github.com/anchore/syft/internal/output"
|
||||
"github.com/anchore/syft/internal/ui"
|
||||
"github.com/anchore/syft/internal/version"
|
||||
"github.com/anchore/syft/syft/artifact"
|
||||
@@ -74,7 +73,7 @@ func powerUserExec(_ *cobra.Command, args []string) error {
|
||||
// could be an image or a directory, with or without a scheme
|
||||
userInput := args[0]
|
||||
|
||||
writer, err := output.MakeWriter(output.WriterOption{
|
||||
writer, err := sbom.NewWriter(sbom.WriterOption{
|
||||
Format: syftjson.Format(),
|
||||
Path: appConfig.File,
|
||||
})
|
||||
|
||||
+4
-4
@@ -11,7 +11,7 @@ import (
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
var outputFormat string
|
||||
var versionCmdOutputFormat string
|
||||
|
||||
var versionCmd = &cobra.Command{
|
||||
Use: "version",
|
||||
@@ -20,14 +20,14 @@ var versionCmd = &cobra.Command{
|
||||
}
|
||||
|
||||
func init() {
|
||||
versionCmd.Flags().StringVarP(&outputFormat, "output", "o", "text", "format to show version information (available=[text, json])")
|
||||
versionCmd.Flags().StringVarP(&versionCmdOutputFormat, "output", "o", "text", "format to show version information (available=[text, json])")
|
||||
rootCmd.AddCommand(versionCmd)
|
||||
}
|
||||
|
||||
func printVersion(_ *cobra.Command, _ []string) {
|
||||
versionInfo := version.FromBuild()
|
||||
|
||||
switch outputFormat {
|
||||
switch versionCmdOutputFormat {
|
||||
case "text":
|
||||
fmt.Println("Application: ", internal.ApplicationName)
|
||||
fmt.Println("Version: ", versionInfo.Version)
|
||||
@@ -54,7 +54,7 @@ func printVersion(_ *cobra.Command, _ []string) {
|
||||
os.Exit(1)
|
||||
}
|
||||
default:
|
||||
fmt.Printf("unsupported output format: %s\n", outputFormat)
|
||||
fmt.Printf("unsupported output format: %s\n", versionCmdOutputFormat)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user