mirror of https://github.com/docker/cli.git
cli-plugins: fix when plugin does not use PersistentPreRun* hooks
This regressed in 3af168c7df
("Ensure plugins can use `PersistentPreRunE`
again.") but this wasn't noticed because the helloworld test plugin has it's
own `PersistentPreRunE` which has the effect of deferring the resolution of the
global variable. In the case where the hook isn't used the variable is resolved
during `newPluginCommand` which is before the global variable was set.
Initialize the plugin command with a stub function wrapping the call to the
(global) hook, this defers resolving the variable until after it has been set,
otherwise the initial value (`nil`) is used in the struct.
Signed-off-by: Ian Campbell <ijc@docker.com>
This commit is contained in:
parent
3273c2e235
commit
af200f14ed
|
@ -118,7 +118,10 @@ func newPluginCommand(dockerCli *command.DockerCli, plugin *cobra.Command, meta
|
|||
Short: fullname + " is a Docker CLI plugin",
|
||||
SilenceUsage: true,
|
||||
SilenceErrors: true,
|
||||
PersistentPreRunE: PersistentPreRunE,
|
||||
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,
|
||||
}
|
||||
|
|
|
@ -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",
|
||||
})
|
||||
}
|
|
@ -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()
|
||||
|
||||
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.
|
||||
|
|
Loading…
Reference in New Issue