From 123ef81f7db4ec9e99083a8dc6aae00f3c9ecfcd Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Thu, 21 Aug 2025 14:36:20 +0200 Subject: [PATCH] cli/command/node: deprecate NewFormat, FormatWrite, InspectFormatWrite It's part of the presentation logic of the cli, and only used internally. We can consider providing utilities for these, but better as part of separate packages. Signed-off-by: Sebastiaan van Stijn --- cli/command/node/formatter.go | 33 ++++++++++++++++++++++++------ cli/command/node/formatter_test.go | 28 ++++++++++++------------- cli/command/node/inspect.go | 4 ++-- cli/command/node/list.go | 4 ++-- 4 files changed, 45 insertions(+), 24 deletions(-) diff --git a/cli/command/node/formatter.go b/cli/command/node/formatter.go index 58814874f..4111494ba 100644 --- a/cli/command/node/formatter.go +++ b/cli/command/node/formatter.go @@ -80,7 +80,14 @@ TLS Info: ) // NewFormat returns a Format for rendering using a node Context +// +// Deprecated: this function was only used internally and will be removed in the next release. func NewFormat(source string, quiet bool) formatter.Format { + return newFormat(source, quiet) +} + +// newFormat returns a Format for rendering using a nodeContext. +func newFormat(source string, quiet bool) formatter.Format { switch source { case formatter.PrettyFormatKey: return nodeInspectPrettyTemplate @@ -99,7 +106,14 @@ func NewFormat(source string, quiet bool) formatter.Format { } // FormatWrite writes the context -func FormatWrite(ctx formatter.Context, nodes []swarm.Node, info system.Info) error { +// +// Deprecated: this function was only used internally and will be removed in the next release. +func FormatWrite(fmtCtx formatter.Context, nodes []swarm.Node, info system.Info) error { + return formatWrite(fmtCtx, nodes, info) +} + +// formatWrite writes the context. +func formatWrite(fmtCtx formatter.Context, nodes []swarm.Node, info system.Info) error { render := func(format func(subContext formatter.SubContext) error) error { for _, node := range nodes { nodeCtx := &nodeContext{n: node, info: info} @@ -120,7 +134,7 @@ func FormatWrite(ctx formatter.Context, nodes []swarm.Node, info system.Info) er "EngineVersion": engineVersionHeader, "TLSStatus": tlsStatusHeader, } - return ctx.Write(&nodeCtx, render) + return fmtCtx.Write(&nodeCtx, render) } type nodeContext struct { @@ -180,9 +194,16 @@ func (c *nodeContext) EngineVersion() string { } // InspectFormatWrite renders the context for a list of nodes -func InspectFormatWrite(ctx formatter.Context, refs []string, getRef inspect.GetRefFunc) error { - if ctx.Format != nodeInspectPrettyTemplate { - return inspect.Inspect(ctx.Output, refs, string(ctx.Format), getRef) +// +// Deprecated: this function was only used internally and will be removed in the next release. +func InspectFormatWrite(fmtCtx formatter.Context, refs []string, getRef inspect.GetRefFunc) error { + return inspectFormatWrite(fmtCtx, refs, getRef) +} + +// inspectFormatWrite renders the context for a list of nodes. +func inspectFormatWrite(fmtCtx formatter.Context, refs []string, getRef inspect.GetRefFunc) error { + if fmtCtx.Format != nodeInspectPrettyTemplate { + return inspect.Inspect(fmtCtx.Output, refs, string(fmtCtx.Format), getRef) } render := func(format func(subContext formatter.SubContext) error) error { for _, ref := range refs { @@ -200,7 +221,7 @@ func InspectFormatWrite(ctx formatter.Context, refs []string, getRef inspect.Get } return nil } - return ctx.Write(&nodeInspectContext{}, render) + return fmtCtx.Write(&nodeInspectContext{}, render) } type nodeInspectContext struct { diff --git a/cli/command/node/formatter_test.go b/cli/command/node/formatter_test.go index 44abeb7a0..f842e4934 100644 --- a/cli/command/node/formatter_test.go +++ b/cli/command/node/formatter_test.go @@ -74,7 +74,7 @@ func TestNodeContextWrite(t *testing.T) { }, // Table format { - context: formatter.Context{Format: NewFormat("table", false)}, + context: formatter.Context{Format: newFormat("table", false)}, expected: `ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION nodeID1 foobar_baz Foo Drain Leader 18.03.0-ce nodeID2 foobar_bar Bar Active Reachable 1.2.3 @@ -82,7 +82,7 @@ nodeID3 foobar_boo Boo Active ` + "\n", // clusterInfo: swarm.ClusterInfo{TLSInfo: swarm.TLSInfo{TrustRoot: "hi"}}, }, { - context: formatter.Context{Format: NewFormat("table", true)}, + context: formatter.Context{Format: newFormat("table", true)}, expected: `nodeID1 nodeID2 nodeID3 @@ -90,7 +90,7 @@ nodeID3 clusterInfo: swarm.ClusterInfo{TLSInfo: swarm.TLSInfo{TrustRoot: "hi"}}, }, { - context: formatter.Context{Format: NewFormat("table {{.Hostname}}", false)}, + context: formatter.Context{Format: newFormat("table {{.Hostname}}", false)}, expected: `HOSTNAME foobar_baz foobar_bar @@ -99,7 +99,7 @@ foobar_boo clusterInfo: swarm.ClusterInfo{TLSInfo: swarm.TLSInfo{TrustRoot: "hi"}}, }, { - context: formatter.Context{Format: NewFormat("table {{.Hostname}}", true)}, + context: formatter.Context{Format: newFormat("table {{.Hostname}}", true)}, expected: `HOSTNAME foobar_baz foobar_bar @@ -108,7 +108,7 @@ foobar_boo clusterInfo: swarm.ClusterInfo{TLSInfo: swarm.TLSInfo{TrustRoot: "hi"}}, }, { - context: formatter.Context{Format: NewFormat("table {{.ID}}\t{{.Hostname}}\t{{.TLSStatus}}", false)}, + context: formatter.Context{Format: newFormat("table {{.ID}}\t{{.Hostname}}\t{{.TLSStatus}}", false)}, expected: `ID HOSTNAME TLS STATUS nodeID1 foobar_baz Needs Rotation nodeID2 foobar_bar Ready @@ -117,7 +117,7 @@ nodeID3 foobar_boo Unknown clusterInfo: swarm.ClusterInfo{TLSInfo: swarm.TLSInfo{TrustRoot: "hi"}}, }, { // no cluster TLS status info, TLS status for all nodes is unknown - context: formatter.Context{Format: NewFormat("table {{.ID}}\t{{.Hostname}}\t{{.TLSStatus}}", false)}, + context: formatter.Context{Format: newFormat("table {{.ID}}\t{{.Hostname}}\t{{.TLSStatus}}", false)}, expected: `ID HOSTNAME TLS STATUS nodeID1 foobar_baz Unknown nodeID2 foobar_bar Unknown @@ -127,7 +127,7 @@ nodeID3 foobar_boo Unknown }, // Raw Format { - context: formatter.Context{Format: NewFormat("raw", false)}, + context: formatter.Context{Format: newFormat("raw", false)}, expected: `node_id: nodeID1 hostname: foobar_baz status: Foo @@ -148,7 +148,7 @@ manager_status: ` + "\n\n", // to preserve whitespace clusterInfo: swarm.ClusterInfo{TLSInfo: swarm.TLSInfo{TrustRoot: "hi"}}, }, { - context: formatter.Context{Format: NewFormat("raw", true)}, + context: formatter.Context{Format: newFormat("raw", true)}, expected: `node_id: nodeID1 node_id: nodeID2 node_id: nodeID3 @@ -157,7 +157,7 @@ node_id: nodeID3 }, // Custom Format { - context: formatter.Context{Format: NewFormat("{{.Hostname}} {{.TLSStatus}}", false)}, + context: formatter.Context{Format: newFormat("{{.Hostname}} {{.TLSStatus}}", false)}, expected: `foobar_baz Needs Rotation foobar_bar Ready foobar_boo Unknown @@ -205,7 +205,7 @@ foobar_boo Unknown var out bytes.Buffer tc.context.Output = &out - err := FormatWrite(tc.context, nodes, system.Info{Swarm: swarm.Info{Cluster: &tc.clusterInfo}}) + err := formatWrite(tc.context, nodes, system.Info{Swarm: swarm.Info{Cluster: &tc.clusterInfo}}) if err != nil { assert.Error(t, err, tc.expected) } else { @@ -252,7 +252,7 @@ func TestNodeContextWriteJSON(t *testing.T) { {ID: "nodeID3", Description: swarm.NodeDescription{Hostname: "foobar_boo", Engine: swarm.EngineDescription{EngineVersion: "18.03.0-ce"}}}, } out := bytes.NewBufferString("") - err := FormatWrite(formatter.Context{Format: "{{json .}}", Output: out}, nodes, testcase.info) + err := formatWrite(formatter.Context{Format: "{{json .}}", Output: out}, nodes, testcase.info) if err != nil { t.Fatal(err) } @@ -272,7 +272,7 @@ func TestNodeContextWriteJSONField(t *testing.T) { {ID: "nodeID2", Description: swarm.NodeDescription{Hostname: "foobar_bar"}}, } out := bytes.NewBufferString("") - err := FormatWrite(formatter.Context{Format: "{{json .ID}}", Output: out}, nodes, system.Info{}) + err := formatWrite(formatter.Context{Format: "{{json .ID}}", Output: out}, nodes, system.Info{}) if err != nil { t.Fatal(err) } @@ -317,10 +317,10 @@ func TestNodeInspectWriteContext(t *testing.T) { } out := bytes.NewBufferString("") context := formatter.Context{ - Format: NewFormat("pretty", false), + Format: newFormat("pretty", false), Output: out, } - err := InspectFormatWrite(context, []string{"nodeID1"}, func(string) (any, []byte, error) { + err := inspectFormatWrite(context, []string{"nodeID1"}, func(string) (any, []byte, error) { return node, nil, nil }) if err != nil { diff --git a/cli/command/node/inspect.go b/cli/command/node/inspect.go index f293861d4..8f2519e04 100644 --- a/cli/command/node/inspect.go +++ b/cli/command/node/inspect.go @@ -66,10 +66,10 @@ func runInspect(ctx context.Context, dockerCli command.Cli, opts inspectOptions) nodeCtx := formatter.Context{ Output: dockerCli.Out(), - Format: NewFormat(f, false), + Format: newFormat(f, false), } - if err := InspectFormatWrite(nodeCtx, opts.nodeIds, getRef); err != nil { + if err := inspectFormatWrite(nodeCtx, opts.nodeIds, getRef); err != nil { return cli.StatusError{StatusCode: 1, Status: err.Error()} } return nil diff --git a/cli/command/node/list.go b/cli/command/node/list.go index 8e9df4113..77adb09e4 100644 --- a/cli/command/node/list.go +++ b/cli/command/node/list.go @@ -79,10 +79,10 @@ func runList(ctx context.Context, dockerCli command.Cli, options listOptions) er nodesCtx := formatter.Context{ Output: dockerCli.Out(), - Format: NewFormat(format, options.quiet), + Format: newFormat(format, options.quiet), } sort.Slice(nodes, func(i, j int) bool { return sortorder.NaturalLess(nodes[i].Description.Hostname, nodes[j].Description.Hostname) }) - return FormatWrite(nodesCtx, nodes, info) + return formatWrite(nodesCtx, nodes, info) }