From 8e93ef7ebe2798b550c8aa92ec6bf0861c7e9b1e Mon Sep 17 00:00:00 2001 From: luojiyin Date: Tue, 24 Feb 2026 10:17:12 +0800 Subject: [PATCH] fix: restore os.Args after plugin completion and fix error return --- cli-plugins/manager/cobra.go | 6 +++- cli-plugins/manager/cobra_test.go | 49 +++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 1 deletion(-) diff --git a/cli-plugins/manager/cobra.go b/cli-plugins/manager/cobra.go index dd3f05baedbf..c2ed316e477d 100644 --- a/cli-plugins/manager/cobra.go +++ b/cli-plugins/manager/cobra.go @@ -47,7 +47,7 @@ func AddPluginCommandStubs(dockerCLI config.Provider, rootCmd *cobra.Command) (e flags.SetOutput(nil) perr := flags.Parse(args) if perr != nil { - return err + return perr } if flags.Changed("help") { cmd.HelpFunc()(rootCmd, args) @@ -60,7 +60,11 @@ func AddPluginCommandStubs(dockerCLI config.Provider, rootCmd *cobra.Command) (e cargs := []string{p.Path, cobra.ShellCompRequestCmd, p.Name} //nolint:prealloc // no need to over-complicate things. cargs = append(cargs, args...) cargs = append(cargs, toComplete) + origArgs := os.Args os.Args = cargs + defer func() { + os.Args = origArgs + }() runCommand, runErr := PluginRunCommand(dockerCLI, p.Name, cmd) if runErr != nil { return nil, cobra.ShellCompDirectiveError diff --git a/cli-plugins/manager/cobra_test.go b/cli-plugins/manager/cobra_test.go index 207b536f1faf..446084b6a10c 100644 --- a/cli-plugins/manager/cobra_test.go +++ b/cli-plugins/manager/cobra_test.go @@ -1,10 +1,15 @@ package manager import ( + "os" + "sync" "testing" + "github.com/docker/cli/cli/config/configfile" + "github.com/docker/cli/internal/test" "github.com/spf13/cobra" "gotest.tools/v3/assert" + "gotest.tools/v3/fs" ) func TestPluginResourceAttributesEnvvar(t *testing.T) { @@ -24,3 +29,47 @@ func TestPluginResourceAttributesEnvvar(t *testing.T) { env = appendPluginResourceAttributesEnvvar(nil, cmd, Plugin{Name: "compose"}) assert.DeepEqual(t, []string{"OTEL_RESOURCE_ATTRIBUTES=a.b.c=foo,docker.cli.cobra.command_path=docker%20compose"}, env) } + +func TestPluginStubRunEReturnsParseError(t *testing.T) { + cmd := preparePluginStubCommand(t, `{"SchemaVersion":"0.1.0","Vendor":"e2e-testing"}`) + + err := cmd.RunE(cmd, []string{"--definitely-not-a-real-flag"}) + assert.ErrorContains(t, err, "unknown flag: --definitely-not-a-real-flag") +} + +func TestPluginStubCompletionRestoresOSArgs(t *testing.T) { + cmd := preparePluginStubCommand(t, `{"SchemaVersion":"0.1.0"}`) + + originalArgs := []string{"docker", "image", "ls"} + os.Args = append([]string(nil), originalArgs...) + + _, directive := cmd.ValidArgsFunction(cmd, []string{"--all"}, "alp") + assert.Equal(t, directive, cobra.ShellCompDirectiveError) + assert.DeepEqual(t, os.Args, originalArgs) +} + +func preparePluginStubCommand(t *testing.T, metadata string) *cobra.Command { + t.Helper() + pluginCommandStubsOnce = sync.Once{} + + dir := fs.NewDir(t, t.Name(), + fs.WithFile("docker-testplugin", "#!/bin/sh\nprintf '%s' '"+metadata+"'\n", fs.WithMode(0o777)), + ) + t.Cleanup(func() { dir.Remove() }) + + cli := test.NewFakeCli(nil) + cli.SetConfigFile(&configfile.ConfigFile{ + CLIPluginsExtraDirs: []string{dir.Path()}, + }) + + root := &cobra.Command{Use: "docker"} + root.PersistentFlags().Bool("debug", false, "") + + err := AddPluginCommandStubs(cli, root) + assert.NilError(t, err) + + cmd, _, err := root.Find([]string{"testplugin"}) + assert.NilError(t, err) + assert.Assert(t, cmd != nil) + return cmd +}