Skip to content

Commit a3e49b0

Browse files
committed
cli-plugins/manager: use shallower interface
The manager only requires the CLI's configuration; define a shallow interface for this so that we don't have to import cli/command. In addition to the CLI's configuration, `runHooks` also used the CLI's configured StdErr output. We set the Cobra input and output streams to be the same as the DockerCLI outputs in [newDockerCommand] and [newPluginCommand], so we can get this from the Cobra command. [newDockerCommand]: https://github.com/docker/cli/blob/ea1f10b440370997b8ff2c78602b249236c34f4a/cmd/docker/docker.go#L148-L150 [newPluginCommand]: https://github.com/docker/cli/blob/ea1f10b440370997b8ff2c78602b249236c34f4a/cli-plugins/plugin/plugin.go#L166-L168 Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
1 parent ea1f10b commit a3e49b0

File tree

3 files changed

+30
-21
lines changed

3 files changed

+30
-21
lines changed

cli-plugins/manager/cobra.go

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import (
55
"os"
66
"sync"
77

8-
"github.com/docker/cli/cli/command"
98
"github.com/spf13/cobra"
109
)
1110

@@ -41,10 +40,10 @@ var pluginCommandStubsOnce sync.Once
4140
// AddPluginCommandStubs adds a stub cobra.Commands for each valid and invalid
4241
// plugin. The command stubs will have several annotations added, see
4342
// `CommandAnnotationPlugin*`.
44-
func AddPluginCommandStubs(dockerCli command.Cli, rootCmd *cobra.Command) (err error) {
43+
func AddPluginCommandStubs(dockerCLI ConfigProvider, rootCmd *cobra.Command) (err error) {
4544
pluginCommandStubsOnce.Do(func() {
4645
var plugins []Plugin
47-
plugins, err = ListPlugins(dockerCli, rootCmd)
46+
plugins, err = ListPlugins(dockerCLI, rootCmd)
4847
if err != nil {
4948
return
5049
}
@@ -86,7 +85,7 @@ func AddPluginCommandStubs(dockerCli command.Cli, rootCmd *cobra.Command) (err e
8685
cargs = append(cargs, args...)
8786
cargs = append(cargs, toComplete)
8887
os.Args = cargs
89-
runCommand, runErr := PluginRunCommand(dockerCli, p.Name, cmd)
88+
runCommand, runErr := PluginRunCommand(dockerCLI, p.Name, cmd)
9089
if runErr != nil {
9190
return nil, cobra.ShellCompDirectiveError
9291
}

cli-plugins/manager/hooks.go

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import (
66
"strings"
77

88
"github.com/docker/cli/cli-plugins/hooks"
9-
"github.com/docker/cli/cli/command"
9+
"github.com/docker/cli/cli/config/configfile"
1010
"github.com/sirupsen/logrus"
1111
"github.com/spf13/cobra"
1212
"github.com/spf13/pflag"
@@ -29,49 +29,52 @@ type HookPluginData struct {
2929
// a main CLI command was executed. It calls the hook subcommand for all
3030
// present CLI plugins that declare support for hooks in their metadata and
3131
// parses/prints their responses.
32-
func RunCLICommandHooks(ctx context.Context, dockerCli command.Cli, rootCmd, subCommand *cobra.Command, cmdErrorMessage string) {
32+
func RunCLICommandHooks(ctx context.Context, dockerCLI ConfigProvider, rootCmd, subCommand *cobra.Command, cmdErrorMessage string) {
3333
commandName := strings.TrimPrefix(subCommand.CommandPath(), rootCmd.Name()+" ")
3434
flags := getCommandFlags(subCommand)
3535

36-
runHooks(ctx, dockerCli, rootCmd, subCommand, commandName, flags, cmdErrorMessage)
36+
runHooks(ctx, dockerCLI.ConfigFile(), rootCmd, subCommand, commandName, flags, cmdErrorMessage)
3737
}
3838

3939
// RunPluginHooks is the entrypoint for the hooks execution flow
4040
// after a plugin command was just executed by the CLI.
41-
func RunPluginHooks(ctx context.Context, dockerCli command.Cli, rootCmd, subCommand *cobra.Command, args []string) {
41+
func RunPluginHooks(ctx context.Context, dockerCLI ConfigProvider, rootCmd, subCommand *cobra.Command, args []string) {
4242
commandName := strings.Join(args, " ")
4343
flags := getNaiveFlags(args)
4444

45-
runHooks(ctx, dockerCli, rootCmd, subCommand, commandName, flags, "")
45+
runHooks(ctx, dockerCLI.ConfigFile(), rootCmd, subCommand, commandName, flags, "")
4646
}
4747

48-
func runHooks(ctx context.Context, dockerCli command.Cli, rootCmd, subCommand *cobra.Command, invokedCommand string, flags map[string]string, cmdErrorMessage string) {
49-
nextSteps := invokeAndCollectHooks(ctx, dockerCli, rootCmd, subCommand, invokedCommand, flags, cmdErrorMessage)
50-
51-
hooks.PrintNextSteps(dockerCli.Err(), nextSteps)
48+
func runHooks(ctx context.Context, cfg *configfile.ConfigFile, rootCmd, subCommand *cobra.Command, invokedCommand string, flags map[string]string, cmdErrorMessage string) {
49+
nextSteps := invokeAndCollectHooks(ctx, cfg, rootCmd, subCommand, invokedCommand, flags, cmdErrorMessage)
50+
hooks.PrintNextSteps(subCommand.ErrOrStderr(), nextSteps)
5251
}
5352

54-
func invokeAndCollectHooks(ctx context.Context, dockerCli command.Cli, rootCmd, subCmd *cobra.Command, subCmdStr string, flags map[string]string, cmdErrorMessage string) []string {
53+
func invokeAndCollectHooks(ctx context.Context, cfg *configfile.ConfigFile, rootCmd, subCmd *cobra.Command, subCmdStr string, flags map[string]string, cmdErrorMessage string) []string {
5554
// check if the context was cancelled before invoking hooks
5655
select {
5756
case <-ctx.Done():
5857
return nil
5958
default:
6059
}
6160

62-
pluginsCfg := dockerCli.ConfigFile().Plugins
61+
pluginsCfg := cfg.Plugins
6362
if pluginsCfg == nil {
6463
return nil
6564
}
6665

66+
pluginDirs, err := getPluginDirs(cfg)
67+
if err != nil {
68+
return nil
69+
}
6770
nextSteps := make([]string, 0, len(pluginsCfg))
6871
for pluginName, cfg := range pluginsCfg {
6972
match, ok := pluginMatch(cfg, subCmdStr)
7073
if !ok {
7174
continue
7275
}
7376

74-
p, err := GetPlugin(pluginName, dockerCli, rootCmd)
77+
p, err := getPlugin(pluginName, pluginDirs, rootCmd)
7578
if err != nil {
7679
continue
7780
}

cli-plugins/manager/manager.go

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import (
99
"strings"
1010
"sync"
1111

12-
"github.com/docker/cli/cli/command"
1312
"github.com/docker/cli/cli/config"
1413
"github.com/docker/cli/cli/config/configfile"
1514
"github.com/fvbommel/sortorder"
@@ -114,13 +113,21 @@ func listPluginCandidates(dirs []string) map[string][]string {
114113
return result
115114
}
116115

116+
// ConfigProvider defines an interface for providing the CLI config.
117+
type ConfigProvider interface {
118+
ConfigFile() *configfile.ConfigFile
119+
}
120+
117121
// GetPlugin returns a plugin on the system by its name
118-
func GetPlugin(name string, dockerCli command.Cli, rootcmd *cobra.Command) (*Plugin, error) {
119-
pluginDirs, err := getPluginDirs(dockerCli.ConfigFile())
122+
func GetPlugin(name string, dockerCLI ConfigProvider, rootcmd *cobra.Command) (*Plugin, error) {
123+
pluginDirs, err := getPluginDirs(dockerCLI.ConfigFile())
120124
if err != nil {
121125
return nil, err
122126
}
127+
return getPlugin(name, pluginDirs, rootcmd)
128+
}
123129

130+
func getPlugin(name string, pluginDirs []string, rootcmd *cobra.Command) (*Plugin, error) {
124131
candidates := listPluginCandidates(pluginDirs)
125132
if paths, ok := candidates[name]; ok {
126133
if len(paths) == 0 {
@@ -141,7 +148,7 @@ func GetPlugin(name string, dockerCli command.Cli, rootcmd *cobra.Command) (*Plu
141148
}
142149

143150
// ListPlugins produces a list of the plugins available on the system
144-
func ListPlugins(dockerCli command.Cli, rootcmd *cobra.Command) ([]Plugin, error) {
151+
func ListPlugins(dockerCli ConfigProvider, rootcmd *cobra.Command) ([]Plugin, error) {
145152
pluginDirs, err := getPluginDirs(dockerCli.ConfigFile())
146153
if err != nil {
147154
return nil, err
@@ -188,7 +195,7 @@ func ListPlugins(dockerCli command.Cli, rootcmd *cobra.Command) ([]Plugin, error
188195
// PluginRunCommand returns an "os/exec".Cmd which when .Run() will execute the named plugin.
189196
// The rootcmd argument is referenced to determine the set of builtin commands in order to detect conficts.
190197
// The error returned satisfies the IsNotFound() predicate if no plugin was found or if the first candidate plugin was invalid somehow.
191-
func PluginRunCommand(dockerCli command.Cli, name string, rootcmd *cobra.Command) (*exec.Cmd, error) {
198+
func PluginRunCommand(dockerCli ConfigProvider, name string, rootcmd *cobra.Command) (*exec.Cmd, error) {
192199
// This uses the full original args, not the args which may
193200
// have been provided by cobra to our caller. This is because
194201
// they lack e.g. global options which we must propagate here.

0 commit comments

Comments
 (0)