cli-plugins: minor cleanups: use Println

- use Println to print newline instead of custom format
- suppress some errors to make my IDE and linters happier
- use res.Assert() with icmd.Expected{} where possible to make
  assertions not depend on newline / whitespace randomness
- use apiClient instead of client for the API client to
  prevent shadowing imports.
- use dockerCLI with Go's standard camelCase casing.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
Sebastiaan van Stijn 2025-02-01 22:16:12 +01:00
parent 4d7fe01d4b
commit b10b79e6fd
No known key found for this signature in database
GPG Key ID: 76698F39D527CE8C
7 changed files with 41 additions and 37 deletions

View File

@ -12,24 +12,24 @@ import (
) )
func main() { func main() {
plugin.Run(func(dockerCli command.Cli) *cobra.Command { plugin.Run(func(dockerCLI command.Cli) *cobra.Command {
goodbye := &cobra.Command{ goodbye := &cobra.Command{
Use: "goodbye", Use: "goodbye",
Short: "Say Goodbye instead of Hello", Short: "Say Goodbye instead of Hello",
Run: func(cmd *cobra.Command, _ []string) { Run: func(cmd *cobra.Command, _ []string) {
fmt.Fprintln(dockerCli.Out(), "Goodbye World!") _, _ = fmt.Fprintln(dockerCLI.Out(), "Goodbye World!")
}, },
} }
apiversion := &cobra.Command{ apiversion := &cobra.Command{
Use: "apiversion", Use: "apiversion",
Short: "Print the API version of the server", Short: "Print the API version of the server",
RunE: func(_ *cobra.Command, _ []string) error { RunE: func(_ *cobra.Command, _ []string) error {
cli := dockerCli.Client() apiClient := dockerCLI.Client()
ping, err := cli.Ping(context.Background()) ping, err := apiClient.Ping(context.Background())
if err != nil { if err != nil {
return err return err
} }
fmt.Println(ping.APIVersion) _, _ = fmt.Println(ping.APIVersion)
return nil return nil
}, },
} }
@ -38,7 +38,7 @@ func main() {
Use: "exitstatus2", Use: "exitstatus2",
Short: "Exit with status 2", Short: "Exit with status 2",
RunE: func(_ *cobra.Command, _ []string) error { RunE: func(_ *cobra.Command, _ []string) error {
fmt.Fprintln(dockerCli.Err(), "Exiting with error status 2") _, _ = fmt.Fprintln(dockerCLI.Err(), "Exiting with error status 2")
os.Exit(2) os.Exit(2)
return nil return nil
}, },
@ -56,33 +56,33 @@ func main() {
return err return err
} }
if preRun { if preRun {
fmt.Fprintf(dockerCli.Err(), "Plugin PersistentPreRunE called") _, _ = fmt.Fprintln(dockerCLI.Err(), "Plugin PersistentPreRunE called")
} }
return nil 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.Fprintln(dockerCLI.Err(), "Plugin debug mode enabled")
} }
switch optContext { switch optContext {
case "Christmas": case "Christmas":
fmt.Fprintf(dockerCli.Out(), "Merry Christmas!\n") _, _ = fmt.Fprintln(dockerCLI.Out(), "Merry Christmas!")
return nil return nil
case "": case "":
// nothing // nothing
} }
if who == "" { if who == "" {
who, _ = dockerCli.ConfigFile().PluginConfig("helloworld", "who") who, _ = dockerCLI.ConfigFile().PluginConfig("helloworld", "who")
} }
if who == "" { if who == "" {
who = "World" who = "World"
} }
fmt.Fprintf(dockerCli.Out(), "Hello %s!\n", who) _, _ = fmt.Fprintln(dockerCLI.Out(), "Hello", who)
dockerCli.ConfigFile().SetPluginConfig("helloworld", "lastwho", who) dockerCLI.ConfigFile().SetPluginConfig("helloworld", "lastwho", who)
return dockerCli.ConfigFile().Save() return dockerCLI.ConfigFile().Save()
}, },
} }

