Skip to content

Commit 8858366

Browse files
author
Ian Campbell
committed
Integrate CLI plugins with docker help «foo»
Signed-off-by: Ian Campbell <ijc@docker.com>
1 parent d3c3132 commit 8858366

File tree

3 files changed

+61
-0
lines changed

3 files changed

+61
-0
lines changed

cli-plugins/manager/manager.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,3 +181,10 @@ func PluginRunCommand(name string, rootcmd *cobra.Command) (*exec.Cmd, error) {
181181
// they lack e.g. global options which we must propagate here.
182182
return runPluginCommand(name, rootcmd, os.Args[1:])
183183
}
184+
185+
// PluginHelpCommand returns an "os/exec".Cmd which when .Run() will execute the named plugin's help command.
186+
// The rootcmd argument is referenced to determine the set of builtin commands in order to detect conficts.
187+
// The error returned is an ErrPluginNotFound if no plugin was found or if the first candidate plugin was invalid somehow.
188+
func PluginHelpCommand(name string, rootcmd *cobra.Command) (*exec.Cmd, error) {
189+
return runPluginCommand(name, rootcmd, []string{"help", name})
190+
}

cli/cobra.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package cli
22

33
import (
44
"fmt"
5+
"os"
56
"strings"
67

78
pluginmanager "github.com/docker/cli/cli-plugins/manager"
@@ -57,6 +58,18 @@ var helpCommand = &cobra.Command{
5758
RunE: func(c *cobra.Command, args []string) error {
5859
cmd, args, e := c.Root().Find(args)
5960
if cmd == nil || e != nil || len(args) > 0 {
61+
if len(args) == 1 {
62+
helpcmd, err := pluginmanager.PluginHelpCommand(args[0], cmd.Root())
63+
if err == nil {
64+
helpcmd.Stdin = os.Stdin
65+
helpcmd.Stdout = os.Stdout
66+
helpcmd.Stderr = os.Stderr
67+
return helpcmd.Run()
68+
}
69+
if _, ok := err.(pluginmanager.ErrPluginNotFound); !ok {
70+
return err
71+
}
72+
}
6073
return errors.Errorf("unknown help topic: %v", strings.Join(args, " "))
6174
}
6275

e2e/cli-plugins/run_test.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,20 @@ func TestRunNonexisting(t *testing.T) {
1414
})
1515
}
1616

17+
func TestHelpNonexisting(t *testing.T) {
18+
res := icmd.RunCmd(icmd.Command("docker", "help", "nonexistent"))
19+
res.Assert(t, icmd.Expected{
20+
ExitCode: 1,
21+
Err: "unknown help topic: nonexistent",
22+
})
23+
24+
res = icmd.RunCmd(icmd.Command("docker", "nonexistent", "--help"))
25+
res.Assert(t, icmd.Expected{
26+
ExitCode: 0,
27+
Out: "Usage: docker [OPTIONS] COMMAND",
28+
})
29+
}
30+
1731
func TestRunBad(t *testing.T) {
1832
res := icmd.RunCmd(icmd.Command("docker", "badmeta"))
1933
res.Assert(t, icmd.Expected{
@@ -22,10 +36,37 @@ func TestRunBad(t *testing.T) {
2236
})
2337
}
2438

39+
func TestHelpBad(t *testing.T) {
40+
res := icmd.RunCmd(icmd.Command("docker", "help", "badmeta"))
41+
res.Assert(t, icmd.Expected{
42+
ExitCode: 1,
43+
Err: "unknown help topic: badmeta",
44+
})
45+
46+
res = icmd.RunCmd(icmd.Command("docker", "badmeta", "--help"))
47+
res.Assert(t, icmd.Expected{
48+
ExitCode: 0,
49+
Out: "Usage: docker [OPTIONS] COMMAND",
50+
})
51+
}
52+
2553
func TestRunGood(t *testing.T) {
2654
res := icmd.RunCmd(icmd.Command("docker", "helloworld"))
2755
res.Assert(t, icmd.Expected{
2856
ExitCode: 0,
2957
Out: "Hello World!",
3058
})
3159
}
60+
61+
func TestHelpGood(t *testing.T) {
62+
res := icmd.RunCmd(icmd.Command("docker", "help", "helloworld"))
63+
res.Assert(t, icmd.Expected{
64+
ExitCode: 0,
65+
Out: "Usage:\n docker helloworld",
66+
})
67+
res = icmd.RunCmd(icmd.Command("docker", "helloworld", "--help"))
68+
res.Assert(t, icmd.Expected{
69+
ExitCode: 0,
70+
Out: "Usage: docker helloworld",
71+
})
72+
}

0 commit comments

Comments
 (0)