From 1c37bab2b2b45f59ab7a9b70e3a200206771996e Mon Sep 17 00:00:00 2001 From: Keith Zantow Date: Thu, 23 May 2024 15:18:09 -0400 Subject: [PATCH] feat: add config command (#2892) Signed-off-by: Keith Zantow --- cmd/syft/cli/cli.go | 1 + cmd/syft/internal/options/attest.go | 10 +++++- cmd/syft/internal/options/file.go | 20 +++++++++++ cmd/syft/internal/options/format.go | 42 ++++++++++++++++++---- cmd/syft/internal/options/golang.go | 23 ++++++++++++ cmd/syft/internal/options/java.go | 17 +++++++++ cmd/syft/internal/options/javascript.go | 11 ++++++ cmd/syft/internal/options/linux_kernel.go | 10 ++++++ cmd/syft/internal/options/output.go | 10 ++++++ cmd/syft/internal/options/pkg.go | 19 +++++++++- cmd/syft/internal/options/python.go | 13 +++++++ cmd/syft/internal/options/registry.go | 19 +++++++++- cmd/syft/internal/options/relationships.go | 4 +-- cmd/syft/internal/options/source.go | 11 ++++++ go.mod | 12 +++---- go.sum | 29 ++++++++------- 16 files changed, 219 insertions(+), 32 deletions(-) diff --git a/cmd/syft/cli/cli.go b/cmd/syft/cli/cli.go index 1d1b3cf3a..49912d887 100644 --- a/cmd/syft/cli/cli.go +++ b/cmd/syft/cli/cli.go @@ -48,6 +48,7 @@ func create(id clio.Identification, out io.Writer) (clio.Application, *cobra.Com commands.Attest(app), commands.Convert(app), clio.VersionCommand(id), + clio.ConfigCommand(app, nil), cranecmd.NewCmdAuthLogin(id.Name), // syft login uses the same command as crane ) diff --git a/cmd/syft/internal/options/attest.go b/cmd/syft/internal/options/attest.go index 7507ae36e..d22e32617 100644 --- a/cmd/syft/internal/options/attest.go +++ b/cmd/syft/internal/options/attest.go @@ -12,8 +12,16 @@ type Attest struct { Password secret `yaml:"password" json:"password" mapstructure:"password"` } -var _ clio.FlagAdder = (*Attest)(nil) +var _ interface { + clio.FlagAdder + clio.FieldDescriber +} = (*Attest)(nil) func (o *Attest) AddFlags(flags clio.FlagSet) { flags.StringVarP((*string)(&o.Key), "key", "k", "the key to use for the attestation") } + +func (o *Attest) DescribeFields(descriptions clio.FieldDescriptionSet) { + descriptions.Add(&o.Password, `password to decrypt to given private key +additionally responds to COSIGN_PASSWORD env var`) +} diff --git a/cmd/syft/internal/options/file.go b/cmd/syft/internal/options/file.go index ae628f078..6ac9c8d2b 100644 --- a/cmd/syft/internal/options/file.go +++ b/cmd/syft/internal/options/file.go @@ -6,6 +6,7 @@ import ( "github.com/scylladb/go-set/strset" + "github.com/anchore/clio" intFile "github.com/anchore/syft/internal/file" "github.com/anchore/syft/syft/file" ) @@ -45,6 +46,11 @@ func defaultFileConfig() fileConfig { } } +var _ interface { + clio.PostLoader + clio.FieldDescriber +} = (*fileConfig)(nil) + func (c *fileConfig) PostLoad() error { digests := strset.New(c.Metadata.Digests...).List() sort.Strings(digests) @@ -56,3 +62,17 @@ func (c *fileConfig) PostLoad() error { } return fmt.Errorf("invalid file metadata selection: %q", c.Metadata.Selection) } + +func (c *fileConfig) DescribeFields(descriptions clio.FieldDescriptionSet) { + descriptions.Add(&c.Metadata.Selection, `select which files should be captured by the file-metadata cataloger and included in the SBOM. +Options include: + - "all": capture all files from the search space + - "owned-by-package": capture only files owned by packages + - "none", "": do not capture any files`) + descriptions.Add(&c.Metadata.Digests, `the file digest algorithms to use when cataloging files (options: "md5", "sha1", "sha224", "sha256", "sha384", "sha512")`) + + descriptions.Add(&c.Content.SkipFilesAboveSize, `skip searching a file entirely if it is above the given size (default = 1MB; unit = bytes)`) + descriptions.Add(&c.Content.Globs, `file globs for the cataloger to match on`) + + descriptions.Add(&c.Executable.Globs, `file globs for the cataloger to match on`) +} diff --git a/cmd/syft/internal/options/format.go b/cmd/syft/internal/options/format.go index 0f4134165..4ff1e9934 100644 --- a/cmd/syft/internal/options/format.go +++ b/cmd/syft/internal/options/format.go @@ -7,16 +7,19 @@ import ( "github.com/anchore/syft/syft/sbom" ) -var _ clio.PostLoader = (*Format)(nil) +var _ interface { + clio.PostLoader + clio.FieldDescriber +} = (*Format)(nil) // Format contains all user configuration for output formatting. type Format struct { Pretty *bool `yaml:"pretty" json:"pretty" mapstructure:"pretty"` - Template FormatTemplate `yaml:"template" json:"template" mapstructure:"template"` - SyftJSON FormatSyftJSON `yaml:"json" json:"json" mapstructure:"json"` - SPDXJSON FormatSPDXJSON `yaml:"spdx-json" json:"spdx-json" mapstructure:"spdx-json"` - CyclonedxJSON FormatCyclonedxJSON `yaml:"cyclonedx-json" json:"cyclonedx-json" mapstructure:"cyclonedx-json"` - CyclonedxXML FormatCyclonedxXML `yaml:"cyclonedx-xml" json:"cyclonedx-xml" mapstructure:"cyclonedx-xml"` + Template FormatTemplate `yaml:"template" json:"template" mapstructure:"template" description:"all template format options"` + SyftJSON FormatSyftJSON `yaml:"json" json:"json" mapstructure:"json" description:"all syft-json format options"` + SPDXJSON FormatSPDXJSON `yaml:"spdx-json" json:"spdx-json" mapstructure:"spdx-json" description:"all spdx-json format options"` + CyclonedxJSON FormatCyclonedxJSON `yaml:"cyclonedx-json" json:"cyclonedx-json" mapstructure:"cyclonedx-json" description:"all cyclonedx-json format options"` + CyclonedxXML FormatCyclonedxXML `yaml:"cyclonedx-xml" json:"cyclonedx-xml" mapstructure:"cyclonedx-xml" description:"all cyclonedx-xml format options"` } func (o *Format) PostLoad() error { @@ -28,6 +31,33 @@ func (o *Format) PostLoad() error { return nil } +func (o *Format) DescribeFields(descriptions clio.FieldDescriptionSet) { + descriptions.Add(&o.Pretty, `default value for all formats that support the "pretty" option (default is unset)`) + descriptions.Add(&o.SyftJSON, `all syft-json format options`) + descriptions.Add(&o.SyftJSON.Legacy, `transform any syft-json output to conform to an approximation of the v11.0.1 schema. This includes: +- using the package metadata type names from before v12 of the JSON schema (changed in https://github.com/anchore/syft/pull/1983) + +Note: this will still include package types and fields that were added at or after json schema v12. This means +that output might not strictly be json schema v11 compliant, however, for consumers that require time to port +over to the final syft 1.0 json output this option can be used to ease the transition. + +Note: long term support for this option is not guaranteed (it may change or break at any time)`) + + descriptions.Add(&o.Template.Path, `path to the template file to use when rendering the output with the template output format. +Note that all template paths are based on the current syft-json schema`) + descriptions.Add(&o.Template.Legacy, `if true, uses the go structs for the syft-json format for templating. +if false, uses the syft-json output for templating (which follows the syft JSON schema exactly). + +Note: long term support for this option is not guaranteed (it may change or break at any time)`) + + prettyDescription := `include space indention and newlines +note: inherits default value from 'format.pretty' or 'false' if parent is unset` + descriptions.Add(&o.SyftJSON.Pretty, prettyDescription) + descriptions.Add(&o.SPDXJSON.Pretty, prettyDescription) + descriptions.Add(&o.CyclonedxJSON.Pretty, prettyDescription) + descriptions.Add(&o.CyclonedxXML.Pretty, prettyDescription) +} + func DefaultFormat() Format { return Format{ Template: DefaultFormatTemplate(), diff --git a/cmd/syft/internal/options/golang.go b/cmd/syft/internal/options/golang.go index a4121eda0..63ac1bcc7 100644 --- a/cmd/syft/internal/options/golang.go +++ b/cmd/syft/internal/options/golang.go @@ -3,6 +3,7 @@ package options import ( "strings" + "github.com/anchore/clio" "github.com/anchore/syft/syft/pkg/cataloger/golang" ) @@ -15,6 +16,28 @@ type golangConfig struct { MainModuleVersion golangMainModuleVersionConfig `json:"main-module-version" yaml:"main-module-version" mapstructure:"main-module-version"` } +var _ interface { + clio.FieldDescriber +} = (*golangConfig)(nil) + +func (o *golangConfig) DescribeFields(descriptions clio.FieldDescriptionSet) { + descriptions.Add(&o.SearchLocalModCacheLicenses, `search for go package licences in the GOPATH of the system running Syft, note that this is outside the +container filesystem and potentially outside the root of a local directory scan`) + descriptions.Add(&o.LocalModCacheDir, `specify an explicit go mod cache directory, if unset this defaults to $GOPATH/pkg/mod or $HOME/go/pkg/mod`) + descriptions.Add(&o.SearchRemoteLicenses, `search for go package licences by retrieving the package from a network proxy`) + descriptions.Add(&o.Proxy, `remote proxy to use when retrieving go packages from the network, +if unset this defaults to $GOPROXY followed by https://proxy.golang.org`) + descriptions.Add(&o.NoProxy, `specifies packages which should not be fetched by proxy +if unset this defaults to $GONOPROXY`) + descriptions.Add(&o.MainModuleVersion, `the go main module version discovered from binaries built with the go compiler will +always show (devel) as the version. Use these options to control heuristics to guess +a more accurate version from the binary.`) + descriptions.Add(&o.MainModuleVersion.FromLDFlags, `look for LD flags that appear to be setting a version (e.g. -X main.version=1.0.0)`) + descriptions.Add(&o.MainModuleVersion.FromBuildSettings, `use the build settings (e.g. vcs.version & vcs.time) to craft a v0 pseudo version +(e.g. v0.0.0-20220308212642-53e6d0aaf6fb) when a more accurate version cannot be found otherwise`) + descriptions.Add(&o.MainModuleVersion.FromContents, `search for semver-like strings in the binary contents`) +} + type golangMainModuleVersionConfig struct { FromLDFlags bool `json:"from-ld-flags" yaml:"from-ld-flags" mapstructure:"from-ld-flags"` FromContents bool `json:"from-contents" yaml:"from-contents" mapstructure:"from-contents"` diff --git a/cmd/syft/internal/options/java.go b/cmd/syft/internal/options/java.go index 342954068..79b0fd127 100644 --- a/cmd/syft/internal/options/java.go +++ b/cmd/syft/internal/options/java.go @@ -1,7 +1,24 @@ package options +import "github.com/anchore/clio" + type javaConfig struct { UseNetwork bool `yaml:"use-network" json:"use-network" mapstructure:"use-network"` MavenURL string `yaml:"maven-url" json:"maven-url" mapstructure:"maven-url"` MaxParentRecursiveDepth int `yaml:"max-parent-recursive-depth" json:"max-parent-recursive-depth" mapstructure:"max-parent-recursive-depth"` } + +var _ interface { + clio.FieldDescriber +} = (*javaConfig)(nil) + +func (o *javaConfig) DescribeFields(descriptions clio.FieldDescriptionSet) { + descriptions.Add(&o.UseNetwork, `enables Syft to use the network to fill in more detailed information about artifacts +currently this enables searching maven-url for license data +when running across pom.xml files that could have more information, syft will +explicitly search maven for license information by querying the online pom when this is true +this option is helpful for when the parent pom has more data, +that is not accessible from within the final built artifact`) + descriptions.Add(&o.MavenURL, `maven repository to use, defaults to Maven central`) + descriptions.Add(&o.MaxParentRecursiveDepth, `depth to recursively resolve parent POMs`) +} diff --git a/cmd/syft/internal/options/javascript.go b/cmd/syft/internal/options/javascript.go index 353b19003..5f88c0f33 100644 --- a/cmd/syft/internal/options/javascript.go +++ b/cmd/syft/internal/options/javascript.go @@ -1,6 +1,17 @@ package options +import "github.com/anchore/clio" + type javaScriptConfig struct { SearchRemoteLicenses bool `json:"search-remote-licenses" yaml:"search-remote-licenses" mapstructure:"search-remote-licenses"` NpmBaseURL string `json:"npm-base-url" yaml:"npm-base-url" mapstructure:"npm-base-url"` } + +var _ interface { + clio.FieldDescriber +} = (*javaScriptConfig)(nil) + +func (o *javaScriptConfig) DescribeFields(descriptions clio.FieldDescriptionSet) { + descriptions.Add(&o.SearchRemoteLicenses, `enables Syft to use the network to fill in more detailed license information`) + descriptions.Add(&o.NpmBaseURL, `base NPM url to use`) +} diff --git a/cmd/syft/internal/options/linux_kernel.go b/cmd/syft/internal/options/linux_kernel.go index ac6adff2a..03f24dbf0 100644 --- a/cmd/syft/internal/options/linux_kernel.go +++ b/cmd/syft/internal/options/linux_kernel.go @@ -1,5 +1,7 @@ package options +import "github.com/anchore/clio" + type linuxKernelConfig struct { CatalogModules bool `json:"catalog-modules" yaml:"catalog-modules" mapstructure:"catalog-modules"` } @@ -9,3 +11,11 @@ func defaultLinuxKernelConfig() linuxKernelConfig { CatalogModules: true, } } + +var _ interface { + clio.FieldDescriber +} = (*linuxKernelConfig)(nil) + +func (o *linuxKernelConfig) DescribeFields(descriptions clio.FieldDescriptionSet) { + descriptions.Add(&o.CatalogModules, `whether to catalog linux kernel modules found within lib/modules/** directories`) +} diff --git a/cmd/syft/internal/options/output.go b/cmd/syft/internal/options/output.go index 961698d1c..ab51887e0 100644 --- a/cmd/syft/internal/options/output.go +++ b/cmd/syft/internal/options/output.go @@ -24,6 +24,7 @@ import ( var _ interface { clio.FlagAdder clio.PostLoader + clio.FieldDescriber } = (*Output)(nil) // Output has the standard output options syft accepts: multiple -o, --file, --template @@ -70,6 +71,15 @@ func (o *Output) AddFlags(flags clio.FlagSet) { fmt.Sprintf("report output format (= to output to a file), formats=%v", names)) } +func (o *Output) DescribeFields(descriptions clio.FieldDescriptionSet) { + descriptions.Add(&o.Outputs, `the output format(s) of the SBOM report (options: syft-table, syft-text, syft-json, spdx-json, ...) +to specify multiple output files in differing formats, use a list: +output: + - "syft-json=" + - "spdx-json=" +`) +} + func (o Output) SBOMWriter() (sbom.Writer, error) { names := o.OutputNameSet() diff --git a/cmd/syft/internal/options/pkg.go b/cmd/syft/internal/options/pkg.go index e384e5680..b15104d99 100644 --- a/cmd/syft/internal/options/pkg.go +++ b/cmd/syft/internal/options/pkg.go @@ -1,6 +1,9 @@ package options -import "github.com/anchore/syft/syft/cataloging" +import ( + "github.com/anchore/clio" + "github.com/anchore/syft/syft/cataloging" +) type packageConfig struct { SearchUnindexedArchives bool `yaml:"search-unindexed-archives" json:"search-unindexed-archives" mapstructure:"search-unindexed-archives"` @@ -8,6 +11,20 @@ type packageConfig struct { ExcludeBinaryOverlapByOwnership bool `yaml:"exclude-binary-overlap-by-ownership" json:"exclude-binary-overlap-by-ownership" mapstructure:"exclude-binary-overlap-by-ownership"` // exclude synthetic binary packages owned by os package files } +var _ interface { + clio.FieldDescriber +} = (*packageConfig)(nil) + +func (o *packageConfig) DescribeFields(descriptions clio.FieldDescriptionSet) { + descriptions.Add(&o.SearchUnindexedArchives, `search within archives that do contain a file index to search against (zip) +note: for now this only applies to the java package cataloger`) + descriptions.Add(&o.SearchIndexedArchives, `search within archives that do not contain a file index to search against (tar, tar.gz, tar.bz2, etc) +note: enabling this may result in a performance impact since all discovered compressed tars will be decompressed +note: for now this only applies to the java package cataloger`) + descriptions.Add(&o.ExcludeBinaryOverlapByOwnership, `allows users to exclude synthetic binary packages from the sbom +these packages are removed if an overlap with a non-synthetic package is found`) +} + func defaultPackageConfig() packageConfig { c := cataloging.DefaultArchiveSearchConfig() return packageConfig{ diff --git a/cmd/syft/internal/options/python.go b/cmd/syft/internal/options/python.go index 26b36c99a..c645cbfcd 100644 --- a/cmd/syft/internal/options/python.go +++ b/cmd/syft/internal/options/python.go @@ -1,5 +1,18 @@ package options +import "github.com/anchore/clio" + type pythonConfig struct { GuessUnpinnedRequirements bool `json:"guess-unpinned-requirements" yaml:"guess-unpinned-requirements" mapstructure:"guess-unpinned-requirements"` } + +var _ interface { + clio.FieldDescriber +} = (*pythonConfig)(nil) + +func (o *pythonConfig) DescribeFields(descriptions clio.FieldDescriptionSet) { + descriptions.Add(&o.GuessUnpinnedRequirements, `when running across entries in requirements.txt that do not specify a specific version +(e.g. "sqlalchemy >= 1.0.0, <= 2.0.0, != 3.0.0, <= 3.0.0"), attempt to guess what the version could +be based on the version requirements specified (e.g. "1.0.0"). When enabled the lowest expressible version +when given an arbitrary constraint will be used (even if that version may not be available/published).`) +} diff --git a/cmd/syft/internal/options/registry.go b/cmd/syft/internal/options/registry.go index 2ea23653c..fc0a80d53 100644 --- a/cmd/syft/internal/options/registry.go +++ b/cmd/syft/internal/options/registry.go @@ -25,7 +25,10 @@ type registryConfig struct { CACert string `yaml:"ca-cert" json:"ca-cert" mapstructure:"ca-cert"` } -var _ clio.PostLoader = (*registryConfig)(nil) +var _ interface { + clio.PostLoader + clio.FieldDescriber +} = (*registryConfig)(nil) func (cfg *registryConfig) PostLoad() error { // there may be additional credentials provided by env var that should be appended to the set of credentials @@ -55,6 +58,20 @@ func (cfg *registryConfig) PostLoad() error { return nil } +func (cfg *registryConfig) DescribeFields(descriptions clio.FieldDescriptionSet) { + descriptions.Add(&cfg.InsecureSkipTLSVerify, "skip TLS verification when communicating with the registry") + descriptions.Add(&cfg.InsecureUseHTTP, "use http instead of https when connecting to the registry") + descriptions.Add(&cfg.CACert, "filepath to a CA certificate (or directory containing *.crt, *.cert, *.pem) used to generate the client certificate") + descriptions.Add(&cfg.Auth, `Authentication credentials for specific registries. Each entry describes authentication for a specific authority: +- authority: the registry authority URL the URL to the registry (e.g. "docker.io", "localhost:5000", etc.) (env: SYFT_REGISTRY_AUTH_AUTHORITY) + username: a username if using basic credentials (env: SYFT_REGISTRY_AUTH_USERNAME) + password: a corresponding password (env: SYFT_REGISTRY_AUTH_PASSWORD) + token: a token if using token-based authentication, mutually exclusive with username/password (env: SYFT_REGISTRY_AUTH_TOKEN) + tls-cert: filepath to the client certificate used for TLS authentication to the registry (env: SYFT_REGISTRY_AUTH_TLS_CERT) + tls-key: filepath to the client key used for TLS authentication to the registry (env: SYFT_REGISTRY_AUTH_TLS_KEY) +`) +} + func hasNonEmptyCredentials(username, password, token, tlsCert, tlsKey string) bool { hasUserPass := username != "" && password != "" hasToken := token != "" diff --git a/cmd/syft/internal/options/relationships.go b/cmd/syft/internal/options/relationships.go index 5bc491b85..bb2afa5c7 100644 --- a/cmd/syft/internal/options/relationships.go +++ b/cmd/syft/internal/options/relationships.go @@ -17,6 +17,6 @@ func defaultRelationshipsConfig() relationshipsConfig { } func (r *relationshipsConfig) DescribeFields(descriptions fangs.FieldDescriptionSet) { - descriptions.Add(&r.PackageFileOwnership, "include package-to-file relationships that indicate which files are owned by which packages.") - descriptions.Add(&r.PackageFileOwnershipOverlap, "include package-to-package relationships that indicate one package is owned by another due to files claimed to be owned by one package are also evidence of another package's existence.") + descriptions.Add(&r.PackageFileOwnership, "include package-to-file relationships that indicate which files are owned by which packages") + descriptions.Add(&r.PackageFileOwnershipOverlap, "include package-to-package relationships that indicate one package is owned by another due to files claimed to be owned by one package are also evidence of another package's existence") } diff --git a/cmd/syft/internal/options/source.go b/cmd/syft/internal/options/source.go index 3766ce592..fcc81bd31 100644 --- a/cmd/syft/internal/options/source.go +++ b/cmd/syft/internal/options/source.go @@ -7,6 +7,7 @@ import ( "github.com/scylladb/go-set/strset" + "github.com/anchore/clio" "github.com/anchore/syft/syft/source/sourceproviders" ) @@ -22,6 +23,16 @@ type fileSource struct { Digests []string `json:"digests" yaml:"digests" mapstructure:"digests"` } +var _ interface { + clio.FieldDescriber +} = (*sourceConfig)(nil) + +func (o *sourceConfig) DescribeFields(descriptions clio.FieldDescriptionSet) { + descriptions.Add(&o.File.Digests, `the file digest algorithms to use on the scanned file (options: "md5", "sha1", "sha224", "sha256", "sha384", "sha512")`) + descriptions.Add(&o.Image.DefaultPullSource, `allows users to specify which image source should be used to generate the sbom +valid values are: registry, docker, podman`) +} + type imageSource struct { DefaultPullSource string `json:"default-pull-source" yaml:"default-pull-source" mapstructure:"default-pull-source"` } diff --git a/go.mod b/go.mod index 77dfbc714..32038aaad 100644 --- a/go.mod +++ b/go.mod @@ -9,8 +9,8 @@ require ( github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d github.com/acobaugh/osrelease v0.1.0 github.com/anchore/bubbly v0.0.0-20231115134915-def0aba654a9 - github.com/anchore/clio v0.0.0-20240209204744-cb94e40a4f65 - github.com/anchore/fangs v0.0.0-20231201140849-5075d28d6d8b + github.com/anchore/clio v0.0.0-20240522144804-d81e109008aa + github.com/anchore/fangs v0.0.0-20240508143433-f016b099950f github.com/anchore/go-collections v0.0.0-20240216171411-9321230ce537 github.com/anchore/go-logger v0.0.0-20230725134548-c21dafa1ec5a github.com/anchore/go-macholibre v0.0.0-20220308212642-53e6d0aaf6fb @@ -129,7 +129,7 @@ require ( github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect github.com/felixge/fgprof v0.9.3 // indirect github.com/felixge/httpsnoop v1.0.3 // indirect - github.com/fsnotify/fsnotify v1.6.0 // indirect + github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/gabriel-vasile/mimetype v1.4.0 // indirect github.com/gkampitakis/ciinfo v0.3.0 // indirect github.com/gkampitakis/go-diff v1.3.2 // indirect @@ -189,7 +189,7 @@ require ( github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect github.com/rivo/uniseg v0.4.7 // indirect github.com/rogpeppe/go-internal v1.12.0 // indirect - github.com/sagikazarmark/locafero v0.3.0 // indirect + github.com/sagikazarmark/locafero v0.4.0 // indirect github.com/sagikazarmark/slog-shim v0.1.0 // indirect github.com/sahilm/fuzzy v0.1.1-0.20230530133925-c48e322e2a8f // indirect github.com/secDre4mer/pkcs7 v0.0.0-20240322103146-665324a4461d // indirect @@ -197,9 +197,9 @@ require ( github.com/sirupsen/logrus v1.9.3 // indirect github.com/skeema/knownhosts v1.2.2 // indirect github.com/sourcegraph/conc v0.3.0 // indirect - github.com/spf13/cast v1.5.1 // indirect + github.com/spf13/cast v1.6.0 // indirect github.com/spf13/pflag v1.0.5 // indirect - github.com/spf13/viper v1.17.0 // indirect + github.com/spf13/viper v1.18.2 // indirect github.com/subosito/gotenv v1.6.0 // indirect github.com/sylabs/sif/v2 v2.11.5 // indirect github.com/sylabs/squashfs v0.6.1 // indirect diff --git a/go.sum b/go.sum index 73677e451..e5ded7ade 100644 --- a/go.sum +++ b/go.sum @@ -93,10 +93,10 @@ github.com/anchore/archiver/v3 v3.5.2 h1:Bjemm2NzuRhmHy3m0lRe5tNoClB9A4zYyDV58Pa github.com/anchore/archiver/v3 v3.5.2/go.mod h1:e3dqJ7H78uzsRSEACH1joayhuSyhnonssnDhppzS1L4= github.com/anchore/bubbly v0.0.0-20231115134915-def0aba654a9 h1:p0ZIe0htYOX284Y4axJaGBvXHU0VCCzLN5Wf5XbKStU= github.com/anchore/bubbly v0.0.0-20231115134915-def0aba654a9/go.mod h1:3ZsFB9tzW3vl4gEiUeuSOMDnwroWxIxJelOOHUp8dSw= -github.com/anchore/clio v0.0.0-20240209204744-cb94e40a4f65 h1:u9XrEabKlGPsrmRvAER+kUKkwXiJfLyqGhmOTFsXjX4= -github.com/anchore/clio v0.0.0-20240209204744-cb94e40a4f65/go.mod h1:8Jr7CjmwFVcBPtkJdTpaAGHimoGJGfbExypjzOu87Og= -github.com/anchore/fangs v0.0.0-20231201140849-5075d28d6d8b h1:L/djgY7ZbZ/38+wUtdkk398W3PIBJLkt1N8nU/7e47A= -github.com/anchore/fangs v0.0.0-20231201140849-5075d28d6d8b/go.mod h1:TLcE0RE5+8oIx2/NPWem/dq1DeaMoC+fPEH7hoSzPLo= +github.com/anchore/clio v0.0.0-20240522144804-d81e109008aa h1:pwlAn4O9SBUnlgfa69YcqIynbUyobLVFYu8HxSoCffA= +github.com/anchore/clio v0.0.0-20240522144804-d81e109008aa/go.mod h1:nD3H5uIvjxlfmakOBgtyFQbk5Zjp3l538kxfpHPslzI= +github.com/anchore/fangs v0.0.0-20240508143433-f016b099950f h1:NOhzafCyNYFi88qxkBFjMzQo4dRa1vDhBzx+0Uovx8Q= +github.com/anchore/fangs v0.0.0-20240508143433-f016b099950f/go.mod h1:sVpRS2yNCw6tLVpvA1QSDVWTJVpCuAm8JNZgn4Sjz/k= github.com/anchore/go-collections v0.0.0-20240216171411-9321230ce537 h1:GjNGuwK5jWjJMyVppBjYS54eOiiSNv4Ba869k4wh72Q= github.com/anchore/go-collections v0.0.0-20240216171411-9321230ce537/go.mod h1:1aiktV46ATCkuVg0O573ZrH56BUawTECPETbZyBcqT8= github.com/anchore/go-logger v0.0.0-20230725134548-c21dafa1ec5a h1:nJ2G8zWKASyVClGVgG7sfM5mwoZlZ2zYpIzN2OhjWkw= @@ -269,11 +269,11 @@ github.com/felixge/fgprof v0.9.3 h1:VvyZxILNuCiUCSXtPtYmmtGvb65nqXh2QFWc0Wpf2/g= github.com/felixge/fgprof v0.9.3/go.mod h1:RdbpDgzqYVh/T9fPELJyV7EYJuHB55UTEULNun8eiPw= github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk= github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= -github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= -github.com/frankban/quicktest v1.14.4/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= +github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= +github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU= -github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= -github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= +github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= +github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= github.com/gabriel-vasile/mimetype v1.4.0 h1:Cn9dkdYsMIu56tGho+fqzh7XmvY2YyGU0FnbhiOsEro= github.com/gabriel-vasile/mimetype v1.4.0/go.mod h1:fA8fi6KUiG7MgQQ+mEWotXoEOvmxRtOJlERCzSmRvr8= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= @@ -677,8 +677,8 @@ github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb github.com/saferwall/pe v1.5.3 h1:tZ2KJWeJK6N2jjJx+B9hm+wq6qe0o56pql2PXUaQ9eI= github.com/saferwall/pe v1.5.3/go.mod h1:mJx+PuptmNpoPFBNhWs/uDMFL/kTHVZIkg0d4OUJFbQ= github.com/sagikazarmark/crypt v0.3.0/go.mod h1:uD/D+6UF4SrIR1uGEv7bBNkNqLGqUr43MRiaGWX1Nig= -github.com/sagikazarmark/locafero v0.3.0 h1:zT7VEGWC2DTflmccN/5T1etyKvxSxpHsjb9cJvm4SvQ= -github.com/sagikazarmark/locafero v0.3.0/go.mod h1:w+v7UsPNFwzF1cHuOajOOzoq4U7v/ig1mpRjqV+Bu1U= +github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ= +github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4= github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE= github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ= github.com/sahilm/fuzzy v0.1.1-0.20230530133925-c48e322e2a8f h1:MvTmaQdww/z0Q4wrYjDSCcZ78NoftLQyHBSLW/Cx79Y= @@ -724,8 +724,8 @@ github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8= github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY= github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cast v1.4.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= -github.com/spf13/cast v1.5.1 h1:R+kOtfhWQE6TVQzY+4D7wJLBgkdVasCEFxSUBYBYIlA= -github.com/spf13/cast v1.5.1/go.mod h1:b9PdjNptOpzXr7Rq1q9gJML/2cdGQAo69NKzQ10KN48= +github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0= +github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= github.com/spf13/cobra v1.3.0/go.mod h1:BrRVncBjOJa/eUcVVm9CE+oC6as8k+VYr4NY7WCi9V4= github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= @@ -733,8 +733,8 @@ github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0 github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.10.0/go.mod h1:SoyBPwAtKDzypXNDFKN5kzH7ppppbGZtls1UpIy5AsM= -github.com/spf13/viper v1.17.0 h1:I5txKw7MJasPL/BrfkbA0Jyo/oELqVmux4pR/UxOMfI= -github.com/spf13/viper v1.17.0/go.mod h1:BmMMMLQXSbcHK6KAOiFLz0l5JHrU89OdIRHvsk0+yVI= +github.com/spf13/viper v1.18.2 h1:LUXCnvUvSM6FXAsj6nnfc8Q2tp1dIgUfY9Kc8GsSOiQ= +github.com/spf13/viper v1.18.2/go.mod h1:EKmWIqdnk5lOcmR72yw6hS+8OPYcwD0jteitLMVB+yk= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= @@ -1066,7 +1066,6 @@ golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220906165534-d0df966e6959/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=