View File

@ -11,8 +11,8 @@ func PrintNextSteps(out io.Writer, messages []string) {
if len(messages) == 0 { if len(messages) == 0 {
return return
} }
fmt.Fprintln(out, aec.Bold.Apply("\nWhat's next:")) _, _ = fmt.Fprintln(out, aec.Bold.Apply("\nWhat's next:"))
for _, n := range messages { for _, n := range messages {
_, _ = fmt.Fprintf(out, " %s\n", n) _, _ = fmt.Fprintln(out, " ", n)
} }
} }

View File

@ -20,7 +20,7 @@ func TestConfig(t *testing.T) {
res := icmd.RunCmd(run("helloworld")) res := icmd.RunCmd(run("helloworld"))
res.Assert(t, icmd.Expected{ res.Assert(t, icmd.Expected{
ExitCode: 0, ExitCode: 0,
Out: "Hello Cambridge!", Out: "Hello Cambridge",
}) })
cfg2, err := config.Load(filepath.Dir(cfg.GetFilename())) cfg2, err := config.Load(filepath.Dir(cfg.GetFilename()))

View File

@ -6,8 +6,6 @@ import (
"testing" "testing"
"github.com/docker/cli/cli-plugins/manager" "github.com/docker/cli/cli-plugins/manager"
"gotest.tools/v3/assert"
is "gotest.tools/v3/assert/cmp"
"gotest.tools/v3/icmd" "gotest.tools/v3/icmd"
) )
@ -24,7 +22,9 @@ func TestCLIPluginDialStdio(t *testing.T) {
helloworld := filepath.Join(os.Getenv("DOCKER_CLI_E2E_PLUGINS_EXTRA_DIRS"), "docker-helloworld") helloworld := filepath.Join(os.Getenv("DOCKER_CLI_E2E_PLUGINS_EXTRA_DIRS"), "docker-helloworld")
cmd := icmd.Command(helloworld, "--config=blah", "--log-level", "debug", "helloworld", "--who=foo") cmd := icmd.Command(helloworld, "--config=blah", "--log-level", "debug", "helloworld", "--who=foo")
res := icmd.RunCmd(cmd, icmd.WithEnv(manager.ReexecEnvvar+"=/bin/true")) res := icmd.RunCmd(cmd, icmd.WithEnv(manager.ReexecEnvvar+"=/bin/true"))
res.Assert(t, icmd.Success) res.Assert(t, icmd.Expected{
assert.Assert(t, is.Contains(res.Stderr(), `msg="commandconn: starting /bin/true with [--config=blah --log-level debug system dial-stdio]"`)) ExitCode: 0,
assert.Assert(t, is.Equal(res.Stdout(), "Hello foo!\n")) Err: `msg="commandconn: starting /bin/true with [--config=blah --log-level debug system dial-stdio]"`,
Out: `Hello foo`,
})
} }

View File

