mirror of https://github.com/docker/cli.git
Merge pull request #1737 from ijc/plugins-using-PersistentPreRunE
Fix regression for CLI plugins using PersistentPreRunE
This commit is contained in:
commit
7f1176b8aa
|
@ -46,11 +46,20 @@ func main() {
|
||||||
|
|
||||||
var (
|
var (
|
||||||
who, context string
|
who, context string
|
||||||
debug bool
|
preRun, debug bool
|
||||||
)
|
)
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
Use: "helloworld",
|
Use: "helloworld",
|
||||||
Short: "A basic Hello World plugin for tests",
|
Short: "A basic Hello World plugin for tests",
|
||||||
|
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
|
||||||
|
if err := plugin.PersistentPreRunE(cmd, args); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if preRun {
|
||||||
|
fmt.Fprintf(dockerCli.Err(), "Plugin PersistentPreRunE called")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
},
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
if debug {
|
if debug {
|
||||||
fmt.Fprintf(dockerCli.Err(), "Plugin debug mode enabled")
|
fmt.Fprintf(dockerCli.Err(), "Plugin debug mode enabled")
|
||||||
|
@ -79,6 +88,7 @@ func main() {
|
||||||
|
|
||||||
flags := cmd.Flags()
|
flags := cmd.Flags()
|
||||||
flags.StringVar(&who, "who", "", "Who are we addressing?")
|
flags.StringVar(&who, "who", "", "Who are we addressing?")
|
||||||
|
flags.BoolVar(&preRun, "pre-run", false, "Log from prerun hook")
|
||||||
// These are intended to deliberately clash with the CLIs own top
|
// These are intended to deliberately clash with the CLIs own top
|
||||||
// level arguments.
|
// level arguments.
|
||||||
flags.BoolVarP(&debug, "debug", "D", false, "Enable debug")
|
flags.BoolVarP(&debug, "debug", "D", false, "Enable debug")
|
||||||
|
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
"sync"
|
||||||
|
|
||||||
"github.com/docker/cli/cli"
|
"github.com/docker/cli/cli"
|
||||||
"github.com/docker/cli/cli-plugins/manager"
|
"github.com/docker/cli/cli-plugins/manager"
|
||||||
|
@ -13,14 +14,26 @@ import (
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// PersistentPreRunE must be called by any plugin command (or
|
||||||
|
// subcommand) which uses the cobra `PersistentPreRun*` hook. Plugins
|
||||||
|
// which do not make use of `PersistentPreRun*` do not need to call
|
||||||
|
// this (although it remains safe to do so). Plugins are recommended
|
||||||
|
// to use `PersistenPreRunE` to enable the error to be
|
||||||
|
// returned. Should not be called outside of a command's
|
||||||
|
// PersistentPreRunE hook and must not be run unless Run has been
|
||||||
|
// called.
|
||||||
|
var PersistentPreRunE func(*cobra.Command, []string) error
|
||||||
|
|
||||||
func runPlugin(dockerCli *command.DockerCli, plugin *cobra.Command, meta manager.Metadata) error {
|
func runPlugin(dockerCli *command.DockerCli, plugin *cobra.Command, meta manager.Metadata) error {
|
||||||
tcmd := newPluginCommand(dockerCli, plugin, meta)
|
tcmd := newPluginCommand(dockerCli, plugin, meta)
|
||||||
|
|
||||||
// Doing this here avoids also calling it for the metadata
|
var persistentPreRunOnce sync.Once
|
||||||
// command which needlessly initializes the client and tries
|
PersistentPreRunE = func(_ *cobra.Command, _ []string) error {
|
||||||
// to connect to the daemon.
|
var err error
|
||||||
plugin.PersistentPreRunE = func(_ *cobra.Command, _ []string) error {
|
persistentPreRunOnce.Do(func() {
|
||||||
return tcmd.Initialize(withPluginClientConn(plugin.Name()))
|
err = tcmd.Initialize(withPluginClientConn(plugin.Name()))
|
||||||
|
})
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd, _, err := tcmd.HandleGlobalFlags()
|
cmd, _, err := tcmd.HandleGlobalFlags()
|
||||||
|
@ -98,6 +111,7 @@ func newPluginCommand(dockerCli *command.DockerCli, plugin *cobra.Command, meta
|
||||||
Short: fullname + " is a Docker CLI plugin",
|
Short: fullname + " is a Docker CLI plugin",
|
||||||
SilenceUsage: true,
|
SilenceUsage: true,
|
||||||
SilenceErrors: true,
|
SilenceErrors: true,
|
||||||
|
PersistentPreRunE: PersistentPreRunE,
|
||||||
TraverseChildren: true,
|
TraverseChildren: true,
|
||||||
DisableFlagsInUseLine: true,
|
DisableFlagsInUseLine: true,
|
||||||
}
|
}
|
||||||
|
@ -122,6 +136,10 @@ func newMetadataSubcommand(plugin *cobra.Command, meta manager.Metadata) *cobra.
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
Use: manager.MetadataSubcommandName,
|
Use: manager.MetadataSubcommandName,
|
||||||
Hidden: true,
|
Hidden: true,
|
||||||
|
// Suppress the global/parent PersistentPreRunE, which
|
||||||
|
// needlessly initializes the client and tries to
|
||||||
|
// connect to the daemon.
|
||||||
|
PersistentPreRun: func(cmd *cobra.Command, args []string) {},
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
enc := json.NewEncoder(os.Stdout)
|
enc := json.NewEncoder(os.Stdout)
|
||||||
enc.SetEscapeHTML(false)
|
enc.SetEscapeHTML(false)
|
||||||
|
|
|
@ -177,10 +177,10 @@ func TestCliInitialized(t *testing.T) {
|
||||||
run, _, cleanup := prepare(t)
|
run, _, cleanup := prepare(t)
|
||||||
defer cleanup()
|
defer cleanup()
|
||||||
|
|
||||||
res := icmd.RunCmd(run("helloworld", "apiversion"))
|
res := icmd.RunCmd(run("helloworld", "--pre-run", "apiversion"))
|
||||||
res.Assert(t, icmd.Success)
|
res.Assert(t, icmd.Success)
|
||||||
assert.Assert(t, res.Stdout() != "")
|
assert.Assert(t, res.Stdout() != "")
|
||||||
assert.Assert(t, is.Equal(res.Stderr(), ""))
|
assert.Assert(t, is.Equal(res.Stderr(), "Plugin PersistentPreRunE called"))
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestPluginErrorCode tests when the plugin return with a given exit status.
|
// TestPluginErrorCode tests when the plugin return with a given exit status.
|
||||||
|
|
|
@ -6,6 +6,7 @@ A basic Hello World plugin for tests
|
||||||
Options:
|
Options:
|
||||||
-c, --context string Is it Christmas?
|
-c, --context string Is it Christmas?
|
||||||
-D, --debug Enable debug
|
-D, --debug Enable debug
|
||||||
|
--pre-run Log from prerun hook
|
||||||
--who string Who are we addressing?
|
--who string Who are we addressing?
|
||||||
|
|
||||||
Commands:
|
Commands:
|
||||||
|
|
Loading…
Reference in New Issue