mirror of
https://github.com/anchore/syft.git
synced 2026-02-13 19:16:43 +01:00
feat: source-version flag (#1859)
This commit is contained in:
parent
1bd9de9047
commit
79a955b1a9
@ -47,7 +47,7 @@ func Run(_ context.Context, app *config.Application, args []string) error {
|
|||||||
// could be an image or a directory, with or without a scheme
|
// could be an image or a directory, with or without a scheme
|
||||||
// TODO: validate that source is image
|
// TODO: validate that source is image
|
||||||
userInput := args[0]
|
userInput := args[0]
|
||||||
si, err := source.ParseInputWithName(userInput, app.Platform, app.Name, app.DefaultImagePullSource)
|
si, err := source.ParseInputWithNameVersion(userInput, app.Platform, app.SourceName, app.SourceVersion, app.DefaultImagePullSource)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("could not generate source input for packages command: %w", err)
|
return fmt.Errorf("could not generate source input for packages command: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -21,7 +21,8 @@ type PackagesOptions struct {
|
|||||||
Platform string
|
Platform string
|
||||||
Exclude []string
|
Exclude []string
|
||||||
Catalogers []string
|
Catalogers []string
|
||||||
Name string
|
SourceName string
|
||||||
|
SourceVersion string
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ Interface = (*PackagesOptions)(nil)
|
var _ Interface = (*PackagesOptions)(nil)
|
||||||
@ -48,7 +49,14 @@ func (o *PackagesOptions) AddFlags(cmd *cobra.Command, v *viper.Viper) error {
|
|||||||
cmd.Flags().StringArrayVarP(&o.Catalogers, "catalogers", "", nil,
|
cmd.Flags().StringArrayVarP(&o.Catalogers, "catalogers", "", nil,
|
||||||
"enable one or more package catalogers")
|
"enable one or more package catalogers")
|
||||||
|
|
||||||
cmd.Flags().StringVarP(&o.Name, "name", "", "",
|
cmd.Flags().StringVarP(&o.SourceName, "name", "", "",
|
||||||
|
"set the name of the target being analyzed")
|
||||||
|
cmd.Flags().Lookup("name").Deprecated = "use: source-name"
|
||||||
|
|
||||||
|
cmd.Flags().StringVarP(&o.SourceName, "source-name", "", "",
|
||||||
|
"set the name of the target being analyzed")
|
||||||
|
|
||||||
|
cmd.Flags().StringVarP(&o.SourceVersion, "source-version", "", "",
|
||||||
"set the name of the target being analyzed")
|
"set the name of the target being analyzed")
|
||||||
|
|
||||||
return bindPackageConfigOptions(cmd.Flags(), v)
|
return bindPackageConfigOptions(cmd.Flags(), v)
|
||||||
@ -78,6 +86,14 @@ func bindPackageConfigOptions(flags *pflag.FlagSet, v *viper.Viper) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err := v.BindPFlag("source-name", flags.Lookup("source-name")); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := v.BindPFlag("source-version", flags.Lookup("source-version")); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
if err := v.BindPFlag("output", flags.Lookup("output")); err != nil {
|
if err := v.BindPFlag("output", flags.Lookup("output")); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@ -42,7 +42,7 @@ func Run(_ context.Context, app *config.Application, args []string) error {
|
|||||||
|
|
||||||
// could be an image or a directory, with or without a scheme
|
// could be an image or a directory, with or without a scheme
|
||||||
userInput := args[0]
|
userInput := args[0]
|
||||||
si, err := source.ParseInputWithName(userInput, app.Platform, app.Name, app.DefaultImagePullSource)
|
si, err := source.ParseInputWithNameVersion(userInput, app.Platform, app.SourceName, app.SourceVersion, app.DefaultImagePullSource)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("could not generate source input for packages command: %w", err)
|
return fmt.Errorf("could not generate source input for packages command: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -47,7 +47,7 @@ func Run(_ context.Context, app *config.Application, args []string) error {
|
|||||||
}()
|
}()
|
||||||
|
|
||||||
userInput := args[0]
|
userInput := args[0]
|
||||||
si, err := source.ParseInputWithName(userInput, app.Platform, app.Name, app.DefaultImagePullSource)
|
si, err := source.ParseInputWithNameVersion(userInput, app.Platform, app.SourceName, app.SourceVersion, app.DefaultImagePullSource)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("could not generate source input for packages command: %w", err)
|
return fmt.Errorf("could not generate source input for packages command: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -61,6 +61,8 @@ type Application struct {
|
|||||||
Exclusions []string `yaml:"exclude" json:"exclude" mapstructure:"exclude"`
|
Exclusions []string `yaml:"exclude" json:"exclude" mapstructure:"exclude"`
|
||||||
Platform string `yaml:"platform" json:"platform" mapstructure:"platform"`
|
Platform string `yaml:"platform" json:"platform" mapstructure:"platform"`
|
||||||
Name string `yaml:"name" json:"name" mapstructure:"name"`
|
Name string `yaml:"name" json:"name" mapstructure:"name"`
|
||||||
|
SourceName string `yaml:"source-name" json:"source-name" mapstructure:"source-name"`
|
||||||
|
SourceVersion string `yaml:"source-version" json:"source-version" mapstructure:"source-version"`
|
||||||
Parallelism int `yaml:"parallelism" json:"parallelism" mapstructure:"parallelism"` // the number of catalog workers to run in parallel
|
Parallelism int `yaml:"parallelism" json:"parallelism" mapstructure:"parallelism"` // the number of catalog workers to run in parallel
|
||||||
DefaultImagePullSource string `yaml:"default-image-pull-source" json:"default-image-pull-source" mapstructure:"default-image-pull-source"` // specify default image pull source
|
DefaultImagePullSource string `yaml:"default-image-pull-source" json:"default-image-pull-source" mapstructure:"default-image-pull-source"` // specify default image pull source
|
||||||
}
|
}
|
||||||
@ -143,6 +145,13 @@ func (cfg *Application) parseConfigValues() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if cfg.Name != "" {
|
||||||
|
log.Warnf("name parameter is deprecated. please use: source-name. name will be removed in a future version")
|
||||||
|
if cfg.SourceName == "" {
|
||||||
|
cfg.SourceName = cfg.Name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// check for valid default source options
|
// check for valid default source options
|
||||||
// parse nested config options
|
// parse nested config options
|
||||||
// for each field in the configuration struct, see if the field implements the parser interface
|
// for each field in the configuration struct, see if the field implements the parser interface
|
||||||
|
|||||||
@ -8,4 +8,5 @@ type Metadata struct {
|
|||||||
Path string // the root path to be cataloged (directory only)
|
Path string // the root path to be cataloged (directory only)
|
||||||
Base string // the base path to be cataloged (directory only)
|
Base string // the base path to be cataloged (directory only)
|
||||||
Name string
|
Name string
|
||||||
|
Version string
|
||||||
}
|
}
|
||||||
|
|||||||
@ -48,6 +48,7 @@ type Input struct {
|
|||||||
Location string
|
Location string
|
||||||
Platform string
|
Platform string
|
||||||
Name string
|
Name string
|
||||||
|
Version string
|
||||||
}
|
}
|
||||||
|
|
||||||
// ParseInput generates a source Input that can be used as an argument to generate a new source
|
// ParseInput generates a source Input that can be used as an argument to generate a new source
|
||||||
@ -59,6 +60,12 @@ func ParseInput(userInput string, platform string) (*Input, error) {
|
|||||||
// ParseInputWithName generates a source Input that can be used as an argument to generate a new source
|
// ParseInputWithName generates a source Input that can be used as an argument to generate a new source
|
||||||
// from specific providers including a registry, with an explicit name.
|
// from specific providers including a registry, with an explicit name.
|
||||||
func ParseInputWithName(userInput string, platform, name, defaultImageSource string) (*Input, error) {
|
func ParseInputWithName(userInput string, platform, name, defaultImageSource string) (*Input, error) {
|
||||||
|
return ParseInputWithNameVersion(userInput, platform, name, "", defaultImageSource)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParseInputWithNameVersion generates a source Input that can be used as an argument to generate a new source
|
||||||
|
// from specific providers including a registry, with an explicit name and version.
|
||||||
|
func ParseInputWithNameVersion(userInput, platform, name, version, defaultImageSource string) (*Input, error) {
|
||||||
fs := afero.NewOsFs()
|
fs := afero.NewOsFs()
|
||||||
scheme, source, location, err := DetectScheme(fs, image.DetectSource, userInput)
|
scheme, source, location, err := DetectScheme(fs, image.DetectSource, userInput)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -97,6 +104,7 @@ func ParseInputWithName(userInput string, platform, name, defaultImageSource str
|
|||||||
Location: location,
|
Location: location,
|
||||||
Platform: platform,
|
Platform: platform,
|
||||||
Name: name,
|
Name: name,
|
||||||
|
Version: version,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -154,7 +162,7 @@ func generateImageSource(in Input, registryOptions *image.RegistryOptions) (*Sou
|
|||||||
return nil, cleanup, fmt.Errorf("could not fetch image %q: %w", in.Location, err)
|
return nil, cleanup, fmt.Errorf("could not fetch image %q: %w", in.Location, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
s, err := NewFromImageWithName(img, in.Location, in.Name)
|
s, err := NewFromImageWithNameVersion(img, in.Location, in.Name, in.Version)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, cleanup, fmt.Errorf("could not populate source with image: %w", err)
|
return nil, cleanup, fmt.Errorf("could not populate source with image: %w", err)
|
||||||
}
|
}
|
||||||
@ -251,7 +259,7 @@ func generateDirectorySource(fs afero.Fs, in Input) (*Source, func(), error) {
|
|||||||
return nil, func() {}, fmt.Errorf("given path is not a directory (path=%q): %w", in.Location, err)
|
return nil, func() {}, fmt.Errorf("given path is not a directory (path=%q): %w", in.Location, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
s, err := NewFromDirectoryWithName(in.Location, in.Name)
|
s, err := NewFromDirectoryWithNameVersion(in.Location, in.Name, in.Version)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, func() {}, fmt.Errorf("could not populate source from path=%q: %w", in.Location, err)
|
return nil, func() {}, fmt.Errorf("could not populate source from path=%q: %w", in.Location, err)
|
||||||
}
|
}
|
||||||
@ -269,7 +277,7 @@ func generateFileSource(fs afero.Fs, in Input) (*Source, func(), error) {
|
|||||||
return nil, func() {}, fmt.Errorf("given path is not a directory (path=%q): %w", in.Location, err)
|
return nil, func() {}, fmt.Errorf("given path is not a directory (path=%q): %w", in.Location, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
s, cleanupFn := NewFromFileWithName(in.Location, in.Name)
|
s, cleanupFn := NewFromFileWithNameVersion(in.Location, in.Name, in.Version)
|
||||||
|
|
||||||
return &s, cleanupFn, nil
|
return &s, cleanupFn, nil
|
||||||
}
|
}
|
||||||
@ -279,19 +287,20 @@ func NewFromDirectory(path string) (Source, error) {
|
|||||||
return NewFromDirectoryWithName(path, "")
|
return NewFromDirectoryWithName(path, "")
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewFromDirectory creates a new source object tailored to catalog a given filesystem directory recursively.
|
|
||||||
func NewFromDirectoryRoot(path string) (Source, error) {
|
|
||||||
return NewFromDirectoryRootWithName(path, "")
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewFromDirectoryWithName creates a new source object tailored to catalog a given filesystem directory recursively, with an explicitly provided name.
|
// NewFromDirectoryWithName creates a new source object tailored to catalog a given filesystem directory recursively, with an explicitly provided name.
|
||||||
func NewFromDirectoryWithName(path string, name string) (Source, error) {
|
func NewFromDirectoryWithName(path string, name string) (Source, error) {
|
||||||
|
return NewFromDirectoryWithNameVersion(path, name, "")
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewFromDirectoryWithNameVersion creates a new source object tailored to catalog a given filesystem directory recursively, with an explicitly provided name.
|
||||||
|
func NewFromDirectoryWithNameVersion(path string, name string, version string) (Source, error) {
|
||||||
s := Source{
|
s := Source{
|
||||||
mutex: &sync.Mutex{},
|
mutex: &sync.Mutex{},
|
||||||
Metadata: Metadata{
|
Metadata: Metadata{
|
||||||
Name: name,
|
Name: name,
|
||||||
Scheme: DirectoryScheme,
|
Version: version,
|
||||||
Path: path,
|
Scheme: DirectoryScheme,
|
||||||
|
Path: path,
|
||||||
},
|
},
|
||||||
path: path,
|
path: path,
|
||||||
}
|
}
|
||||||
@ -299,15 +308,26 @@ func NewFromDirectoryWithName(path string, name string) (Source, error) {
|
|||||||
return s, nil
|
return s, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewFromDirectoryRoot creates a new source object tailored to catalog a given filesystem directory recursively.
|
||||||
|
func NewFromDirectoryRoot(path string) (Source, error) {
|
||||||
|
return NewFromDirectoryRootWithName(path, "")
|
||||||
|
}
|
||||||
|
|
||||||
// NewFromDirectoryRootWithName creates a new source object tailored to catalog a given filesystem directory recursively, with an explicitly provided name.
|
// NewFromDirectoryRootWithName creates a new source object tailored to catalog a given filesystem directory recursively, with an explicitly provided name.
|
||||||
func NewFromDirectoryRootWithName(path string, name string) (Source, error) {
|
func NewFromDirectoryRootWithName(path string, name string) (Source, error) {
|
||||||
|
return NewFromDirectoryRootWithNameVersion(path, name, "")
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewFromDirectoryRootWithNameVersion creates a new source object tailored to catalog a given filesystem directory recursively, with an explicitly provided name.
|
||||||
|
func NewFromDirectoryRootWithNameVersion(path string, name string, version string) (Source, error) {
|
||||||
s := Source{
|
s := Source{
|
||||||
mutex: &sync.Mutex{},
|
mutex: &sync.Mutex{},
|
||||||
Metadata: Metadata{
|
Metadata: Metadata{
|
||||||
Name: name,
|
Name: name,
|
||||||
Scheme: DirectoryScheme,
|
Version: version,
|
||||||
Path: path,
|
Scheme: DirectoryScheme,
|
||||||
Base: path,
|
Path: path,
|
||||||
|
Base: path,
|
||||||
},
|
},
|
||||||
path: path,
|
path: path,
|
||||||
base: path,
|
base: path,
|
||||||
@ -323,14 +343,20 @@ func NewFromFile(path string) (Source, func()) {
|
|||||||
|
|
||||||
// NewFromFileWithName creates a new source object tailored to catalog a file, with an explicitly provided name.
|
// NewFromFileWithName creates a new source object tailored to catalog a file, with an explicitly provided name.
|
||||||
func NewFromFileWithName(path string, name string) (Source, func()) {
|
func NewFromFileWithName(path string, name string) (Source, func()) {
|
||||||
|
return NewFromFileWithNameVersion(path, name, "")
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewFromFileWithNameVersion creates a new source object tailored to catalog a file, with an explicitly provided name and version.
|
||||||
|
func NewFromFileWithNameVersion(path string, name string, version string) (Source, func()) {
|
||||||
analysisPath, cleanupFn := fileAnalysisPath(path)
|
analysisPath, cleanupFn := fileAnalysisPath(path)
|
||||||
|
|
||||||
s := Source{
|
s := Source{
|
||||||
mutex: &sync.Mutex{},
|
mutex: &sync.Mutex{},
|
||||||
Metadata: Metadata{
|
Metadata: Metadata{
|
||||||
Name: name,
|
Name: name,
|
||||||
Scheme: FileScheme,
|
Version: version,
|
||||||
Path: path,
|
Scheme: FileScheme,
|
||||||
|
Path: path,
|
||||||
},
|
},
|
||||||
path: analysisPath,
|
path: analysisPath,
|
||||||
}
|
}
|
||||||
@ -380,6 +406,12 @@ func NewFromImage(img *image.Image, userImageStr string) (Source, error) {
|
|||||||
// NewFromImageWithName creates a new source object tailored to catalog a given container image, relative to the
|
// NewFromImageWithName creates a new source object tailored to catalog a given container image, relative to the
|
||||||
// option given (e.g. all-layers, squashed, etc), with an explicit name.
|
// option given (e.g. all-layers, squashed, etc), with an explicit name.
|
||||||
func NewFromImageWithName(img *image.Image, userImageStr string, name string) (Source, error) {
|
func NewFromImageWithName(img *image.Image, userImageStr string, name string) (Source, error) {
|
||||||
|
return NewFromImageWithNameVersion(img, userImageStr, name, "")
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewFromImageWithNameVersion creates a new source object tailored to catalog a given container image, relative to the
|
||||||
|
// option given (e.g. all-layers, squashed, etc), with an explicit name and version.
|
||||||
|
func NewFromImageWithNameVersion(img *image.Image, userImageStr string, name string, version string) (Source, error) {
|
||||||
if img == nil {
|
if img == nil {
|
||||||
return Source{}, fmt.Errorf("no image given")
|
return Source{}, fmt.Errorf("no image given")
|
||||||
}
|
}
|
||||||
@ -388,6 +420,7 @@ func NewFromImageWithName(img *image.Image, userImageStr string, name string) (S
|
|||||||
Image: img,
|
Image: img,
|
||||||
Metadata: Metadata{
|
Metadata: Metadata{
|
||||||
Name: name,
|
Name: name,
|
||||||
|
Version: version,
|
||||||
Scheme: ImageScheme,
|
Scheme: ImageScheme,
|
||||||
ImageMetadata: NewImageMetadata(img, userImageStr),
|
ImageMetadata: NewImageMetadata(img, userImageStr),
|
||||||
},
|
},
|
||||||
|
|||||||
@ -125,7 +125,7 @@ func TestSetID(t *testing.T) {
|
|||||||
Path: "test-fixtures/image-simple",
|
Path: "test-fixtures/image-simple",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expected: artifact.ID("1b0dc351e6577b01"),
|
expected: artifact.ID("9ee9e786412d6ae5"),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user