improve config parsing + fix command deprecation warning

Signed-off-by: Alex Goodman <alex.goodman@anchore.com>
This commit is contained in:
Alex Goodman
2021-03-22 10:58:09 -04:00
parent b1b57f6ba6
commit f180d1c537
20 changed files with 179 additions and 131 deletions
+28 -17
View File
@@ -34,7 +34,7 @@ func init() {
}
// provided to disambiguate the root vs packages command, whichever is indicated by the cli args will be set here.
// TODO: when the root alias command is removed, this function (hack) can be removed
// TODO: when the root alias command is removed, this variable can be removed
var activeCmd *cobra.Command
func Execute() {
@@ -44,23 +44,28 @@ func Execute() {
}
}
// we must setup the config-cli bindings first before the application configuration is parsed. However, this cannot
// be done without determining what the primary command that the config options should be bound to since there are
// shared concerns (the root-packages alias).
func initCmdAliasBindings() {
// TODO: when the root alias command is removed, this function (hack) can be removed
// map of all commands except for root
commands := make(map[string]*cobra.Command)
for _, c := range rootCmd.Commands() {
name := strings.Split(c.Use, " ")[0]
commands[name] = c
}
activeCmd = rootCmd
for i, a := range os.Args {
if i == 0 {
// don't consider the bin
continue
}
if a == "packages" {
// this is positively the first subcommand directive, and is "packages"
activeCmd = packagesCmd
break
}
if !strings.HasPrefix("-", a) {
// this is the first non-switch provided and was not "packages"
break
// check to see if this argument may be a command
if c, exists := commands[a]; exists {
activeCmd = c
}
}
@@ -69,14 +74,20 @@ func initCmdAliasBindings() {
fmt.Fprintln(os.Stderr, color.New(color.Bold, color.Red).Sprintf("The root command is deprecated, please use the 'packages' subcommand"))
}
// note: we need to lazily bind config options since they are shared between both the root command
// and the packages command. Otherwise there will be global viper state that is in contention.
// See for more details: https://github.com/spf13/viper/issues/233 . Additionally, the bindings must occur BEFORE
// reading the application configuration, which implies that it must be an initializer (or rewrite the command
// initialization structure against typical patterns used with cobra, which is somewhat extreme for a
// temporary alias)
if err := bindConfigOptions(activeCmd.Flags()); err != nil {
panic(err)
if activeCmd == packagesCmd || activeCmd == rootCmd {
// note: we need to lazily bind config options since they are shared between both the root command
// and the packages command. Otherwise there will be global viper state that is in contention.
// See for more details: https://github.com/spf13/viper/issues/233 . Additionally, the bindings must occur BEFORE
// reading the application configuration, which implies that it must be an initializer (or rewrite the command
// initialization structure against typical patterns used with cobra, which is somewhat extreme for a
// temporary alias)
if err := bindConfigOptions(activeCmd.Flags()); err != nil {
panic(err)
}
} else {
if err := bindConfigOptions(packagesCmd.Flags()); err != nil {
panic(err)
}
}
}
+4 -4
View File
@@ -141,7 +141,7 @@ func setPackageFlags(flags *pflag.FlagSet) {
func bindConfigOptions(flags *pflag.FlagSet) error {
///////// Formatting & Input options //////////////////////////////////////////////
if err := viper.BindPFlag("packages.scope", flags.Lookup("scope")); err != nil {
if err := viper.BindPFlag("package.cataloger.scope", flags.Lookup("scope")); err != nil {
return err
}
@@ -194,14 +194,14 @@ func packagesExecWorker(userInput string) <-chan error {
}
defer cleanup()
catalog, d, err := syft.CatalogPackages(src, appConfig.Packages.ScopeOpt)
catalog, d, err := syft.CatalogPackages(src, appConfig.Package.Cataloger.ScopeOpt)
if err != nil {
errs <- fmt.Errorf("failed to catalog input: %+v", err)
return
}
if appConfig.Anchore.Host != "" {
if err := runPackageSbomUpload(src, src.Metadata, catalog, d, appConfig.Packages.ScopeOpt); err != nil {
if err := runPackageSbomUpload(src, src.Metadata, catalog, d, appConfig.Package.Cataloger.ScopeOpt); err != nil {
errs <- err
return
}
@@ -213,7 +213,7 @@ func packagesExecWorker(userInput string) <-chan error {
SourceMetadata: src.Metadata,
Catalog: catalog,
Distro: d,
Scope: appConfig.Packages.ScopeOpt,
Scope: appConfig.Package.Cataloger.ScopeOpt,
}),
})
}()
+15 -3
View File
@@ -3,6 +3,8 @@ package cmd
import (
"fmt"
"github.com/anchore/syft/internal"
"github.com/anchore/syft/internal/bus"
"github.com/anchore/syft/internal/presenter/poweruser"
"github.com/anchore/syft/internal/ui"
@@ -13,14 +15,24 @@ import (
"github.com/wagoodman/go-partybus"
)
const powerUserExample = ` {{.appName}} {{.command}} <image>
Only image sources are supported (e.g. docker: , docker-archive: , oci: , etc.), the directory source (dir:) is not supported.
All behavior is controlled via application configuration and environment variables (see https://github.com/anchore/syft#configuration)
`
var powerUserOpts = struct {
configPath string
}{}
var powerUserCmd = &cobra.Command{
Use: "power-user [SOURCE]",
Short: "Run bulk operations on container images",
Example: ` {{.appName}} power-user <image>`,
Use: "power-user [IMAGE]",
Short: "Run bulk operations on container images",
Example: internal.Tprintf(powerUserExample, map[string]interface{}{
"appName": internal.ApplicationName,
"command": "power-user",
}),
Args: cobra.ExactArgs(1),
Hidden: true,
SilenceUsage: true,
+6 -6
View File
@@ -37,12 +37,12 @@ func powerUserTasks(src source.Source) ([]powerUserTask, error) {
}
func catalogPackagesTask(src source.Source) powerUserTask {
if !appConfig.Packages.CatalogingEnabled {
if !appConfig.Package.Cataloger.Enabled {
return nil
}
task := func(results *poweruser.JSONDocumentConfig) error {
packageCatalog, theDistro, err := syft.CatalogPackages(src, appConfig.Packages.ScopeOpt)
packageCatalog, theDistro, err := syft.CatalogPackages(src, appConfig.Package.Cataloger.ScopeOpt)
if err != nil {
return err
}
@@ -57,11 +57,11 @@ func catalogPackagesTask(src source.Source) powerUserTask {
}
func catalogFileMetadataTask(src source.Source) (powerUserTask, error) {
if !appConfig.FileMetadata.CatalogingEnabled {
if !appConfig.FileMetadata.Cataloger.Enabled {
return nil, nil
}
resolver, err := src.FileResolver(appConfig.FileMetadata.ScopeOpt)
resolver, err := src.FileResolver(appConfig.FileMetadata.Cataloger.ScopeOpt)
if err != nil {
return nil, err
}
@@ -79,11 +79,11 @@ func catalogFileMetadataTask(src source.Source) (powerUserTask, error) {
}
func catalogFileDigestTask(src source.Source) (powerUserTask, error) {
if !appConfig.FileMetadata.CatalogingEnabled {
if !appConfig.FileMetadata.Cataloger.Enabled {
return nil, nil
}
resolver, err := src.FileResolver(appConfig.FileMetadata.ScopeOpt)
resolver, err := src.FileResolver(appConfig.FileMetadata.Cataloger.ScopeOpt)
if err != nil {
return nil, err
}