Files
syft/cmd/syft/cli/options/output.go
T
Alex Goodman b0ab75fd89 Replace core SBOM-creation API with builder pattern (#1383)
* remove existing cataloging API

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* add file cataloging config

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* add package cataloging config

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* add configs for cross-cutting concerns

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* rename CLI option configs to not require import aliases later

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* update all nested structs for the Catalog struct

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* update Catalog cli options

- add new cataloger selection options (selection and default)
- remove the excludeBinaryOverlapByOwnership
- deprecate "catalogers" flag
- add new javascript configuration

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* migrate relationship capabilities to separate internal package

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* refactor golang cataloger to use configuration options when creating packages

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* create internal object to facilitate reading from and writing to an SBOM

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* create a command-like object (task) to facilitate partial SBOM creation

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* add cataloger selection capability

- be able to parse string expressions into a set of resolved actions against sets
- be able to use expressions to select/add/remove tasks to/from the final set of tasks to run

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* add package, file, and environment related tasks

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* update existing file catalogers to use nested UI elements

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* add CreateSBOMConfig that drives the SBOM creation process

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* capture SBOM creation info as a struct

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* add CreateSBOM() function

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* fix tests

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* update docs with SBOM selection help + breaking changes

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* fix multiple override default inputs

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* fix deprecation flag printing to stdout

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* refactor cataloger selection description to separate object

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* address review comments

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* keep expression errors and show specific suggestions only

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* address additional review feedback

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* address more review comments

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* addressed additional PR review feedback

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* fix file selection references

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* remove guess language data generation option

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* add tests for coordinatesForSelection

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* rename relationship attributes

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* add descriptions to relationships config fields

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* improve documentation around configuration options

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* add explicit errors around legacy config entries

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

---------

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>
2024-01-12 17:39:13 -05:00

130 lines
3.3 KiB
Go

package options
import (
"fmt"
"sort"
"strings"
"github.com/hashicorp/go-multierror"
"github.com/scylladb/go-set/strset"
"github.com/anchore/clio"
"github.com/anchore/syft/syft/format/cyclonedxjson"
"github.com/anchore/syft/syft/format/cyclonedxxml"
"github.com/anchore/syft/syft/format/github"
"github.com/anchore/syft/syft/format/spdxjson"
"github.com/anchore/syft/syft/format/spdxtagvalue"
"github.com/anchore/syft/syft/format/syftjson"
"github.com/anchore/syft/syft/format/table"
"github.com/anchore/syft/syft/format/template"
"github.com/anchore/syft/syft/format/text"
"github.com/anchore/syft/syft/sbom"
)
var _ interface {
clio.FlagAdder
clio.PostLoader
} = (*Output)(nil)
// Output has the standard output options syft accepts: multiple -o, --file, --template
type Output struct {
AllowableOptions []string `yaml:"-" json:"-" mapstructure:"-"`
AllowMultipleOutputs bool `yaml:"-" json:"-" mapstructure:"-"`
AllowToFile bool `yaml:"-" json:"-" mapstructure:"-"`
Outputs []string `yaml:"output" json:"output" mapstructure:"output"` // -o, the format to use for output
OutputFile `yaml:",inline" json:"" mapstructure:",squash"`
Format `yaml:"format" json:"format" mapstructure:"format"`
}
func DefaultOutput() Output {
return Output{
AllowMultipleOutputs: true,
AllowToFile: true,
Outputs: []string{string(table.ID)},
OutputFile: OutputFile{
Enabled: true,
},
Format: DefaultFormat(),
}
}
func (o *Output) PostLoad() error {
var errs error
for _, loader := range []clio.PostLoader{&o.OutputFile, &o.Format} {
if err := loader.PostLoad(); err != nil {
errs = multierror.Append(errs, err)
}
}
return errs
}
func (o *Output) AddFlags(flags clio.FlagSet) {
var names []string
for _, id := range supportedIDs() {
names = append(names, id.String())
}
sort.Strings(names)
flags.StringArrayVarP(&o.Outputs, "output", "o",
fmt.Sprintf("report output format (<format>=<file> to output to a file), formats=%v", names))
}
func (o Output) SBOMWriter() (sbom.Writer, error) {
names := o.OutputNameSet()
if len(o.Outputs) > 1 && !o.AllowMultipleOutputs {
return nil, fmt.Errorf("only one output format is allowed (given %d: %s)", len(o.Outputs), names)
}
usesTemplateOutput := names.Has(string(template.ID))
if usesTemplateOutput && o.Format.Template.Path == "" {
return nil, fmt.Errorf(`must specify path to template file when using "template" output format`)
}
encoders, err := o.Encoders()
if err != nil {
return nil, err
}
if !o.AllowToFile {
for _, opt := range o.Outputs {
if strings.Contains(opt, "=") {
return nil, fmt.Errorf("file output is not allowed ('-o format=path' should be '-o format')")
}
}
}
return makeSBOMWriter(o.Outputs, o.LegacyFile, encoders)
}
func (o Output) OutputNameSet() *strset.Set {
names := strset.New()
for _, output := range o.Outputs {
fields := strings.Split(output, "=")
names.Add(fields[0])
}
return names
}
func supportedIDs() []sbom.FormatID {
encs := []sbom.FormatID{
// encoders that support a single version
syftjson.ID,
github.ID,
table.ID,
text.ID,
template.ID,
// encoders that support multiple versions
cyclonedxxml.ID,
cyclonedxjson.ID,
spdxtagvalue.ID,
spdxjson.ID,
}
return encs
}