chore: update CLI to CLIO (#2001)

Signed-off-by: Keith Zantow <kzantow@gmail.com>
Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>
Co-authored-by: Alex Goodman <wagoodman@users.noreply.github.com>
This commit is contained in:
Keith Zantow
2023-08-29 15:52:26 -04:00
committed by GitHub
co-authored by Alex Goodman
parent b03e9c6868
commit 2b7a9d0be3
95 changed files with 1680 additions and 3192 deletions
+81
View File
@@ -0,0 +1,81 @@
package cli
import (
"os"
cranecmd "github.com/google/go-containerregistry/cmd/crane/cmd"
"github.com/anchore/clio"
"github.com/anchore/stereoscope"
"github.com/anchore/syft/cmd/syft/cli/commands"
handler "github.com/anchore/syft/cmd/syft/cli/ui"
"github.com/anchore/syft/cmd/syft/internal/ui"
"github.com/anchore/syft/internal/bus"
"github.com/anchore/syft/internal/log"
"github.com/anchore/syft/internal/redact"
)
// New constructs the `syft packages` command, aliases the root command to `syft packages`,
// and constructs the `syft power-user` command. It is also responsible for
// organizing flag usage and injecting the application config for each command.
// It also constructs the syft attest command and the syft version command.
// `RunE` is the earliest that the complete application configuration can be loaded.
func New(id clio.Identification) clio.Application {
clioCfg := clio.NewSetupConfig(id).
WithGlobalConfigFlag(). // add persistent -c <path> for reading an application config from
WithGlobalLoggingFlags(). // add persistent -v and -q flags tied to the logging config
WithConfigInRootHelp(). // --help on the root command renders the full application config in the help text
WithUIConstructor(
// select a UI based on the logging configuration and state of stdin (if stdin is a tty)
func(cfg clio.Config) ([]clio.UI, error) {
noUI := ui.None(cfg.Log.Quiet)
if !cfg.Log.AllowUI(os.Stdin) {
return []clio.UI{noUI}, nil
}
h := handler.New(handler.DefaultHandlerConfig())
return []clio.UI{
ui.New(h, false, cfg.Log.Quiet),
noUI,
}, nil
},
).
WithInitializers(
func(state *clio.State) error {
// clio is setting up and providing the bus, redact store, and logger to the application. Once loaded,
// we can hoist them into the internal packages for global use.
stereoscope.SetBus(state.Bus)
bus.Set(state.Bus)
redact.Set(state.RedactStore)
log.Set(state.Logger)
stereoscope.SetLogger(state.Logger)
return nil
},
).
WithPostRuns(func(state *clio.State, err error) {
stereoscope.Cleanup()
})
app := clio.New(*clioCfg)
// since root is aliased as the packages cmd we need to construct this command first
// we also need the command to have information about the `root` options because of this alias
packagesCmd := commands.Packages(app)
// rootCmd is currently an alias for the packages command
rootCmd := commands.Root(app, packagesCmd)
// add sub-commands
rootCmd.AddCommand(
packagesCmd,
commands.PowerUser(app),
commands.Attest(app),
commands.Convert(app),
clio.VersionCommand(id),
cranecmd.NewCmdAuthLogin(id.Name), // syft login uses the same command as crane
)
return app
}