@ -15,7 +15,7 @@ func TestRunGoodArgument(t *testing.T) {
res := icmd.RunCmd(run("helloworld", "--who", "Cleveland")) res := icmd.RunCmd(run("helloworld", "--who", "Cleveland"))
res.Assert(t, icmd.Expected{ res.Assert(t, icmd.Expected{
ExitCode: 0, ExitCode: 0,
Out: "Hello Cleveland!", Out: "Hello Cleveland",
}) })
} }
@ -33,25 +33,25 @@ func TestClashWithGlobalArgs(t *testing.T) {
{ {
name: "short-without-val", name: "short-without-val",
args: []string{"-D"}, args: []string{"-D"},
expectedOut: "Hello World!", expectedOut: "Hello World",
expectedErr: "Plugin debug mode enabled", expectedErr: "Plugin debug mode enabled",
}, },
{ {
name: "long-without-val", name: "long-without-val",
args: []string{"--debug"}, args: []string{"--debug"},
expectedOut: "Hello World!", expectedOut: "Hello World",
expectedErr: "Plugin debug mode enabled", expectedErr: "Plugin debug mode enabled",
}, },
{ {
name: "short-with-val", name: "short-with-val",
args: []string{"-c", "Christmas"}, args: []string{"-c", "Christmas"},
expectedOut: "Merry Christmas!", expectedOut: "Merry Christmas",
expectedErr: icmd.None, expectedErr: icmd.None,
}, },
{ {
name: "short-with-val", name: "short-with-val",
args: []string{"--context", "Christmas"}, args: []string{"--context", "Christmas"},
expectedOut: "Merry Christmas!", expectedOut: "Merry Christmas",
expectedErr: icmd.None, expectedErr: icmd.None,
}, },
} { } {
@ -220,7 +220,7 @@ func TestCliPluginsVersion(t *testing.T) {
name: "plugin-with-version", name: "plugin-with-version",
args: []string{"helloworld", "version"}, args: []string{"helloworld", "version"},
expCode: 0, expCode: 0,
expOut: "Hello World!", expOut: "Hello World",
expErr: icmd.None, expErr: icmd.None,
}, },
{ {

View File

@ -113,7 +113,7 @@ func RootCmd(dockerCli command.Cli) *cobra.Command {
select { select {
case <-done: case <-done:
case <-time.After(2 * time.Second): case <-time.After(2 * time.Second):
_, _ = fmt.Fprint(dockerCli.Err(), "timeout after 2 seconds") _, _ = fmt.Fprintln(dockerCli.Err(), "timeout after 2 seconds")
} }
return nil return nil
}, },

View File

@ -4,7 +4,6 @@ import (
"testing" "testing"
"gotest.tools/v3/assert" "gotest.tools/v3/assert"
is "gotest.tools/v3/assert/cmp"
"gotest.tools/v3/golden" "gotest.tools/v3/golden"
"gotest.tools/v3/icmd" "gotest.tools/v3/icmd"
) )
@ -123,7 +122,7 @@ func TestRunGood(t *testing.T) {
res := icmd.RunCmd(run("helloworld")) res := icmd.RunCmd(run("helloworld"))
res.Assert(t, icmd.Expected{ res.Assert(t, icmd.Expected{
ExitCode: 0, ExitCode: 0,
Out: "Hello World!", Out: "Hello World",
Err: icmd.None, Err: icmd.None,
}) })
} }
@ -218,18 +217,23 @@ func TestCliInitialized(t *testing.T) {
run, _, cleanup := prepare(t) run, _, cleanup := prepare(t)
defer cleanup() defer cleanup()
var apiversion string var apiVersion string
t.Run("withhook", func(t *testing.T) { t.Run("withhook", func(t *testing.T) {
res := icmd.RunCmd(run("helloworld", "--pre-run", "apiversion")) res := icmd.RunCmd(run("helloworld", "--pre-run", "apiversion"))
res.Assert(t, icmd.Success) res.Assert(t, icmd.Expected{
assert.Assert(t, res.Stdout() != "") ExitCode: 0,
apiversion = res.Stdout() Err: "Plugin PersistentPreRunE called",
assert.Assert(t, is.Equal(res.Stderr(), "Plugin PersistentPreRunE called")) })
apiVersion = res.Stdout()
assert.Assert(t, apiVersion != "")
}) })
t.Run("withouthook", func(t *testing.T) { t.Run("withouthook", func(t *testing.T) {
res := icmd.RunCmd(run("nopersistentprerun")) res := icmd.RunCmd(run("nopersistentprerun"))
res.Assert(t, icmd.Success) res.Assert(t, icmd.Expected{
assert.Assert(t, is.Equal(res.Stdout(), apiversion)) ExitCode: 0,
Err: icmd.None,
Out: apiVersion,
})
}) })
} }