From 155f7d9e2ba65d49de771baedbb1a8817fea29a4 Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Mon, 10 Apr 2023 16:48:22 +0200 Subject: [PATCH] cli/command/system: add utilities for printing Adding some utilities to print the output, to keep the linters happier without having to either suppress errors, or ignore them. Perhaps we should consider adding utilities for this on the "command.Streams" outputs. Signed-off-by: Sebastiaan van Stijn --- cli/command/system/info.go | 225 ++++++++++++++++---------------- cli/command/system/info_test.go | 6 +- 2 files changed, 119 insertions(+), 112 deletions(-) diff --git a/cli/command/system/info.go b/cli/command/system/info.go index 471d732104..153c968bd2 100644 --- a/cli/command/system/info.go +++ b/cli/command/system/info.go @@ -108,7 +108,7 @@ func runInfo(cmd *cobra.Command, dockerCli command.Cli, opts *infoOptions) error } else { // if a format is provided, print the error, as it may be hidden // otherwise if the template doesn't include the ServerErrors field. - fmt.Fprintln(dockerCli.Err(), err) + fprintln(dockerCli.Err(), err) } } } @@ -118,7 +118,7 @@ func runInfo(cmd *cobra.Command, dockerCli command.Cli, opts *infoOptions) error info.ClientInfo.APIVersion = dockerCli.CurrentVersion() return prettyPrintInfo(dockerCli, info) } - return formatInfo(dockerCli, info, opts.format) + return formatInfo(dockerCli.Out(), info, opts.format) } // placeHolders does a rudimentary match for possible placeholders in a @@ -163,26 +163,26 @@ func needsServerInfo(template string, info info) bool { func prettyPrintInfo(streams command.Streams, info info) error { // Only append the platform info if it's not empty, to prevent printing a trailing space. if p := info.clientPlatform(); p != "" { - _, _ = fmt.Fprintln(streams.Out(), "Client:", p) + fprintln(streams.Out(), "Client:", p) } else { - _, _ = fmt.Fprintln(streams.Out(), "Client:") + fprintln(streams.Out(), "Client:") } if info.ClientInfo != nil { prettyPrintClientInfo(streams, *info.ClientInfo) } for _, err := range info.ClientErrors { - fmt.Fprintln(streams.Err(), "ERROR:", err) + fprintln(streams.Err(), "ERROR:", err) } - fmt.Fprintln(streams.Out()) - fmt.Fprintln(streams.Out(), "Server:") + fprintln(streams.Out()) + fprintln(streams.Out(), "Server:") if info.Info != nil { for _, err := range prettyPrintServerInfo(streams, &info) { info.ServerErrors = append(info.ServerErrors, err.Error()) } } for _, err := range info.ServerErrors { - fmt.Fprintln(streams.Err(), "ERROR:", err) + fprintln(streams.Err(), "ERROR:", err) } if len(info.ServerErrors) > 0 || len(info.ClientErrors) > 0 { @@ -192,18 +192,17 @@ func prettyPrintInfo(streams command.Streams, info info) error { } func prettyPrintClientInfo(streams command.Streams, info clientInfo) { - output := streams.Out() - fprintlnNonEmpty(output, " Version: ", info.Version) - fmt.Fprintln(output, " Context: ", info.Context) - fmt.Fprintln(output, " Debug Mode:", info.Debug) + fprintlnNonEmpty(streams.Out(), " Version: ", info.Version) + fprintln(streams.Out(), " Context: ", info.Context) + fprintln(streams.Out(), " Debug Mode:", info.Debug) if len(info.Plugins) > 0 { - fmt.Fprintln(output, " Plugins:") + fprintln(streams.Out(), " Plugins:") for _, p := range info.Plugins { if p.Err == nil { - fmt.Fprintf(output, " %s: %s (%s)\n", p.Name, p.ShortDescription, p.Vendor) - fprintlnNonEmpty(output, " Version: ", p.Version) - fprintlnNonEmpty(output, " Path: ", p.Path) + fprintf(streams.Out(), " %s: %s (%s)\n", p.Name, p.ShortDescription, p.Vendor) + fprintlnNonEmpty(streams.Out(), " Version: ", p.Version) + fprintlnNonEmpty(streams.Out(), " Path: ", p.Path) } else { info.Warnings = append(info.Warnings, fmt.Sprintf("WARNING: Plugin %q is not valid: %s", p.Path, p.Err)) } @@ -211,7 +210,7 @@ func prettyPrintClientInfo(streams command.Streams, info clientInfo) { } if len(info.Warnings) > 0 { - fmt.Fprintln(streams.Err(), strings.Join(info.Warnings, "\n")) + fprintln(streams.Err(), strings.Join(info.Warnings, "\n")) } } @@ -220,38 +219,38 @@ func prettyPrintServerInfo(streams command.Streams, info *info) []error { var errs []error output := streams.Out() - fmt.Fprintln(output, " Containers:", info.Containers) - fmt.Fprintln(output, " Running:", info.ContainersRunning) - fmt.Fprintln(output, " Paused:", info.ContainersPaused) - fmt.Fprintln(output, " Stopped:", info.ContainersStopped) - fmt.Fprintln(output, " Images:", info.Images) + fprintln(output, " Containers:", info.Containers) + fprintln(output, " Running:", info.ContainersRunning) + fprintln(output, " Paused:", info.ContainersPaused) + fprintln(output, " Stopped:", info.ContainersStopped) + fprintln(output, " Images:", info.Images) fprintlnNonEmpty(output, " Server Version:", info.ServerVersion) fprintlnNonEmpty(output, " Storage Driver:", info.Driver) if info.DriverStatus != nil { for _, pair := range info.DriverStatus { - fmt.Fprintf(output, " %s: %s\n", pair[0], pair[1]) + fprintf(output, " %s: %s\n", pair[0], pair[1]) } } if info.SystemStatus != nil { for _, pair := range info.SystemStatus { - fmt.Fprintf(output, " %s: %s\n", pair[0], pair[1]) + fprintf(output, " %s: %s\n", pair[0], pair[1]) } } fprintlnNonEmpty(output, " Logging Driver:", info.LoggingDriver) fprintlnNonEmpty(output, " Cgroup Driver:", info.CgroupDriver) fprintlnNonEmpty(output, " Cgroup Version:", info.CgroupVersion) - fmt.Fprintln(output, " Plugins:") - fmt.Fprintln(output, " Volume:", strings.Join(info.Plugins.Volume, " ")) - fmt.Fprintln(output, " Network:", strings.Join(info.Plugins.Network, " ")) + fprintln(output, " Plugins:") + fprintln(output, " Volume:", strings.Join(info.Plugins.Volume, " ")) + fprintln(output, " Network:", strings.Join(info.Plugins.Network, " ")) if len(info.Plugins.Authorization) != 0 { - fmt.Fprintln(output, " Authorization:", strings.Join(info.Plugins.Authorization, " ")) + fprintln(output, " Authorization:", strings.Join(info.Plugins.Authorization, " ")) } - fmt.Fprintln(output, " Log:", strings.Join(info.Plugins.Log, " ")) + fprintln(output, " Log:", strings.Join(info.Plugins.Log, " ")) - fmt.Fprintln(output, " Swarm:", info.Swarm.LocalNodeState) + fprintln(output, " Swarm:", info.Swarm.LocalNodeState) printSwarmInfo(output, *info.Info) if len(info.Runtimes) > 0 { @@ -259,12 +258,12 @@ func prettyPrintServerInfo(streams command.Streams, info *info) []error { for name := range info.Runtimes { names = append(names, name) } - fmt.Fprintln(output, " Runtimes:", strings.Join(names, " ")) - fmt.Fprintln(output, " Default Runtime:", info.DefaultRuntime) + fprintln(output, " Runtimes:", strings.Join(names, " ")) + fprintln(output, " Default Runtime:", info.DefaultRuntime) } if info.OSType == "linux" { - fmt.Fprintln(output, " Init Binary:", info.InitBinary) + fprintln(output, " Init Binary:", info.InitBinary) for _, ci := range []struct { Name string @@ -274,23 +273,23 @@ func prettyPrintServerInfo(streams command.Streams, info *info) []error { {"runc", info.RuncCommit}, {"init", info.InitCommit}, } { - fmt.Fprintf(output, " %s version: %s", ci.Name, ci.Commit.ID) + fprintf(output, " %s version: %s", ci.Name, ci.Commit.ID) if ci.Commit.ID != ci.Commit.Expected { - fmt.Fprintf(output, " (expected: %s)", ci.Commit.Expected) + fprintf(output, " (expected: %s)", ci.Commit.Expected) } - fmt.Fprint(output, "\n") + fprintln(output) } if len(info.SecurityOptions) != 0 { if kvs, err := types.DecodeSecurityOptions(info.SecurityOptions); err != nil { errs = append(errs, err) } else { - fmt.Fprintln(output, " Security Options:") + fprintln(output, " Security Options:") for _, so := range kvs { - fmt.Fprintln(output, " "+so.Name) + fprintln(output, " "+so.Name) for _, o := range so.Options { switch o.Key { case "profile": - fmt.Fprintln(output, " Profile:", o.Value) + fprintln(output, " Profile:", o.Value) } } } @@ -300,25 +299,25 @@ func prettyPrintServerInfo(streams command.Streams, info *info) []error { // Isolation only has meaning on a Windows daemon. if info.OSType == "windows" { - fmt.Fprintln(output, " Default Isolation:", info.Isolation) + fprintln(output, " Default Isolation:", info.Isolation) } fprintlnNonEmpty(output, " Kernel Version:", info.KernelVersion) fprintlnNonEmpty(output, " Operating System:", info.OperatingSystem) fprintlnNonEmpty(output, " OSType:", info.OSType) fprintlnNonEmpty(output, " Architecture:", info.Architecture) - fmt.Fprintln(output, " CPUs:", info.NCPU) - fmt.Fprintln(output, " Total Memory:", units.BytesSize(float64(info.MemTotal))) + fprintln(output, " CPUs:", info.NCPU) + fprintln(output, " Total Memory:", units.BytesSize(float64(info.MemTotal))) fprintlnNonEmpty(output, " Name:", info.Name) fprintlnNonEmpty(output, " ID:", info.ID) - fmt.Fprintln(output, " Docker Root Dir:", info.DockerRootDir) - fmt.Fprintln(output, " Debug Mode:", info.Debug) + fprintln(output, " Docker Root Dir:", info.DockerRootDir) + fprintln(output, " Debug Mode:", info.Debug) if info.Debug { - fmt.Fprintln(output, " File Descriptors:", info.NFd) - fmt.Fprintln(output, " Goroutines:", info.NGoroutines) - fmt.Fprintln(output, " System Time:", info.SystemTime) - fmt.Fprintln(output, " EventsListeners:", info.NEventsListener) + fprintln(output, " File Descriptors:", info.NFd) + fprintln(output, " Goroutines:", info.NGoroutines) + fprintln(output, " System Time:", info.SystemTime) + fprintln(output, " EventsListeners:", info.NEventsListener) } fprintlnNonEmpty(output, " HTTP Proxy:", info.HTTPProxy) @@ -326,48 +325,48 @@ func prettyPrintServerInfo(streams command.Streams, info *info) []error { fprintlnNonEmpty(output, " No Proxy:", info.NoProxy) fprintlnNonEmpty(output, " Username:", info.UserName) if len(info.Labels) > 0 { - fmt.Fprintln(output, " Labels:") + fprintln(output, " Labels:") for _, lbl := range info.Labels { - fmt.Fprintln(output, " "+lbl) + fprintln(output, " "+lbl) } } - fmt.Fprintln(output, " Experimental:", info.ExperimentalBuild) + fprintln(output, " Experimental:", info.ExperimentalBuild) if info.RegistryConfig != nil && (len(info.RegistryConfig.InsecureRegistryCIDRs) > 0 || len(info.RegistryConfig.IndexConfigs) > 0) { - fmt.Fprintln(output, " Insecure Registries:") - for _, reg := range info.RegistryConfig.IndexConfigs { - if !reg.Secure { - fmt.Fprintln(output, " "+reg.Name) + fprintln(output, " Insecure Registries:") + for _, registryConfig := range info.RegistryConfig.IndexConfigs { + if !registryConfig.Secure { + fprintln(output, " "+registryConfig.Name) } } - for _, reg := range info.RegistryConfig.InsecureRegistryCIDRs { - mask, _ := reg.Mask.Size() - fmt.Fprintf(output, " %s/%d\n", reg.IP.String(), mask) + for _, registryConfig := range info.RegistryConfig.InsecureRegistryCIDRs { + mask, _ := registryConfig.Mask.Size() + fprintf(output, " %s/%d\n", registryConfig.IP.String(), mask) } } if info.RegistryConfig != nil && len(info.RegistryConfig.Mirrors) > 0 { - fmt.Fprintln(output, " Registry Mirrors:") + fprintln(output, " Registry Mirrors:") for _, mirror := range info.RegistryConfig.Mirrors { - fmt.Fprintln(output, " "+mirror) + fprintln(output, " "+mirror) } } - fmt.Fprintln(output, " Live Restore Enabled:", info.LiveRestoreEnabled) + fprintln(output, " Live Restore Enabled:", info.LiveRestoreEnabled) if info.ProductLicense != "" { - fmt.Fprintln(output, " Product License:", info.ProductLicense) + fprintln(output, " Product License:", info.ProductLicense) } if info.DefaultAddressPools != nil && len(info.DefaultAddressPools) > 0 { - fmt.Fprintln(output, " Default Address Pools:") + fprintln(output, " Default Address Pools:") for _, pool := range info.DefaultAddressPools { - fmt.Fprintf(output, " Base: %s, Size: %d\n", pool.Base, pool.Size) + fprintf(output, " Base: %s, Size: %d\n", pool.Base, pool.Size) } } - fmt.Fprint(output, "\n") + fprintln(output) printServerWarnings(streams.Err(), info) return errs } @@ -377,67 +376,67 @@ func printSwarmInfo(output io.Writer, info types.Info) { if info.Swarm.LocalNodeState == swarm.LocalNodeStateInactive || info.Swarm.LocalNodeState == swarm.LocalNodeStateLocked { return } - fmt.Fprintln(output, " NodeID:", info.Swarm.NodeID) + fprintln(output, " NodeID:", info.Swarm.NodeID) if info.Swarm.Error != "" { - fmt.Fprintln(output, " Error:", info.Swarm.Error) + fprintln(output, " Error:", info.Swarm.Error) } - fmt.Fprintln(output, " Is Manager:", info.Swarm.ControlAvailable) + fprintln(output, " Is Manager:", info.Swarm.ControlAvailable) if info.Swarm.Cluster != nil && info.Swarm.ControlAvailable && info.Swarm.Error == "" && info.Swarm.LocalNodeState != swarm.LocalNodeStateError { - fmt.Fprintln(output, " ClusterID:", info.Swarm.Cluster.ID) - fmt.Fprintln(output, " Managers:", info.Swarm.Managers) - fmt.Fprintln(output, " Nodes:", info.Swarm.Nodes) + fprintln(output, " ClusterID:", info.Swarm.Cluster.ID) + fprintln(output, " Managers:", info.Swarm.Managers) + fprintln(output, " Nodes:", info.Swarm.Nodes) var strAddrPool strings.Builder if info.Swarm.Cluster.DefaultAddrPool != nil { for _, p := range info.Swarm.Cluster.DefaultAddrPool { strAddrPool.WriteString(p + " ") } - fmt.Fprintln(output, " Default Address Pool:", strAddrPool.String()) - fmt.Fprintln(output, " SubnetSize:", info.Swarm.Cluster.SubnetSize) + fprintln(output, " Default Address Pool:", strAddrPool.String()) + fprintln(output, " SubnetSize:", info.Swarm.Cluster.SubnetSize) } if info.Swarm.Cluster.DataPathPort > 0 { - fmt.Fprintln(output, " Data Path Port:", info.Swarm.Cluster.DataPathPort) + fprintln(output, " Data Path Port:", info.Swarm.Cluster.DataPathPort) } - fmt.Fprintln(output, " Orchestration:") + fprintln(output, " Orchestration:") taskHistoryRetentionLimit := int64(0) if info.Swarm.Cluster.Spec.Orchestration.TaskHistoryRetentionLimit != nil { taskHistoryRetentionLimit = *info.Swarm.Cluster.Spec.Orchestration.TaskHistoryRetentionLimit } - fmt.Fprintln(output, " Task History Retention Limit:", taskHistoryRetentionLimit) - fmt.Fprintln(output, " Raft:") - fmt.Fprintln(output, " Snapshot Interval:", info.Swarm.Cluster.Spec.Raft.SnapshotInterval) + fprintln(output, " Task History Retention Limit:", taskHistoryRetentionLimit) + fprintln(output, " Raft:") + fprintln(output, " Snapshot Interval:", info.Swarm.Cluster.Spec.Raft.SnapshotInterval) if info.Swarm.Cluster.Spec.Raft.KeepOldSnapshots != nil { - fmt.Fprintf(output, " Number of Old Snapshots to Retain: %d\n", *info.Swarm.Cluster.Spec.Raft.KeepOldSnapshots) + fprintf(output, " Number of Old Snapshots to Retain: %d\n", *info.Swarm.Cluster.Spec.Raft.KeepOldSnapshots) } - fmt.Fprintln(output, " Heartbeat Tick:", info.Swarm.Cluster.Spec.Raft.HeartbeatTick) - fmt.Fprintln(output, " Election Tick:", info.Swarm.Cluster.Spec.Raft.ElectionTick) - fmt.Fprintln(output, " Dispatcher:") - fmt.Fprintln(output, " Heartbeat Period:", units.HumanDuration(info.Swarm.Cluster.Spec.Dispatcher.HeartbeatPeriod)) - fmt.Fprintln(output, " CA Configuration:") - fmt.Fprintln(output, " Expiry Duration:", units.HumanDuration(info.Swarm.Cluster.Spec.CAConfig.NodeCertExpiry)) - fmt.Fprintln(output, " Force Rotate:", info.Swarm.Cluster.Spec.CAConfig.ForceRotate) + fprintln(output, " Heartbeat Tick:", info.Swarm.Cluster.Spec.Raft.HeartbeatTick) + fprintln(output, " Election Tick:", info.Swarm.Cluster.Spec.Raft.ElectionTick) + fprintln(output, " Dispatcher:") + fprintln(output, " Heartbeat Period:", units.HumanDuration(info.Swarm.Cluster.Spec.Dispatcher.HeartbeatPeriod)) + fprintln(output, " CA Configuration:") + fprintln(output, " Expiry Duration:", units.HumanDuration(info.Swarm.Cluster.Spec.CAConfig.NodeCertExpiry)) + fprintln(output, " Force Rotate:", info.Swarm.Cluster.Spec.CAConfig.ForceRotate) if caCert := strings.TrimSpace(info.Swarm.Cluster.Spec.CAConfig.SigningCACert); caCert != "" { - fmt.Fprintf(output, " Signing CA Certificate: \n%s\n\n", caCert) + fprintf(output, " Signing CA Certificate: \n%s\n\n", caCert) } if len(info.Swarm.Cluster.Spec.CAConfig.ExternalCAs) > 0 { - fmt.Fprintln(output, " External CAs:") + fprintln(output, " External CAs:") for _, entry := range info.Swarm.Cluster.Spec.CAConfig.ExternalCAs { - fmt.Fprintf(output, " %s: %s\n", entry.Protocol, entry.URL) + fprintf(output, " %s: %s\n", entry.Protocol, entry.URL) } } - fmt.Fprintln(output, " Autolock Managers:", info.Swarm.Cluster.Spec.EncryptionConfig.AutoLockManagers) - fmt.Fprintln(output, " Root Rotation In Progress:", info.Swarm.Cluster.RootRotationInProgress) + fprintln(output, " Autolock Managers:", info.Swarm.Cluster.Spec.EncryptionConfig.AutoLockManagers) + fprintln(output, " Root Rotation In Progress:", info.Swarm.Cluster.RootRotationInProgress) } - fmt.Fprintln(output, " Node Address:", info.Swarm.NodeAddr) + fprintln(output, " Node Address:", info.Swarm.NodeAddr) if len(info.Swarm.RemoteManagers) > 0 { managers := []string{} for _, entry := range info.Swarm.RemoteManagers { managers = append(managers, entry.Addr) } sort.Strings(managers) - fmt.Fprintln(output, " Manager Addresses:") + fprintln(output, " Manager Addresses:") for _, entry := range managers { - fmt.Fprintf(output, " %s\n", entry) + fprintf(output, " %s\n", entry) } } } @@ -447,7 +446,7 @@ func printServerWarnings(stdErr io.Writer, info *info) { printSecurityOptionsWarnings(stdErr, *info.Info) } if len(info.Warnings) > 0 { - fmt.Fprintln(stdErr, strings.Join(info.Warnings, "\n")) + fprintln(stdErr, strings.Join(info.Warnings, "\n")) return } // daemon didn't return warnings. Fallback to old behavior @@ -487,38 +486,38 @@ func printServerWarningsLegacy(stdErr io.Writer, info types.Info) { return } if !info.MemoryLimit { - fmt.Fprintln(stdErr, "WARNING: No memory limit support") + fprintln(stdErr, "WARNING: No memory limit support") } if !info.SwapLimit { - fmt.Fprintln(stdErr, "WARNING: No swap limit support") + fprintln(stdErr, "WARNING: No swap limit support") } if !info.OomKillDisable && info.CgroupVersion != "2" { - fmt.Fprintln(stdErr, "WARNING: No oom kill disable support") + fprintln(stdErr, "WARNING: No oom kill disable support") } if !info.CPUCfsQuota { - fmt.Fprintln(stdErr, "WARNING: No cpu cfs quota support") + fprintln(stdErr, "WARNING: No cpu cfs quota support") } if !info.CPUCfsPeriod { - fmt.Fprintln(stdErr, "WARNING: No cpu cfs period support") + fprintln(stdErr, "WARNING: No cpu cfs period support") } if !info.CPUShares { - fmt.Fprintln(stdErr, "WARNING: No cpu shares support") + fprintln(stdErr, "WARNING: No cpu shares support") } if !info.CPUSet { - fmt.Fprintln(stdErr, "WARNING: No cpuset support") + fprintln(stdErr, "WARNING: No cpuset support") } if !info.IPv4Forwarding { - fmt.Fprintln(stdErr, "WARNING: IPv4 forwarding is disabled") + fprintln(stdErr, "WARNING: IPv4 forwarding is disabled") } if !info.BridgeNfIptables { - fmt.Fprintln(stdErr, "WARNING: bridge-nf-call-iptables is disabled") + fprintln(stdErr, "WARNING: bridge-nf-call-iptables is disabled") } if !info.BridgeNfIP6tables { - fmt.Fprintln(stdErr, "WARNING: bridge-nf-call-ip6tables is disabled") + fprintln(stdErr, "WARNING: bridge-nf-call-ip6tables is disabled") } } -func formatInfo(dockerCli command.Cli, info info, format string) error { +func formatInfo(output io.Writer, info info, format string) error { if format == formatter.JSONFormatKey { format = formatter.JSONFormat } @@ -535,13 +534,21 @@ func formatInfo(dockerCli command.Cli, info info, format string) error { Status: "template parsing error: " + err.Error(), } } - err = tmpl.Execute(dockerCli.Out(), info) - dockerCli.Out().Write([]byte{'\n'}) + err = tmpl.Execute(output, info) + fprintln(output) return err } +func fprintf(w io.Writer, format string, a ...any) { + _, _ = fmt.Fprintf(w, format, a...) +} + +func fprintln(w io.Writer, a ...any) { + _, _ = fmt.Fprintln(w, a...) +} + func fprintlnNonEmpty(w io.Writer, label, value string) { if value != "" { - fmt.Fprintln(w, label, value) + _, _ = fmt.Fprintln(w, label, value) } } diff --git a/cli/command/system/info_test.go b/cli/command/system/info_test.go index 5fc55ccd1e..4d3d2823a4 100644 --- a/cli/command/system/info_test.go +++ b/cli/command/system/info_test.go @@ -406,12 +406,12 @@ func TestPrettyPrintInfo(t *testing.T) { if tc.jsonGolden != "" { cli = test.NewFakeCli(&fakeClient{}) - assert.NilError(t, formatInfo(cli, tc.dockerInfo, "{{json .}}")) + assert.NilError(t, formatInfo(cli.Out(), tc.dockerInfo, "{{json .}}")) golden.Assert(t, cli.OutBuffer().String(), tc.jsonGolden+".json.golden") assert.Check(t, is.Equal("", cli.ErrBuffer().String())) cli = test.NewFakeCli(&fakeClient{}) - assert.NilError(t, formatInfo(cli, tc.dockerInfo, "json")) + assert.NilError(t, formatInfo(cli.Out(), tc.dockerInfo, "json")) golden.Assert(t, cli.OutBuffer().String(), tc.jsonGolden+".json.golden") assert.Check(t, is.Equal("", cli.ErrBuffer().String())) } @@ -473,7 +473,7 @@ func TestFormatInfo(t *testing.T) { Info: &sampleInfoNoSwarm, ClientInfo: &clientInfo{Debug: true}, } - err := formatInfo(cli, info, tc.template) + err := formatInfo(cli.Out(), info, tc.template) if tc.expectedOut != "" { assert.NilError(t, err) assert.Equal(t, cli.OutBuffer().String(), tc.expectedOut)