diff --git a/cli-plugins/manager/cobra.go b/cli-plugins/manager/cobra.go index 73dcc9cce1..756ede944d 100644 --- a/cli-plugins/manager/cobra.go +++ b/cli-plugins/manager/cobra.go @@ -5,7 +5,7 @@ import ( "os" "sync" - "github.com/docker/cli/cli/command" + "github.com/docker/cli/cli/config" "github.com/spf13/cobra" ) @@ -41,10 +41,10 @@ var pluginCommandStubsOnce sync.Once // AddPluginCommandStubs adds a stub cobra.Commands for each valid and invalid // plugin. The command stubs will have several annotations added, see // `CommandAnnotationPlugin*`. -func AddPluginCommandStubs(dockerCli command.Cli, rootCmd *cobra.Command) (err error) { +func AddPluginCommandStubs(dockerCLI config.Provider, rootCmd *cobra.Command) (err error) { pluginCommandStubsOnce.Do(func() { var plugins []Plugin - plugins, err = ListPlugins(dockerCli, rootCmd) + plugins, err = ListPlugins(dockerCLI, rootCmd) if err != nil { return } @@ -86,7 +86,7 @@ func AddPluginCommandStubs(dockerCli command.Cli, rootCmd *cobra.Command) (err e cargs = append(cargs, args...) cargs = append(cargs, toComplete) os.Args = cargs - runCommand, runErr := PluginRunCommand(dockerCli, p.Name, cmd) + runCommand, runErr := PluginRunCommand(dockerCLI, p.Name, cmd) if runErr != nil { return nil, cobra.ShellCompDirectiveError } diff --git a/cli-plugins/manager/hooks.go b/cli-plugins/manager/hooks.go index 5125c56d06..b92dab4301 100644 --- a/cli-plugins/manager/hooks.go +++ b/cli-plugins/manager/hooks.go @@ -6,7 +6,8 @@ import ( "strings" "github.com/docker/cli/cli-plugins/hooks" - "github.com/docker/cli/cli/command" + "github.com/docker/cli/cli/config" + "github.com/docker/cli/cli/config/configfile" "github.com/sirupsen/logrus" "github.com/spf13/cobra" "github.com/spf13/pflag" @@ -29,29 +30,28 @@ type HookPluginData struct { // a main CLI command was executed. It calls the hook subcommand for all // present CLI plugins that declare support for hooks in their metadata and // parses/prints their responses. -func RunCLICommandHooks(ctx context.Context, dockerCli command.Cli, rootCmd, subCommand *cobra.Command, cmdErrorMessage string) { +func RunCLICommandHooks(ctx context.Context, dockerCLI config.Provider, rootCmd, subCommand *cobra.Command, cmdErrorMessage string) { commandName := strings.TrimPrefix(subCommand.CommandPath(), rootCmd.Name()+" ") flags := getCommandFlags(subCommand) - runHooks(ctx, dockerCli, rootCmd, subCommand, commandName, flags, cmdErrorMessage) + runHooks(ctx, dockerCLI.ConfigFile(), rootCmd, subCommand, commandName, flags, cmdErrorMessage) } // RunPluginHooks is the entrypoint for the hooks execution flow // after a plugin command was just executed by the CLI. -func RunPluginHooks(ctx context.Context, dockerCli command.Cli, rootCmd, subCommand *cobra.Command, args []string) { +func RunPluginHooks(ctx context.Context, dockerCLI config.Provider, rootCmd, subCommand *cobra.Command, args []string) { commandName := strings.Join(args, " ") flags := getNaiveFlags(args) - runHooks(ctx, dockerCli, rootCmd, subCommand, commandName, flags, "") + runHooks(ctx, dockerCLI.ConfigFile(), rootCmd, subCommand, commandName, flags, "") } -func runHooks(ctx context.Context, dockerCli command.Cli, rootCmd, subCommand *cobra.Command, invokedCommand string, flags map[string]string, cmdErrorMessage string) { - nextSteps := invokeAndCollectHooks(ctx, dockerCli, rootCmd, subCommand, invokedCommand, flags, cmdErrorMessage) - - hooks.PrintNextSteps(dockerCli.Err(), nextSteps) +func runHooks(ctx context.Context, cfg *configfile.ConfigFile, rootCmd, subCommand *cobra.Command, invokedCommand string, flags map[string]string, cmdErrorMessage string) { + nextSteps := invokeAndCollectHooks(ctx, cfg, rootCmd, subCommand, invokedCommand, flags, cmdErrorMessage) + hooks.PrintNextSteps(subCommand.ErrOrStderr(), nextSteps) } -func invokeAndCollectHooks(ctx context.Context, dockerCli command.Cli, rootCmd, subCmd *cobra.Command, subCmdStr string, flags map[string]string, cmdErrorMessage string) []string { +func invokeAndCollectHooks(ctx context.Context, cfg *configfile.ConfigFile, rootCmd, subCmd *cobra.Command, subCmdStr string, flags map[string]string, cmdErrorMessage string) []string { // check if the context was cancelled before invoking hooks select { case <-ctx.Done(): @@ -59,11 +59,15 @@ func invokeAndCollectHooks(ctx context.Context, dockerCli command.Cli, rootCmd, default: } - pluginsCfg := dockerCli.ConfigFile().Plugins + pluginsCfg := cfg.Plugins if pluginsCfg == nil { return nil } + pluginDirs, err := getPluginDirs(cfg) + if err != nil { + return nil + } nextSteps := make([]string, 0, len(pluginsCfg)) for pluginName, cfg := range pluginsCfg { match, ok := pluginMatch(cfg, subCmdStr) @@ -71,7 +75,7 @@ func invokeAndCollectHooks(ctx context.Context, dockerCli command.Cli, rootCmd, continue } - p, err := GetPlugin(pluginName, dockerCli, rootCmd) + p, err := getPlugin(pluginName, pluginDirs, rootCmd) if err != nil { continue } diff --git a/cli-plugins/manager/manager.go b/cli-plugins/manager/manager.go index 91eeed19a4..0f15daa29d 100644 --- a/cli-plugins/manager/manager.go +++ b/cli-plugins/manager/manager.go @@ -9,7 +9,6 @@ import ( "strings" "sync" - "github.com/docker/cli/cli/command" "github.com/docker/cli/cli/config" "github.com/docker/cli/cli/config/configfile" "github.com/fvbommel/sortorder" @@ -115,12 +114,15 @@ func listPluginCandidates(dirs []string) map[string][]string { } // GetPlugin returns a plugin on the system by its name -func GetPlugin(name string, dockerCli command.Cli, rootcmd *cobra.Command) (*Plugin, error) { - pluginDirs, err := getPluginDirs(dockerCli.ConfigFile()) +func GetPlugin(name string, dockerCLI config.Provider, rootcmd *cobra.Command) (*Plugin, error) { + pluginDirs, err := getPluginDirs(dockerCLI.ConfigFile()) if err != nil { return nil, err } + return getPlugin(name, pluginDirs, rootcmd) +} +func getPlugin(name string, pluginDirs []string, rootcmd *cobra.Command) (*Plugin, error) { candidates := listPluginCandidates(pluginDirs) if paths, ok := candidates[name]; ok { if len(paths) == 0 { @@ -141,7 +143,7 @@ func GetPlugin(name string, dockerCli command.Cli, rootcmd *cobra.Command) (*Plu } // ListPlugins produces a list of the plugins available on the system -func ListPlugins(dockerCli command.Cli, rootcmd *cobra.Command) ([]Plugin, error) { +func ListPlugins(dockerCli config.Provider, rootcmd *cobra.Command) ([]Plugin, error) { pluginDirs, err := getPluginDirs(dockerCli.ConfigFile()) if err != nil { return nil, err @@ -188,7 +190,7 @@ func ListPlugins(dockerCli command.Cli, rootcmd *cobra.Command) ([]Plugin, error // PluginRunCommand returns an "os/exec".Cmd which when .Run() will execute the named plugin. // The rootcmd argument is referenced to determine the set of builtin commands in order to detect conficts. // The error returned satisfies the IsNotFound() predicate if no plugin was found or if the first candidate plugin was invalid somehow. -func PluginRunCommand(dockerCli command.Cli, name string, rootcmd *cobra.Command) (*exec.Cmd, error) { +func PluginRunCommand(dockerCli config.Provider, name string, rootcmd *cobra.Command) (*exec.Cmd, error) { // This uses the full original args, not the args which may // have been provided by cobra to our caller. This is because // they lack e.g. global options which we must propagate here. diff --git a/cli/command/cli.go b/cli/command/cli.go index 1b5eca5963..2f3d4ab240 100644 --- a/cli/command/cli.go +++ b/cli/command/cli.go @@ -46,7 +46,7 @@ type Cli interface { Streams SetIn(in *streams.In) Apply(ops ...CLIOption) error - ConfigFile() *configfile.ConfigFile + config.Provider ServerInfo() ServerInfo DefaultVersion() string CurrentVersion() string diff --git a/cli/config/config.go b/cli/config/config.go index 910b3c0064..daf504333c 100644 --- a/cli/config/config.go +++ b/cli/config/config.go @@ -69,6 +69,11 @@ func getHomeDir() string { return home } +// Provider defines an interface for providing the CLI config. +type Provider interface { + ConfigFile() *configfile.ConfigFile +} + // Dir returns the directory the configuration file is stored in func Dir() string { initConfigDir.Do(func() {