Skip to content

Commit

Permalink
Integrate CLI plugins with docker help «foo»
Browse files Browse the repository at this point in the history
Signed-off-by: Ian Campbell <ijc@docker.com>
  • Loading branch information
Ian Campbell committed Dec 13, 2018
1 parent 328a7d7 commit 3aeb78c
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 0 deletions.
7 changes: 7 additions & 0 deletions cli-plugins/manager/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -181,3 +181,10 @@ func PluginRunCommand(name string, rootcmd *cobra.Command) (*exec.Cmd, error) {
// they lack e.g. global options which we must propagate here.
return runPluginCommand(name, rootcmd, os.Args[1:])
}

// PluginHelpCommand returns an "os/exec".Cmd which when .Run() will execute the named plugin's help command.
// The rootcmd argument is referenced to determine the set of builtin commands in order to detect conficts.
// The error returned is an ErrPluginNotFound if no plugin was found or if the first candidate plugin was invalid somehow.
func PluginHelpCommand(name string, rootcmd *cobra.Command) (*exec.Cmd, error) {
return runPluginCommand(name, rootcmd, []string{"help", name})
}
13 changes: 13 additions & 0 deletions cli/cobra.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package cli

import (
"fmt"
"os"
"strings"

pluginmanager "github.com/docker/cli/cli-plugins/manager"
Expand Down Expand Up @@ -57,6 +58,18 @@ var helpCommand = &cobra.Command{
RunE: func(c *cobra.Command, args []string) error {
cmd, args, e := c.Root().Find(args)
if cmd == nil || e != nil || len(args) > 0 {
if len(args) == 1 {
helpcmd, err := pluginmanager.PluginHelpCommand(args[0], cmd.Root())
if err == nil {
helpcmd.Stdin = os.Stdin
helpcmd.Stdout = os.Stdout
helpcmd.Stderr = os.Stderr
return helpcmd.Run()
}
if _, ok := err.(pluginmanager.ErrPluginNotFound); !ok {
return err
}
}
return errors.Errorf("unknown help topic: %v", strings.Join(args, " "))
}

Expand Down
41 changes: 41 additions & 0 deletions e2e/cli-plugins/run_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,20 @@ func TestRunNonexisting(t *testing.T) {
})
}

func TestHelpNonexisting(t *testing.T) {
res := icmd.RunCmd(icmd.Command("docker", "help", "nonexistent"))
res.Assert(t, icmd.Expected{
ExitCode: 1,
Err: "unknown help topic: nonexistent",
})

res = icmd.RunCmd(icmd.Command("docker", "nonexistent", "--help"))
res.Assert(t, icmd.Expected{
ExitCode: 0,
Out: "Usage: docker [OPTIONS] COMMAND",
})
}

func TestRunBad(t *testing.T) {
res := icmd.RunCmd(icmd.Command("docker", "badmeta"))
res.Assert(t, icmd.Expected{
Expand All @@ -22,10 +36,37 @@ func TestRunBad(t *testing.T) {
})
}

func TestHelpBad(t *testing.T) {
res := icmd.RunCmd(icmd.Command("docker", "help", "badmeta"))
res.Assert(t, icmd.Expected{
ExitCode: 1,
Err: "unknown help topic: badmeta",
})

res = icmd.RunCmd(icmd.Command("docker", "badmeta", "--help"))
res.Assert(t, icmd.Expected{
ExitCode: 0,
Out: "Usage: docker [OPTIONS] COMMAND",
})
}

func TestRunGood(t *testing.T) {
res := icmd.RunCmd(icmd.Command("docker", "helloworld"))
res.Assert(t, icmd.Expected{
ExitCode: 0,
Out: "Hello World!",
})
}

func TestHelpGood(t *testing.T) {
res := icmd.RunCmd(icmd.Command("docker", "help", "helloworld"))
res.Assert(t, icmd.Expected{
ExitCode: 0,
Out: "Usage:\n docker helloworld",
})
res = icmd.RunCmd(icmd.Command("docker", "helloworld", "--help"))
res.Assert(t, icmd.Expected{
ExitCode: 0,
Out: "Usage: docker helloworld",
})
}

0 comments on commit 3aeb78c

Please sign in to comment.