Merge pull request #1853 from ijc/cli-plugin-persistentprerun-hook

cli-plugins: fix when plugin does not use PersistentPreRun* hooks
This commit is contained in:
Sebastiaan van Stijn 2019-05-13 07:06:42 -07:00 committed by GitHub
commit 11d2e404c6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 58 additions and 10 deletions

View File

@ -114,11 +114,14 @@ func newPluginCommand(dockerCli *command.DockerCli, plugin *cobra.Command, meta
fullname := manager.NamePrefix + name
cmd := &cobra.Command{
Use: fmt.Sprintf("docker [OPTIONS] %s [ARG...]", name),
Short: fullname + " is a Docker CLI plugin",
SilenceUsage: true,
SilenceErrors: true,
PersistentPreRunE: PersistentPreRunE,
Use: fmt.Sprintf("docker [OPTIONS] %s [ARG...]", name),
Short: fullname + " is a Docker CLI plugin",
SilenceUsage: true,
SilenceErrors: true,
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
// We can't use this as the hook directly since it is initialised later (in runPlugin)
return PersistentPreRunE(cmd, args)
},
TraverseChildren: true,
DisableFlagsInUseLine: true,
}

View File

@ -0,0 +1,36 @@
package main
import (
"context"
"fmt"
"github.com/docker/cli/cli-plugins/manager"
"github.com/docker/cli/cli-plugins/plugin"
"github.com/docker/cli/cli/command"
"github.com/spf13/cobra"
)
func main() {
plugin.Run(func(dockerCli command.Cli) *cobra.Command {
cmd := &cobra.Command{
Use: "nopersistentprerun",
Short: "Testing without PersistentPreRun hooks",
//PersistentPreRunE: Not specified, we need to test that it works in the absence of an explicit call
RunE: func(cmd *cobra.Command, args []string) error {
cli := dockerCli.Client()
ping, err := cli.Ping(context.Background())
if err != nil {
return err
}
fmt.Println(ping.APIVersion)
return nil
},
}
return cmd
},
manager.Metadata{
SchemaVersion: "0.1.0",
Vendor: "Docker Inc.",
Version: "testing",
})
}

View File

@ -213,15 +213,24 @@ func TestGoodSubcommandHelp(t *testing.T) {
}
// TestCliInitialized tests the code paths which ensure that the Cli
// object is initialized even if the plugin uses PersistentRunE
// object is initialized whether the plugin uses PersistentRunE or not
func TestCliInitialized(t *testing.T) {
run, _, cleanup := prepare(t)
defer cleanup()
res := icmd.RunCmd(run("helloworld", "--pre-run", "apiversion"))
res.Assert(t, icmd.Success)
assert.Assert(t, res.Stdout() != "")
assert.Assert(t, is.Equal(res.Stderr(), "Plugin PersistentPreRunE called"))
var apiversion string
t.Run("withhook", func(t *testing.T) {
res := icmd.RunCmd(run("helloworld", "--pre-run", "apiversion"))
res.Assert(t, icmd.Success)
assert.Assert(t, res.Stdout() != "")
apiversion = res.Stdout()
assert.Assert(t, is.Equal(res.Stderr(), "Plugin PersistentPreRunE called"))
})
t.Run("withouthook", func(t *testing.T) {
res := icmd.RunCmd(run("nopersistentprerun"))
res.Assert(t, icmd.Success)
assert.Assert(t, is.Equal(res.Stdout(), apiversion))
})
}
// TestPluginErrorCode tests when the plugin return with a given exit status.