1
0
mirror of https://github.com/docker/cli.git synced 2026-01-13 18:22:35 +03:00

Merge pull request #6336 from thaJeztah/internalize_formatters

cli/command/*: deprecate formatting-related functions and types
This commit is contained in:
Sebastiaan van Stijn
2025-08-22 08:29:16 +02:00
committed by GitHub
36 changed files with 365 additions and 171 deletions

View File

@@ -11,7 +11,14 @@ const (
)
// NewFormat returns a format for use with a checkpoint Context
//
// Deprecated: this function was only used internally and will be removed in the next release.
func NewFormat(source string) formatter.Format {
return newFormat(source)
}
// newFormat returns a format for use with a checkpointContext.
func newFormat(source string) formatter.Format {
if source == formatter.TableFormatKey {
return defaultCheckpointFormat
}
@@ -19,7 +26,14 @@ func NewFormat(source string) formatter.Format {
}
// FormatWrite writes formatted checkpoints using the Context
func FormatWrite(ctx formatter.Context, checkpoints []checkpoint.Summary) error {
//
// Deprecated: this function was only used internally and will be removed in the next release.
func FormatWrite(fmtCtx formatter.Context, checkpoints []checkpoint.Summary) error {
return formatWrite(fmtCtx, checkpoints)
}
// formatWrite writes formatted checkpoints using the Context
func formatWrite(fmtCtx formatter.Context, checkpoints []checkpoint.Summary) error {
render := func(format func(subContext formatter.SubContext) error) error {
for _, cp := range checkpoints {
if err := format(&checkpointContext{c: cp}); err != nil {
@@ -28,7 +42,7 @@ func FormatWrite(ctx formatter.Context, checkpoints []checkpoint.Summary) error
}
return nil
}
return ctx.Write(newCheckpointContext(), render)
return fmtCtx.Write(newCheckpointContext(), render)
}
type checkpointContext struct {

View File

@@ -15,7 +15,7 @@ func TestCheckpointContextFormatWrite(t *testing.T) {
expected string
}{
{
formatter.Context{Format: NewFormat(defaultCheckpointFormat)},
formatter.Context{Format: newFormat(defaultCheckpointFormat)},
`CHECKPOINT NAME
checkpoint-1
checkpoint-2
@@ -23,14 +23,14 @@ checkpoint-3
`,
},
{
formatter.Context{Format: NewFormat("{{.Name}}")},
formatter.Context{Format: newFormat("{{.Name}}")},
`checkpoint-1
checkpoint-2
checkpoint-3
`,
},
{
formatter.Context{Format: NewFormat("{{.Name}}:")},
formatter.Context{Format: newFormat("{{.Name}}:")},
`checkpoint-1:
checkpoint-2:
checkpoint-3:
@@ -41,7 +41,7 @@ checkpoint-3:
for _, testcase := range cases {
out := bytes.NewBufferString("")
testcase.context.Output = out
err := FormatWrite(testcase.context, []checkpoint.Summary{
err := formatWrite(testcase.context, []checkpoint.Summary{
{Name: "checkpoint-1"},
{Name: "checkpoint-2"},
{Name: "checkpoint-3"},

View File

@@ -45,7 +45,7 @@ func runList(ctx context.Context, dockerCli command.Cli, container string, opts
cpCtx := formatter.Context{
Output: dockerCli.Out(),
Format: NewFormat(formatter.TableFormatKey),
Format: newFormat(formatter.TableFormatKey),
}
return FormatWrite(cpCtx, checkpoints)
return formatWrite(cpCtx, checkpoints)
}

View File

@@ -30,7 +30,14 @@ Data:
)
// NewFormat returns a Format for rendering using a config 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 configContext.
func newFormat(source string, quiet bool) formatter.Format {
switch source {
case formatter.PrettyFormatKey:
return configInspectPrettyTemplate
@@ -44,7 +51,14 @@ func NewFormat(source string, quiet bool) formatter.Format {
}
// FormatWrite writes the context
func FormatWrite(ctx formatter.Context, configs []swarm.Config) error {
//
// Deprecated: this function was only used internally and will be removed in the next release.
func FormatWrite(fmtCtx formatter.Context, configs []swarm.Config) error {
return formatWrite(fmtCtx, configs)
}
// formatWrite writes the context
func formatWrite(fmtCtx formatter.Context, configs []swarm.Config) error {
render := func(format func(subContext formatter.SubContext) error) error {
for _, config := range configs {
configCtx := &configContext{c: config}
@@ -54,7 +68,7 @@ func FormatWrite(ctx formatter.Context, configs []swarm.Config) error {
}
return nil
}
return ctx.Write(newConfigContext(), render)
return fmtCtx.Write(newConfigContext(), render)
}
func newConfigContext() *configContext {
@@ -115,9 +129,16 @@ func (c *configContext) Label(name string) string {
}
// InspectFormatWrite renders the context for a list of configs
func InspectFormatWrite(ctx formatter.Context, refs []string, getRef inspect.GetRefFunc) error {
if ctx.Format != configInspectPrettyTemplate {
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 configs
func inspectFormatWrite(fmtCtx formatter.Context, refs []string, getRef inspect.GetRefFunc) error {
if fmtCtx.Format != configInspectPrettyTemplate {
return inspect.Inspect(fmtCtx.Output, refs, string(fmtCtx.Format), getRef)
}
render := func(format func(subContext formatter.SubContext) error) error {
for _, ref := range refs {
@@ -135,7 +156,7 @@ func InspectFormatWrite(ctx formatter.Context, refs []string, getRef inspect.Get
}
return nil
}
return ctx.Write(&configInspectContext{}, render)
return fmtCtx.Write(&configInspectContext{}, render)
}
type configInspectContext struct {

View File

@@ -27,21 +27,21 @@ func TestConfigContextFormatWrite(t *testing.T) {
},
// Table format
{
formatter.Context{Format: NewFormat("table", false)},
formatter.Context{Format: newFormat("table", false)},
`ID NAME CREATED UPDATED
1 passwords Less than a second ago Less than a second ago
2 id_rsa Less than a second ago Less than a second ago
`,
},
{
formatter.Context{Format: NewFormat("table {{.Name}}", true)},
formatter.Context{Format: newFormat("table {{.Name}}", true)},
`NAME
passwords
id_rsa
`,
},
{
formatter.Context{Format: NewFormat("{{.ID}}-{{.Name}}", false)},
formatter.Context{Format: newFormat("{{.ID}}-{{.Name}}", false)},
`1-passwords
2-id_rsa
`,
@@ -64,7 +64,7 @@ id_rsa
t.Run(string(tc.context.Format), func(t *testing.T) {
var out bytes.Buffer
tc.context.Output = &out
if err := FormatWrite(tc.context, configs); err != nil {
if err := formatWrite(tc.context, configs); err != nil {
assert.ErrorContains(t, err, tc.expected)
} else {
assert.Equal(t, out.String(), tc.expected)

View File

@@ -63,10 +63,10 @@ func RunConfigInspect(ctx context.Context, dockerCLI command.Cli, opts InspectOp
configCtx := formatter.Context{
Output: dockerCLI.Out(),
Format: NewFormat(f, false),
Format: newFormat(f, false),
}
if err := InspectFormatWrite(configCtx, opts.Names, getRef); err != nil {
if err := inspectFormatWrite(configCtx, opts.Names, getRef); err != nil {
return cli.StatusError{StatusCode: 1, Status: err.Error()}
}
return nil

View File

@@ -68,7 +68,7 @@ func RunConfigList(ctx context.Context, dockerCLI command.Cli, options ListOptio
configCtx := formatter.Context{
Output: dockerCLI.Out(),
Format: NewFormat(format, options.Quiet),
Format: newFormat(format, options.Quiet),
}
return FormatWrite(configCtx, configs)
return formatWrite(configCtx, configs)
}

View File

@@ -20,7 +20,14 @@ const (
)
// NewHistoryFormat returns a format for rendering an HistoryContext
//
// Deprecated: this function was only used internally and will be removed in the next release.
func NewHistoryFormat(source string, quiet bool, human bool) formatter.Format {
return newHistoryFormat(source, quiet, human)
}
// newHistoryFormat returns a format for rendering a historyContext.
func newHistoryFormat(source string, quiet bool, human bool) formatter.Format {
if source == formatter.TableFormatKey {
switch {
case quiet:
@@ -36,10 +43,17 @@ func NewHistoryFormat(source string, quiet bool, human bool) formatter.Format {
}
// HistoryWrite writes the context
func HistoryWrite(ctx formatter.Context, human bool, histories []image.HistoryResponseItem) error {
//
// Deprecated: this function was only used internally and will be removed in the next release.
func HistoryWrite(fmtCtx formatter.Context, human bool, histories []image.HistoryResponseItem) error {
return historyWrite(fmtCtx, human, histories)
}
// historyWrite writes the context
func historyWrite(fmtCtx formatter.Context, human bool, histories []image.HistoryResponseItem) error {
render := func(format func(subContext formatter.SubContext) error) error {
for _, history := range histories {
historyCtx := &historyContext{trunc: ctx.Trunc, h: history, human: human}
historyCtx := &historyContext{trunc: fmtCtx.Trunc, h: history, human: human}
if err := format(historyCtx); err != nil {
return err
}
@@ -55,7 +69,7 @@ func HistoryWrite(ctx formatter.Context, human bool, histories []image.HistoryRe
"Size": formatter.SizeHeader,
"Comment": commentHeader,
}
return ctx.Write(historyCtx, render)
return fmtCtx.Write(historyCtx, render)
}
type historyContext struct {

View File

@@ -237,7 +237,7 @@ imageID6 17 years ago /bin/bash echo 183MB
}{
{
formatter.Context{
Format: NewHistoryFormat("table", false, true),
Format: newHistoryFormat("table", false, true),
Trunc: true,
Output: out,
},
@@ -245,7 +245,7 @@ imageID6 17 years ago /bin/bash echo 183MB
},
{
formatter.Context{
Format: NewHistoryFormat("table", false, true),
Format: newHistoryFormat("table", false, true),
Trunc: false,
Output: out,
},
@@ -255,7 +255,7 @@ imageID6 17 years ago /bin/bash echo 183MB
for _, tc := range cases {
t.Run(string(tc.context.Format), func(t *testing.T) {
err := HistoryWrite(tc.context, true, histories)
err := historyWrite(tc.context, true, histories)
assert.NilError(t, err)
assert.Equal(t, out.String(), tc.expected)
// Clean buffer

View File

@@ -77,8 +77,8 @@ func runHistory(ctx context.Context, dockerCli command.Cli, opts historyOptions)
historyCtx := formatter.Context{
Output: dockerCli.Out(),
Format: NewHistoryFormat(format, opts.quiet, opts.human),
Format: newHistoryFormat(format, opts.quiet, opts.human),
Trunc: !opts.noTrunc,
}
return HistoryWrite(historyCtx, opts.human, history)
return historyWrite(historyCtx, opts.human, history)
}

View File

@@ -17,8 +17,15 @@ const (
internalHeader = "INTERNAL"
)
// NewFormat returns a Format for rendering using a network Context
// NewFormat returns a Format for rendering using a network 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 [formatter.Format] for rendering a networkContext.
func newFormat(source string, quiet bool) formatter.Format {
switch source {
case formatter.TableFormatKey:
if quiet {
@@ -35,10 +42,17 @@ func NewFormat(source string, quiet bool) formatter.Format {
}
// FormatWrite writes the context
func FormatWrite(ctx formatter.Context, networks []network.Summary) error {
//
// Deprecated: this function was only used internally and will be removed in the next release.
func FormatWrite(fmtCtx formatter.Context, networks []network.Summary) error {
return formatWrite(fmtCtx, networks)
}
// formatWrite writes the context.
func formatWrite(fmtCtx formatter.Context, networks []network.Summary) error {
render := func(format func(subContext formatter.SubContext) error) error {
for _, nw := range networks {
networkCtx := &networkContext{trunc: ctx.Trunc, n: nw}
networkCtx := &networkContext{trunc: fmtCtx.Trunc, n: nw}
if err := format(networkCtx); err != nil {
return err
}
@@ -57,7 +71,7 @@ func FormatWrite(ctx formatter.Context, networks []network.Summary) error {
"Labels": formatter.LabelsHeader,
"CreatedAt": formatter.CreatedAtHeader,
}
return ctx.Write(&networkCtx, render)
return fmtCtx.Write(&networkCtx, render)
}
type networkContext struct {

View File

@@ -91,27 +91,27 @@ func TestNetworkContextWrite(t *testing.T) {
},
// Table format
{
formatter.Context{Format: NewFormat("table", false)},
formatter.Context{Format: newFormat("table", false)},
`NETWORK ID NAME DRIVER SCOPE
networkID1 foobar_baz foo local
networkID2 foobar_bar bar local
`,
},
{
formatter.Context{Format: NewFormat("table", true)},
formatter.Context{Format: newFormat("table", true)},
`networkID1
networkID2
`,
},
{
formatter.Context{Format: NewFormat("table {{.Name}}", false)},
formatter.Context{Format: newFormat("table {{.Name}}", false)},
`NAME
foobar_baz
foobar_bar
`,
},
{
formatter.Context{Format: NewFormat("table {{.Name}}", true)},
formatter.Context{Format: newFormat("table {{.Name}}", true)},
`NAME
foobar_baz
foobar_bar
@@ -119,7 +119,7 @@ foobar_bar
},
// Raw Format
{
formatter.Context{Format: NewFormat("raw", false)},
formatter.Context{Format: newFormat("raw", false)},
`network_id: networkID1
name: foobar_baz
driver: foo
@@ -133,21 +133,21 @@ scope: local
`,
},
{
formatter.Context{Format: NewFormat("raw", true)},
formatter.Context{Format: newFormat("raw", true)},
`network_id: networkID1
network_id: networkID2
`,
},
// Custom Format
{
formatter.Context{Format: NewFormat("{{.Name}}", false)},
formatter.Context{Format: newFormat("{{.Name}}", false)},
`foobar_baz
foobar_bar
`,
},
// Custom Format with CreatedAt
{
formatter.Context{Format: NewFormat("{{.Name}} {{.CreatedAt}}", false)},
formatter.Context{Format: newFormat("{{.Name}} {{.CreatedAt}}", false)},
`foobar_baz 2016-01-01 00:00:00 +0000 UTC
foobar_bar 2017-01-01 00:00:00 +0000 UTC
`,
@@ -166,7 +166,7 @@ foobar_bar 2017-01-01 00:00:00 +0000 UTC
t.Run(string(tc.context.Format), func(t *testing.T) {
var out bytes.Buffer
tc.context.Output = &out
err := FormatWrite(tc.context, networks)
err := formatWrite(tc.context, networks)
if err != nil {
assert.Error(t, err, tc.expected)
} else {
@@ -187,7 +187,7 @@ func TestNetworkContextWriteJSON(t *testing.T) {
}
out := bytes.NewBufferString("")
err := FormatWrite(formatter.Context{Format: "{{json .}}", Output: out}, networks)
err := formatWrite(formatter.Context{Format: "{{json .}}", Output: out}, networks)
if err != nil {
t.Fatal(err)
}
@@ -206,7 +206,7 @@ func TestNetworkContextWriteJSONField(t *testing.T) {
{ID: "networkID2", Name: "foobar_bar"},
}
out := bytes.NewBufferString("")
err := FormatWrite(formatter.Context{Format: "{{json .ID}}", Output: out}, networks)
err := formatWrite(formatter.Context{Format: "{{json .ID}}", Output: out}, networks)
if err != nil {
t.Fatal(err)
}

View File

@@ -67,8 +67,8 @@ func runList(ctx context.Context, dockerCli command.Cli, options listOptions) er
networksCtx := formatter.Context{
Output: dockerCli.Out(),
Format: NewFormat(format, options.quiet),
Format: newFormat(format, options.quiet),
Trunc: !options.noTrunc,
}
return FormatWrite(networksCtx, networkResources)
return formatWrite(networksCtx, networkResources)
}

View File

@@ -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 {

View File

@@ -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 {

View File

@@ -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

View File

@@ -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)
}

View File

@@ -21,7 +21,14 @@ enabled: {{.Enabled}}
)
// NewFormat returns a Format for rendering using a plugin 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 pluginContext.
func newFormat(source string, quiet bool) formatter.Format {
switch source {
case formatter.TableFormatKey:
if quiet {
@@ -38,10 +45,17 @@ func NewFormat(source string, quiet bool) formatter.Format {
}
// FormatWrite writes the context
func FormatWrite(ctx formatter.Context, plugins []*plugin.Plugin) error {
//
// Deprecated: this function was only used internally and will be removed in the next release.
func FormatWrite(fmtCtx formatter.Context, plugins []*plugin.Plugin) error {
return formatWrite(fmtCtx, plugins)
}
// formatWrite writes the context
func formatWrite(fmtCtx formatter.Context, plugins []*plugin.Plugin) error {
render := func(format func(subContext formatter.SubContext) error) error {
for _, p := range plugins {
pluginCtx := &pluginContext{trunc: ctx.Trunc, p: *p}
pluginCtx := &pluginContext{trunc: fmtCtx.Trunc, p: *p}
if err := format(pluginCtx); err != nil {
return err
}
@@ -56,7 +70,7 @@ func FormatWrite(ctx formatter.Context, plugins []*plugin.Plugin) error {
"Enabled": enabledHeader,
"PluginReference": formatter.ImageHeader,
}
return ctx.Write(&pluginCtx, render)
return fmtCtx.Write(&pluginCtx, render)
}
type pluginContext struct {

View File

@@ -86,7 +86,7 @@ func TestPluginContextWrite(t *testing.T) {
},
{
doc: "table format",
context: formatter.Context{Format: NewFormat("table", false)},
context: formatter.Context{Format: newFormat("table", false)},
expected: `ID NAME DESCRIPTION ENABLED
pluginID1 foobar_baz description 1 true
pluginID2 foobar_bar description 2 false
@@ -94,14 +94,14 @@ pluginID2 foobar_bar description 2 false
},
{
doc: "table format, quiet",
context: formatter.Context{Format: NewFormat("table", true)},
context: formatter.Context{Format: newFormat("table", true)},
expected: `pluginID1
pluginID2
`,
},
{
doc: "table format name col",
context: formatter.Context{Format: NewFormat("table {{.Name}}", false)},
context: formatter.Context{Format: newFormat("table {{.Name}}", false)},
expected: `NAME
foobar_baz
foobar_bar
@@ -109,7 +109,7 @@ foobar_bar
},
{
doc: "table format name col, quiet",
context: formatter.Context{Format: NewFormat("table {{.Name}}", true)},
context: formatter.Context{Format: newFormat("table {{.Name}}", true)},
expected: `NAME
foobar_baz
foobar_bar
@@ -117,7 +117,7 @@ foobar_bar
},
{
doc: "raw format",
context: formatter.Context{Format: NewFormat("raw", false)},
context: formatter.Context{Format: newFormat("raw", false)},
expected: `plugin_id: pluginID1
name: foobar_baz
description: description 1
@@ -132,14 +132,14 @@ enabled: false
},
{
doc: "raw format, quiet",
context: formatter.Context{Format: NewFormat("raw", true)},
context: formatter.Context{Format: newFormat("raw", true)},
expected: `plugin_id: pluginID1
plugin_id: pluginID2
`,
},
{
doc: "custom format",
context: formatter.Context{Format: NewFormat("{{.Name}}", false)},
context: formatter.Context{Format: newFormat("{{.Name}}", false)},
expected: `foobar_baz
foobar_bar
`,
@@ -156,7 +156,7 @@ foobar_bar
var out bytes.Buffer
tc.context.Output = &out
err := FormatWrite(tc.context, plugins)
err := formatWrite(tc.context, plugins)
if err != nil {
assert.Error(t, err, tc.expected)
} else {
@@ -177,7 +177,7 @@ func TestPluginContextWriteJSON(t *testing.T) {
}
out := bytes.NewBufferString("")
err := FormatWrite(formatter.Context{Format: "{{json .}}", Output: out}, plugins)
err := formatWrite(formatter.Context{Format: "{{json .}}", Output: out}, plugins)
if err != nil {
t.Fatal(err)
}
@@ -196,7 +196,7 @@ func TestPluginContextWriteJSONField(t *testing.T) {
{ID: "pluginID2", Name: "foobar_bar"},
}
out := bytes.NewBufferString("")
err := FormatWrite(formatter.Context{Format: "{{json .ID}}", Output: out}, plugins)
err := formatWrite(formatter.Context{Format: "{{json .ID}}", Output: out}, plugins)
if err != nil {
t.Fatal(err)
}

View File

@@ -66,8 +66,8 @@ func runList(ctx context.Context, dockerCli command.Cli, options listOptions) er
pluginsCtx := formatter.Context{
Output: dockerCli.Out(),
Format: NewFormat(format, options.quiet),
Format: newFormat(format, options.quiet),
Trunc: !options.noTrunc,
}
return FormatWrite(pluginsCtx, plugins)
return formatWrite(pluginsCtx, plugins)
}

View File

@@ -16,8 +16,15 @@ const (
automatedHeader = "AUTOMATED"
)
// NewSearchFormat returns a Format for rendering using a network Context
// NewSearchFormat returns a Format for rendering using a search Context
//
// Deprecated: this function was only used internally and will be removed in the next release.
func NewSearchFormat(source string) formatter.Format {
return newFormat(source)
}
// newFormat returns a Format for rendering using a searchContext.
func newFormat(source string) formatter.Format {
switch source {
case "", formatter.TableFormatKey:
return defaultSearchTableFormat
@@ -26,10 +33,17 @@ func NewSearchFormat(source string) formatter.Format {
}
// SearchWrite writes the context
func SearchWrite(ctx formatter.Context, results []registrytypes.SearchResult) error {
//
// Deprecated: this function was only used internally and will be removed in the next release.
func SearchWrite(fmtCtx formatter.Context, results []registrytypes.SearchResult) error {
return formatWrite(fmtCtx, results)
}
// formatWrite writes the context.
func formatWrite(fmtCtx formatter.Context, results []registrytypes.SearchResult) error {
render := func(format func(subContext formatter.SubContext) error) error {
for _, result := range results {
searchCtx := &searchContext{trunc: ctx.Trunc, s: result}
searchCtx := &searchContext{trunc: fmtCtx.Trunc, s: result}
if err := format(searchCtx); err != nil {
return err
}
@@ -43,7 +57,7 @@ func SearchWrite(ctx formatter.Context, results []registrytypes.SearchResult) er
"StarCount": starsHeader,
"IsOfficial": officialHeader,
}
return ctx.Write(&searchCtx, render)
return fmtCtx.Write(&searchCtx, render)
}
type searchContext struct {

View File

@@ -157,12 +157,12 @@ func TestSearchContextWrite(t *testing.T) {
},
{
doc: "Table format",
format: NewSearchFormat("table"),
format: newFormat("table"),
expected: string(golden.Get(t, "search-context-write-table.golden")),
},
{
doc: "Table format, single column",
format: NewSearchFormat("table {{.Name}}"),
format: newFormat("table {{.Name}}"),
expected: `NAME
result1
result2
@@ -170,14 +170,14 @@ result2
},
{
doc: "Custom format, single field",
format: NewSearchFormat("{{.Name}}"),
format: newFormat("{{.Name}}"),
expected: `result1
result2
`,
},
{
doc: "Custom Format, two columns",
format: NewSearchFormat("{{.Name}} {{.StarCount}}"),
format: newFormat("{{.Name}} {{.StarCount}}"),
expected: `result1 5000
result2 5
`,
@@ -192,7 +192,7 @@ result2 5
for _, tc := range cases {
t.Run(tc.doc, func(t *testing.T) {
var out bytes.Buffer
err := SearchWrite(formatter.Context{Format: tc.format, Output: &out}, results)
err := formatWrite(formatter.Context{Format: tc.format, Output: &out}, results)
if tc.expectedErr != "" {
assert.Check(t, is.Error(err, tc.expectedErr))
} else {

View File

@@ -74,10 +74,10 @@ func runSearch(ctx context.Context, dockerCli command.Cli, options searchOptions
searchCtx := formatter.Context{
Output: dockerCli.Out(),
Format: NewSearchFormat(options.format),
Format: newFormat(options.format),
Trunc: !options.noTrunc,
}
return SearchWrite(searchCtx, results)
return formatWrite(searchCtx, results)
}
// authConfigKey is the key used to store credentials for Docker Hub. It is

View File

@@ -29,7 +29,14 @@ Updated at: {{.UpdatedAt}}`
)
// NewFormat returns a Format for rendering using a secret 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 secretContext.
func newFormat(source string, quiet bool) formatter.Format {
switch source {
case formatter.PrettyFormatKey:
return secretInspectPrettyTemplate
@@ -43,7 +50,14 @@ func NewFormat(source string, quiet bool) formatter.Format {
}
// FormatWrite writes the context
func FormatWrite(ctx formatter.Context, secrets []swarm.Secret) error {
//
// Deprecated: this function was only used internally and will be removed in the next release.
func FormatWrite(fmtCtx formatter.Context, secrets []swarm.Secret) error {
return formatWrite(fmtCtx, secrets)
}
// formatWrite writes the context
func formatWrite(fmtCtx formatter.Context, secrets []swarm.Secret) error {
render := func(format func(subContext formatter.SubContext) error) error {
for _, secret := range secrets {
secretCtx := &secretContext{s: secret}
@@ -53,7 +67,7 @@ func FormatWrite(ctx formatter.Context, secrets []swarm.Secret) error {
}
return nil
}
return ctx.Write(newSecretContext(), render)
return fmtCtx.Write(newSecretContext(), render)
}
func newSecretContext() *secretContext {
@@ -122,9 +136,16 @@ func (c *secretContext) Label(name string) string {
}
// InspectFormatWrite renders the context for a list of secrets
func InspectFormatWrite(ctx formatter.Context, refs []string, getRef inspect.GetRefFunc) error {
if ctx.Format != secretInspectPrettyTemplate {
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 secrets.
func inspectFormatWrite(fmtCtx formatter.Context, refs []string, getRef inspect.GetRefFunc) error {
if fmtCtx.Format != secretInspectPrettyTemplate {
return inspect.Inspect(fmtCtx.Output, refs, string(fmtCtx.Format), getRef)
}
render := func(format func(subContext formatter.SubContext) error) error {
for _, ref := range refs {
@@ -142,7 +163,7 @@ func InspectFormatWrite(ctx formatter.Context, refs []string, getRef inspect.Get
}
return nil
}
return ctx.Write(&secretInspectContext{}, render)
return fmtCtx.Write(&secretInspectContext{}, render)
}
type secretInspectContext struct {

View File

@@ -27,21 +27,21 @@ func TestSecretContextFormatWrite(t *testing.T) {
},
// Table format
{
formatter.Context{Format: NewFormat("table", false)},
formatter.Context{Format: newFormat("table", false)},
`ID NAME DRIVER CREATED UPDATED
1 passwords Less than a second ago Less than a second ago
2 id_rsa Less than a second ago Less than a second ago
`,
},
{
formatter.Context{Format: NewFormat("table {{.Name}}", true)},
formatter.Context{Format: newFormat("table {{.Name}}", true)},
`NAME
passwords
id_rsa
`,
},
{
formatter.Context{Format: NewFormat("{{.ID}}-{{.Name}}", false)},
formatter.Context{Format: newFormat("{{.ID}}-{{.Name}}", false)},
`1-passwords
2-id_rsa
`,
@@ -65,7 +65,7 @@ id_rsa
var out bytes.Buffer
tc.context.Output = &out
if err := FormatWrite(tc.context, secrets); err != nil {
if err := formatWrite(tc.context, secrets); err != nil {
assert.Error(t, err, tc.expected)
} else {
assert.Equal(t, out.String(), tc.expected)

View File

@@ -61,10 +61,10 @@ func runSecretInspect(ctx context.Context, dockerCli command.Cli, opts inspectOp
secretCtx := formatter.Context{
Output: dockerCli.Out(),
Format: NewFormat(f, false),
Format: newFormat(f, false),
}
if err := InspectFormatWrite(secretCtx, opts.names, getRef); err != nil {
if err := inspectFormatWrite(secretCtx, opts.names, getRef); err != nil {
return cli.StatusError{StatusCode: 1, Status: err.Error()}
}
return nil

View File

@@ -66,7 +66,7 @@ func runSecretList(ctx context.Context, dockerCli command.Cli, options listOptio
secretCtx := formatter.Context{
Output: dockerCli.Out(),
Format: NewFormat(format, options.quiet),
Format: newFormat(format, options.quiet),
}
return FormatWrite(secretCtx, secrets)
return formatWrite(secretCtx, secrets)
}

View File

@@ -196,7 +196,14 @@ Ports:
`
// NewFormat returns a Format for rendering using a Context
//
// Deprecated: this function was only used internally and will be removed in the next release.
func NewFormat(source string) formatter.Format {
return newFormat(source)
}
// newFormat returns a Format for rendering using a Context.
func newFormat(source string) formatter.Format {
switch source {
case formatter.PrettyFormatKey:
return serviceInspectPrettyTemplate
@@ -218,9 +225,16 @@ func resolveNetworks(service swarm.Service, getNetwork inspect.GetRefFunc) map[s
}
// InspectFormatWrite renders the context for a list of services
func InspectFormatWrite(ctx formatter.Context, refs []string, getRef, getNetwork inspect.GetRefFunc) error {
if ctx.Format != serviceInspectPrettyTemplate {
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, getNetwork inspect.GetRefFunc) error {
return inspectFormatWrite(fmtCtx, refs, getRef, getNetwork)
}
// inspectFormatWrite renders the context for a list of services
func inspectFormatWrite(fmtCtx formatter.Context, refs []string, getRef, getNetwork inspect.GetRefFunc) error {
if fmtCtx.Format != serviceInspectPrettyTemplate {
return inspect.Inspect(fmtCtx.Output, refs, string(fmtCtx.Format), getRef)
}
render := func(format func(subContext formatter.SubContext) error) error {
for _, ref := range refs {
@@ -238,7 +252,7 @@ func InspectFormatWrite(ctx formatter.Context, refs []string, getRef, getNetwork
}
return nil
}
return ctx.Write(&serviceInspectContext{}, render)
return fmtCtx.Write(&serviceInspectContext{}, render)
}
type serviceInspectContext struct {

View File

@@ -97,10 +97,10 @@ func runInspect(ctx context.Context, dockerCli command.Cli, opts inspectOptions)
serviceCtx := formatter.Context{
Output: dockerCli.Out(),
Format: NewFormat(f),
Format: newFormat(f),
}
if err := InspectFormatWrite(serviceCtx, opts.refs, getRef, getNetwork); err != nil {
if err := inspectFormatWrite(serviceCtx, opts.refs, getRef, getNetwork); err != nil {
return cli.StatusError{StatusCode: 1, Status: err.Error()}
}
return nil

View File

@@ -131,7 +131,7 @@ func formatServiceInspect(t *testing.T, format formatter.Format, now time.Time)
Format: format,
}
err := InspectFormatWrite(ctx, []string{"de179gar9d0o7ltdybungplod"},
err := inspectFormatWrite(ctx, []string{"de179gar9d0o7ltdybungplod"},
func(ref string) (any, []byte, error) {
return s, nil, nil
},
@@ -149,12 +149,12 @@ func formatServiceInspect(t *testing.T, format formatter.Format, now time.Time)
}
func TestPrettyPrint(t *testing.T) {
s := formatServiceInspect(t, NewFormat("pretty"), time.Now())
s := formatServiceInspect(t, newFormat("pretty"), time.Now())
golden.Assert(t, s, "service-inspect-pretty.golden")
}
func TestPrettyPrintWithNoUpdateConfig(t *testing.T) {
s := formatServiceInspect(t, NewFormat("pretty"), time.Now())
s := formatServiceInspect(t, newFormat("pretty"), time.Now())
if strings.Contains(s, "UpdateStatus") {
t.Fatal("Pretty print failed before parsing UpdateStatus")
}
@@ -167,8 +167,8 @@ func TestJSONFormatWithNoUpdateConfig(t *testing.T) {
now := time.Now()
// s1: [{"ID":..}]
// s2: {"ID":..}
s1 := formatServiceInspect(t, NewFormat(""), now)
s2 := formatServiceInspect(t, NewFormat("{{json .}}"), now)
s1 := formatServiceInspect(t, newFormat(""), now)
s2 := formatServiceInspect(t, newFormat("{{json .}}"), now)
var m1Wrap []map[string]any
if err := json.Unmarshal([]byte(s1), &m1Wrap); err != nil {
t.Fatal(err)
@@ -185,7 +185,7 @@ func TestJSONFormatWithNoUpdateConfig(t *testing.T) {
}
func TestPrettyPrintWithConfigsAndSecrets(t *testing.T) {
s := formatServiceInspect(t, NewFormat("pretty"), time.Now())
s := formatServiceInspect(t, newFormat("pretty"), time.Now())
assert.Check(t, is.Contains(s, "Log Driver:"), "Pretty print missing Log Driver")
assert.Check(t, is.Contains(s, "Configs:"), "Pretty print missing configs")
assert.Check(t, is.Contains(s, "Secrets:"), "Pretty print missing secrets")

View File

@@ -23,7 +23,14 @@ const (
)
// NewTaskFormat returns a Format for rendering using a task Context
//
// Deprecated: this function was only used internally and will be removed in the next release.
func NewTaskFormat(source string, quiet bool) formatter.Format {
return newTaskFormat(source, quiet)
}
// newTaskFormat returns a Format for rendering using a taskContext.
func newTaskFormat(source string, quiet bool) formatter.Format {
switch source {
case formatter.TableFormatKey:
if quiet {
@@ -40,10 +47,17 @@ func NewTaskFormat(source string, quiet bool) formatter.Format {
}
// FormatWrite writes the context
func FormatWrite(ctx formatter.Context, tasks []swarm.Task, names map[string]string, nodes map[string]string) error {
//
// Deprecated: this function was only used internally and will be removed in the next release.
func FormatWrite(fmtCtx formatter.Context, tasks []swarm.Task, names map[string]string, nodes map[string]string) error {
return formatWrite(fmtCtx, tasks, names, nodes)
}
// formatWrite writes the context.
func formatWrite(fmtCtx formatter.Context, tasks []swarm.Task, names map[string]string, nodes map[string]string) error {
render := func(format func(subContext formatter.SubContext) error) error {
for _, task := range tasks {
taskCtx := &taskContext{trunc: ctx.Trunc, task: task, name: names[task.ID], node: nodes[task.ID]}
taskCtx := &taskContext{trunc: fmtCtx.Trunc, task: task, name: names[task.ID], node: nodes[task.ID]}
if err := format(taskCtx); err != nil {
return err
}
@@ -61,7 +75,7 @@ func FormatWrite(ctx formatter.Context, tasks []swarm.Task, names map[string]str
"Error": formatter.ErrorHeader,
"Ports": formatter.PortsHeader,
}
return ctx.Write(&taskCtx, render)
return fmtCtx.Write(&taskCtx, render)
}
type taskContext struct {

View File

@@ -27,30 +27,30 @@ func TestTaskContextWrite(t *testing.T) {
`template parsing error: template: :1:2: executing "" at <nil>: nil is not a command`,
},
{
formatter.Context{Format: NewTaskFormat("table", true)},
formatter.Context{Format: newTaskFormat("table", true)},
`taskID1
taskID2
`,
},
{
formatter.Context{Format: NewTaskFormat("table {{.Name}}\t{{.Node}}\t{{.Ports}}", false)},
formatter.Context{Format: newTaskFormat("table {{.Name}}\t{{.Node}}\t{{.Ports}}", false)},
string(golden.Get(t, "task-context-write-table-custom.golden")),
},
{
formatter.Context{Format: NewTaskFormat("table {{.Name}}", true)},
formatter.Context{Format: newTaskFormat("table {{.Name}}", true)},
`NAME
foobar_baz
foobar_bar
`,
},
{
formatter.Context{Format: NewTaskFormat("raw", true)},
formatter.Context{Format: newTaskFormat("raw", true)},
`id: taskID1
id: taskID2
`,
},
{
formatter.Context{Format: NewTaskFormat("{{.Name}} {{.Node}}", false)},
formatter.Context{Format: newTaskFormat("{{.Name}} {{.Node}}", false)},
`foobar_baz foo1
foobar_bar foo2
`,
@@ -75,7 +75,7 @@ foobar_bar foo2
var out bytes.Buffer
tc.context.Output = &out
if err := FormatWrite(tc.context, tasks, names, nodes); err != nil {
if err := formatWrite(tc.context, tasks, names, nodes); err != nil {
assert.Error(t, err, tc.expected)
} else {
assert.Equal(t, out.String(), tc.expected)
@@ -94,7 +94,7 @@ func TestTaskContextWriteJSONField(t *testing.T) {
"taskID2": "foobar_bar",
}
out := bytes.NewBufferString("")
err := FormatWrite(formatter.Context{Format: "{{json .ID}}", Output: out}, tasks, names, map[string]string{})
err := formatWrite(formatter.Context{Format: "{{json .ID}}", Output: out}, tasks, names, map[string]string{})
if err != nil {
t.Fatal(err)
}

View File

@@ -50,7 +50,7 @@ func Print(ctx context.Context, dockerCli command.Cli, tasks []swarm.Task, resol
tasksCtx := formatter.Context{
Output: dockerCli.Out(),
Format: NewTaskFormat(format, quiet),
Format: newTaskFormat(format, quiet),
Trunc: trunc,
}
@@ -75,7 +75,7 @@ func Print(ctx context.Context, dockerCli command.Cli, tasks []swarm.Task, resol
nodes[task.ID] = nodeValue
}
return FormatWrite(tasksCtx, tasks, names, nodes)
return formatWrite(tasksCtx, tasks, names, nodes)
}
// generateTaskNames generates names for the given tasks, and returns a copy of

View File

@@ -21,7 +21,15 @@ const (
// Name: name of the signed tag
// Digest: hex encoded digest of the contents
// Signers: list of entities who signed the tag
type SignedTagInfo struct {
//
// Deprecated: this type was only used internally and will be removed in the next release.
type SignedTagInfo = signedTagInfo
// signedTagInfo represents all formatted information needed to describe a signed tag:
// Name: name of the signed tag
// Digest: hex encoded digest of the contents
// Signers: list of entities who signed the tag
type signedTagInfo struct {
Name string
Digest string
Signers []string
@@ -30,23 +38,41 @@ type SignedTagInfo struct {
// SignerInfo represents all formatted information needed to describe a signer:
// Name: name of the signer role
// Keys: the keys associated with the signer
type SignerInfo struct {
//
// Deprecated: this type was only used internally and will be removed in the next release.
type SignerInfo = signerInfo
// signerInfo represents all formatted information needed to describe a signer:
// Name: name of the signer role
// Keys: the keys associated with the signer
type signerInfo struct {
Name string
Keys []string
}
// NewTrustTagFormat returns a Format for rendering using a trusted tag Context
//
// Deprecated: this function was only used internally and will be removed in the next release.
func NewTrustTagFormat() formatter.Format {
return defaultTrustTagTableFormat
}
// NewSignerInfoFormat returns a Format for rendering a signer role info Context
//
// Deprecated: this function was only used internally and will be removed in the next release.
func NewSignerInfoFormat() formatter.Format {
return defaultSignerInfoTableFormat
}
// TagWrite writes the context
func TagWrite(ctx formatter.Context, signedTagInfoList []SignedTagInfo) error {
//
// Deprecated: this function was only used internally and will be removed in the next release.
func TagWrite(fmtCtx formatter.Context, signedTagInfoList []signedTagInfo) error {
return tagWrite(fmtCtx, signedTagInfoList)
}
// tagWrite writes the context
func tagWrite(fmtCtx formatter.Context, signedTagInfoList []signedTagInfo) error {
render := func(format func(subContext formatter.SubContext) error) error {
for _, signedTag := range signedTagInfoList {
if err := format(&trustTagContext{s: signedTag}); err != nil {
@@ -61,12 +87,12 @@ func TagWrite(ctx formatter.Context, signedTagInfoList []SignedTagInfo) error {
"Digest": trustedDigestHeader,
"Signers": signersHeader,
}
return ctx.Write(&trustTagCtx, render)
return fmtCtx.Write(&trustTagCtx, render)
}
type trustTagContext struct {
formatter.HeaderContext
s SignedTagInfo
s signedTagInfo
}
// SignedTag returns the name of the signed tag
@@ -86,11 +112,18 @@ func (c *trustTagContext) Signers() string {
}
// SignerInfoWrite writes the context
func SignerInfoWrite(ctx formatter.Context, signerInfoList []SignerInfo) error {
//
// Deprecated: this function was only used internally and will be removed in the next release.
func SignerInfoWrite(fmtCtx formatter.Context, signerInfoList []signerInfo) error {
return signerInfoWrite(fmtCtx, signerInfoList)
}
// signerInfoWrite writes the context.
func signerInfoWrite(fmtCtx formatter.Context, signerInfoList []signerInfo) error {
render := func(format func(subContext formatter.SubContext) error) error {
for _, signerInfo := range signerInfoList {
if err := format(&signerInfoContext{
trunc: ctx.Trunc,
trunc: fmtCtx.Trunc,
s: signerInfo,
}); err != nil {
return err
@@ -103,13 +136,13 @@ func SignerInfoWrite(ctx formatter.Context, signerInfoList []SignerInfo) error {
"Signer": signerNameHeader,
"Keys": keysHeader,
}
return ctx.Write(&signerInfoCtx, render)
return fmtCtx.Write(&signerInfoCtx, render)
}
type signerInfoContext struct {
formatter.HeaderContext
trunc bool
s SignerInfo
s signerInfo
}
// Keys returns the sorted list of keys associated with the signer

View File

@@ -23,7 +23,7 @@ func TestTrustTag(t *testing.T) {
}{
{
trustTagContext{
s: SignedTagInfo{
s: signedTagInfo{
Name: trustedTag,
Digest: digest,
Signers: nil,
@@ -34,7 +34,7 @@ func TestTrustTag(t *testing.T) {
},
{
trustTagContext{
s: SignedTagInfo{
s: signedTagInfo{
Name: trustedTag,
Digest: digest,
Signers: nil,
@@ -46,7 +46,7 @@ func TestTrustTag(t *testing.T) {
// Empty signers makes a row with empty string
{
trustTagContext{
s: SignedTagInfo{
s: signedTagInfo{
Name: trustedTag,
Digest: digest,
Signers: nil,
@@ -57,7 +57,7 @@ func TestTrustTag(t *testing.T) {
},
{
trustTagContext{
s: SignedTagInfo{
s: signedTagInfo{
Name: trustedTag,
Digest: digest,
Signers: []string{"alice", "bob", "claire"},
@@ -69,7 +69,7 @@ func TestTrustTag(t *testing.T) {
// alphabetic signing on Signers
{
trustTagContext{
s: SignedTagInfo{
s: signedTagInfo{
Name: trustedTag,
Digest: digest,
Signers: []string{"claire", "bob", "alice"},
@@ -110,7 +110,7 @@ func TestTrustTagContextWrite(t *testing.T) {
// Table Format
{
formatter.Context{
Format: NewTrustTagFormat(),
Format: defaultTrustTagTableFormat,
},
`SIGNED TAG DIGEST SIGNERS
tag1 deadbeef alice
@@ -120,7 +120,7 @@ tag3 bbbbbbbb
},
}
signedTags := []SignedTagInfo{
signedTags := []signedTagInfo{
{Name: "tag1", Digest: "deadbeef", Signers: []string{"alice"}},
{Name: "tag2", Digest: "aaaaaaaa", Signers: []string{"alice", "bob"}},
{Name: "tag3", Digest: "bbbbbbbb", Signers: []string{}},
@@ -131,7 +131,7 @@ tag3 bbbbbbbb
var out bytes.Buffer
tc.context.Output = &out
if err := TagWrite(tc.context, signedTags); err != nil {
if err := tagWrite(tc.context, signedTags); err != nil {
assert.Error(t, err, tc.expected)
} else {
assert.Equal(t, out.String(), tc.expected)
@@ -140,7 +140,7 @@ tag3 bbbbbbbb
}
}
// With no trust data, the TagWrite will print an empty table:
// With no trust data, the formatWrite will print an empty table:
// it's up to the caller to decide whether or not to print this versus an error
func TestTrustTagContextEmptyWrite(t *testing.T) {
emptyCase := struct {
@@ -148,16 +148,16 @@ func TestTrustTagContextEmptyWrite(t *testing.T) {
expected string
}{
formatter.Context{
Format: NewTrustTagFormat(),
Format: defaultTrustTagTableFormat,
},
`SIGNED TAG DIGEST SIGNERS
`,
}
emptySignedTags := []SignedTagInfo{}
emptySignedTags := []signedTagInfo{}
out := bytes.NewBufferString("")
emptyCase.context.Output = out
err := TagWrite(emptyCase.context, emptySignedTags)
err := tagWrite(emptyCase.context, emptySignedTags)
assert.NilError(t, err)
assert.Check(t, is.Equal(emptyCase.expected, out.String()))
}
@@ -168,15 +168,15 @@ func TestSignerInfoContextEmptyWrite(t *testing.T) {
expected string
}{
formatter.Context{
Format: NewSignerInfoFormat(),
Format: defaultSignerInfoTableFormat,
},
`SIGNER KEYS
`,
}
emptySignerInfo := []SignerInfo{}
emptySignerInfo := []signerInfo{}
out := bytes.NewBufferString("")
emptyCase.context.Output = out
err := SignerInfoWrite(emptyCase.context, emptySignerInfo)
err := signerInfoWrite(emptyCase.context, emptySignerInfo)
assert.NilError(t, err)
assert.Check(t, is.Equal(emptyCase.expected, out.String()))
}
@@ -202,7 +202,7 @@ func TestSignerInfoContextWrite(t *testing.T) {
// Table Format
{
formatter.Context{
Format: NewSignerInfoFormat(),
Format: defaultSignerInfoTableFormat,
Trunc: true,
},
`SIGNER KEYS
@@ -214,7 +214,7 @@ eve foobarbazqux, key31, key32
// No truncation
{
formatter.Context{
Format: NewSignerInfoFormat(),
Format: defaultSignerInfoTableFormat,
},
`SIGNER KEYS
alice key11, key12
@@ -224,7 +224,7 @@ eve foobarbazquxquux, key31, key32
},
}
signerInfo := []SignerInfo{
signerInfo := []signerInfo{
{Name: "alice", Keys: []string{"key11", "key12"}},
{Name: "bob", Keys: []string{"key21"}},
{Name: "eve", Keys: []string{"key31", "key32", "foobarbazquxquux"}},
@@ -234,7 +234,7 @@ eve foobarbazquxquux, key31, key32
var out bytes.Buffer
tc.context.Output = &out
if err := SignerInfoWrite(tc.context, signerInfo); err != nil {
if err := signerInfoWrite(tc.context, signerInfo); err != nil {
assert.Error(t, err, tc.expected)
} else {
assert.Equal(t, out.String(), tc.expected)

View File

@@ -56,33 +56,33 @@ func printSortedAdminKeys(out io.Writer, adminRoles []client.RoleWithSignatures)
func printSignatures(out io.Writer, signatureRows []trustTagRow) error {
trustTagCtx := formatter.Context{
Output: out,
Format: NewTrustTagFormat(),
Format: defaultTrustTagTableFormat,
}
// convert the formatted type before printing
formattedTags := []SignedTagInfo{}
formattedTags := []signedTagInfo{}
for _, sigRow := range signatureRows {
formattedSigners := sigRow.Signers
if len(formattedSigners) == 0 {
formattedSigners = append(formattedSigners, fmt.Sprintf("(%s)", releasedRoleName))
}
formattedTags = append(formattedTags, SignedTagInfo{
formattedTags = append(formattedTags, signedTagInfo{
Name: sigRow.SignedTag,
Digest: sigRow.Digest,
Signers: formattedSigners,
})
}
return TagWrite(trustTagCtx, formattedTags)
return tagWrite(trustTagCtx, formattedTags)
}
func printSignerInfo(out io.Writer, roleToKeyIDs map[string][]string) error {
signerInfoCtx := formatter.Context{
Output: out,
Format: NewSignerInfoFormat(),
Format: defaultSignerInfoTableFormat,
Trunc: true,
}
formattedSignerInfo := []SignerInfo{}
formattedSignerInfo := []signerInfo{}
for name, keyIDs := range roleToKeyIDs {
formattedSignerInfo = append(formattedSignerInfo, SignerInfo{
formattedSignerInfo = append(formattedSignerInfo, signerInfo{
Name: name,
Keys: keyIDs,
})
@@ -90,5 +90,5 @@ func printSignerInfo(out io.Writer, roleToKeyIDs map[string][]string) error {
sort.Slice(formattedSignerInfo, func(i, j int) bool {
return sortorder.NaturalLess(formattedSignerInfo[i].Name, formattedSignerInfo[j].Name)
})
return SignerInfoWrite(signerInfoCtx, formattedSignerInfo)
return signerInfoWrite(signerInfoCtx, formattedSignerInfo)
}