From 99124087e065ae50f4f100a4b47a4c96f1e7e45f Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Mon, 10 Apr 2023 14:26:07 +0200 Subject: [PATCH 1/4] cli/command/formatter: export JSONFormat const Signed-off-by: Sebastiaan van Stijn (cherry picked from commit 1aaa179d9d1cd2d4c2ce5175a5aa0edfdc0139eb) Signed-off-by: Sebastiaan van Stijn --- cli/command/formatter/formatter.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cli/command/formatter/formatter.go b/cli/command/formatter/formatter.go index 715e9ea62b80..55c5ea6e0277 100644 --- a/cli/command/formatter/formatter.go +++ b/cli/command/formatter/formatter.go @@ -19,7 +19,7 @@ const ( JSONFormatKey = "json" DefaultQuietFormat = "{{.ID}}" - jsonFormat = "{{json .}}" + JSONFormat = "{{json .}}" ) // Format is the format string rendered using the Context @@ -62,7 +62,7 @@ func (c *Context) preFormat() { case c.Format.IsTable(): c.finalFormat = c.finalFormat[len(TableFormatKey):] case c.Format.IsJSON(): - c.finalFormat = jsonFormat + c.finalFormat = JSONFormat } c.finalFormat = strings.Trim(c.finalFormat, " ") From 2c1fde22398e18e83c949febaf189189c7e64e45 Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Sun, 9 Apr 2023 13:11:19 +0200 Subject: [PATCH 2/4] fix docker info --format=json not outputting json format The --format=json option was added for all inspect commands, but was not implemented for "docker info". This patch implements the missing option. Before this patch: docker info --format=json json With this patch applied: docker info --format=json {"ID":"80c2f18a-2c88-4e4a-ba69-dca0eea59835","Containers":7,"ContainersRunning":"..."} Signed-off-by: Sebastiaan van Stijn (cherry picked from commit 46234b82e2dbfff4c1243e02608850eddefbb162) Signed-off-by: Sebastiaan van Stijn --- cli/command/system/info.go | 11 +++++++---- cli/command/system/info_test.go | 5 +++++ docs/reference/commandline/info.md | 6 +++--- docs/reference/commandline/system_info.md | 6 +++--- 4 files changed, 18 insertions(+), 10 deletions(-) diff --git a/cli/command/system/info.go b/cli/command/system/info.go index 4bd3e0356540..d30f8b2dfbfa 100644 --- a/cli/command/system/info.go +++ b/cli/command/system/info.go @@ -12,7 +12,9 @@ import ( pluginmanager "github.com/docker/cli/cli-plugins/manager" "github.com/docker/cli/cli/command" "github.com/docker/cli/cli/command/completion" + "github.com/docker/cli/cli/command/formatter" "github.com/docker/cli/cli/debug" + flagsHelper "github.com/docker/cli/cli/flags" "github.com/docker/cli/templates" "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/swarm" @@ -62,10 +64,7 @@ func NewInfoCommand(dockerCli command.Cli) *cobra.Command { ValidArgsFunction: completion.NoComplete, } - flags := cmd.Flags() - - flags.StringVarP(&opts.format, "format", "f", "", "Format the output using the given Go template") - + cmd.Flags().StringVarP(&opts.format, "format", "f", "", flagsHelper.InspectFormatHelp) return cmd } @@ -507,6 +506,10 @@ func printServerWarningsLegacy(dockerCli command.Cli, info types.Info) { } func formatInfo(dockerCli command.Cli, info info, format string) error { + if format == formatter.JSONFormatKey { + format = formatter.JSONFormat + } + // Ensure slice/array fields render as `[]` not `null` if info.ClientInfo != nil && info.ClientInfo.Plugins == nil { info.ClientInfo.Plugins = make([]pluginmanager.Plugin, 0) diff --git a/cli/command/system/info_test.go b/cli/command/system/info_test.go index 199c93721da8..5df964006f25 100644 --- a/cli/command/system/info_test.go +++ b/cli/command/system/info_test.go @@ -396,6 +396,11 @@ func TestPrettyPrintInfo(t *testing.T) { assert.NilError(t, formatInfo(cli, 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")) + golden.Assert(t, cli.OutBuffer().String(), tc.jsonGolden+".json.golden") + assert.Check(t, is.Equal("", cli.ErrBuffer().String())) } }) } diff --git a/docs/reference/commandline/info.md b/docs/reference/commandline/info.md index 9a29bb358b24..d9668c995b1c 100644 --- a/docs/reference/commandline/info.md +++ b/docs/reference/commandline/info.md @@ -9,9 +9,9 @@ Display system-wide information ### Options -| Name | Type | Default | Description | -|:---------------------------------------|:---------|:--------|:----------------------------------------------| -| [`-f`](#format), [`--format`](#format) | `string` | | Format the output using the given Go template | +| Name | Type | Default | Description | +|:---------------------------------------|:---------|:--------|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| [`-f`](#format), [`--format`](#format) | `string` | | Format output using a custom template:
'json': Print in JSON format
'TEMPLATE': Print output using the given Go template.
Refer to https://docs.docker.com/go/formatting/ for more information about formatting output with templates | diff --git a/docs/reference/commandline/system_info.md b/docs/reference/commandline/system_info.md index 8ef2093a07d0..e85ace33824a 100644 --- a/docs/reference/commandline/system_info.md +++ b/docs/reference/commandline/system_info.md @@ -9,9 +9,9 @@ Display system-wide information ### Options -| Name | Type | Default | Description | -|:-----------------|:---------|:--------|:----------------------------------------------| -| `-f`, `--format` | `string` | | Format the output using the given Go template | +| Name | Type | Default | Description | +|:-----------------|:---------|:--------|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `-f`, `--format` | `string` | | Format output using a custom template:
'json': Print in JSON format
'TEMPLATE': Print output using the given Go template.
Refer to https://docs.docker.com/go/formatting/ for more information about formatting output with templates | From 9dfe5a29ee34d86c1c78a7fb2ada8698b56d58e0 Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Mon, 10 Apr 2023 02:11:17 +0200 Subject: [PATCH 3/4] cli/command/system: make default version template a const Signed-off-by: Sebastiaan van Stijn (cherry picked from commit 80640bca72371ea66f7972d0ecfe8862ef683a85) Signed-off-by: Sebastiaan van Stijn --- cli/command/system/version.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cli/command/system/version.go b/cli/command/system/version.go index 3ead03215c19..c0dd17bba62a 100644 --- a/cli/command/system/version.go +++ b/cli/command/system/version.go @@ -20,7 +20,7 @@ import ( "github.com/tonistiigi/go-rosetta" ) -var versionTemplate = `{{with .Client -}} +const defaultVersionTemplate = `{{with .Client -}} Client:{{if ne .Platform.Name ""}} {{.Platform.Name}}{{end}} Version: {{.Version}} API version: {{.APIVersion}}{{if ne .APIVersion .DefaultAPIVersion}} (downgraded from {{.DefaultAPIVersion}}){{end}} @@ -195,7 +195,7 @@ func prettyPrintVersion(dockerCli command.Cli, vd versionInfo, tmpl *template.Te func newVersionTemplate(templateFormat string) (*template.Template, error) { if templateFormat == "" { - templateFormat = versionTemplate + templateFormat = defaultVersionTemplate } tmpl := templates.New("version").Funcs(template.FuncMap{"getDetailsOrder": getDetailsOrder}) tmpl, err := tmpl.Parse(templateFormat) From f914316a972a096d8f79ca6257a566d503a11c13 Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Mon, 10 Apr 2023 02:27:01 +0200 Subject: [PATCH 4/4] fix docker version --format=json not outputting json format The --format=json option was added for all inspect commands, but was not implemented for "docker version". This patch implements the missing option. Before this patch: docker version --format=json json With this patch: docker version --format=json {"Client":{"Platform":{"Name":""},"Version":"24.0.0-dev","ApiVersion":"..."}} Signed-off-by: Sebastiaan van Stijn (cherry picked from commit 23bd746c43a2d191a0faad16cbc393402c59ade0) Signed-off-by: Sebastiaan van Stijn --- .../docker-client-version.json.golden | 1 + cli/command/system/version.go | 11 ++++-- cli/command/system/version_test.go | 37 ++++++++++++++----- docs/reference/commandline/version.md | 6 +-- 4 files changed, 38 insertions(+), 17 deletions(-) create mode 100644 cli/command/system/testdata/docker-client-version.json.golden diff --git a/cli/command/system/testdata/docker-client-version.json.golden b/cli/command/system/testdata/docker-client-version.json.golden new file mode 100644 index 000000000000..3a6688548ba2 --- /dev/null +++ b/cli/command/system/testdata/docker-client-version.json.golden @@ -0,0 +1 @@ +{"Client":{"Platform":{"Name":""},"Version":"18.99.5-ce","ApiVersion":"1.38","DefaultAPIVersion":"1.38","GitCommit":"deadbeef","GoVersion":"go1.10.2","Os":"linux","Arch":"amd64","BuildTime":"Wed May 30 22:21:05 2018","Context":"my-context"},"Server":{"Platform":{"Name":"Docker Enterprise Edition (EE) 2.0"},"Components":[{"Name":"Engine","Version":"17.06.2-ee-15","Details":{"ApiVersion":"1.30","Arch":"amd64","BuildTime":"Mon Jul 9 23:38:38 2018","Experimental":"false","GitCommit":"64ddfa6","GoVersion":"go1.8.7","MinAPIVersion":"1.12","Os":"linux"}},{"Name":"Universal Control Plane","Version":"17.06.2-ee-15","Details":{"ApiVersion":"1.30","Arch":"amd64","BuildTime":"Mon Jul 2 21:24:07 UTC 2018","GitCommit":"4513922","GoVersion":"go1.9.4","MinApiVersion":"1.20","Os":"linux","Version":"3.0.3-tp2"}},{"Name":"Kubernetes","Version":"1.8+","Details":{"buildDate":"2018-04-26T16:51:21Z","compiler":"gc","gitCommit":"8d637aedf46b9c21dde723e29c645b9f27106fa5","gitTreeState":"clean","gitVersion":"v1.8.11-docker-8d637ae","goVersion":"go1.8.3","major":"1","minor":"8+","platform":"linux/amd64"}},{"Name":"Calico","Version":"v3.0.8","Details":{"cni":"v2.0.6","kube-controllers":"v2.0.5","node":"v3.0.8"}}],"Version":"","ApiVersion":"","GitCommit":"","GoVersion":"","Os":"","Arch":""}} diff --git a/cli/command/system/version.go b/cli/command/system/version.go index c0dd17bba62a..712f0a934cef 100644 --- a/cli/command/system/version.go +++ b/cli/command/system/version.go @@ -11,7 +11,9 @@ import ( "github.com/docker/cli/cli" "github.com/docker/cli/cli/command" "github.com/docker/cli/cli/command/completion" + "github.com/docker/cli/cli/command/formatter" "github.com/docker/cli/cli/command/formatter/tabwriter" + flagsHelper "github.com/docker/cli/cli/flags" "github.com/docker/cli/cli/version" "github.com/docker/cli/templates" "github.com/docker/docker/api/types" @@ -101,9 +103,7 @@ func NewVersionCommand(dockerCli command.Cli) *cobra.Command { ValidArgsFunction: completion.NoComplete, } - flags := cmd.Flags() - flags.StringVarP(&opts.format, "format", "f", "", "Format the output using the given Go template") - + cmd.Flags().StringVarP(&opts.format, "format", "f", "", flagsHelper.InspectFormatHelp) return cmd } @@ -194,8 +194,11 @@ func prettyPrintVersion(dockerCli command.Cli, vd versionInfo, tmpl *template.Te } func newVersionTemplate(templateFormat string) (*template.Template, error) { - if templateFormat == "" { + switch templateFormat { + case "": templateFormat = defaultVersionTemplate + case formatter.JSONFormatKey: + templateFormat = formatter.JSONFormat } tmpl := templates.New("version").Funcs(template.FuncMap{"getDetailsOrder": getDetailsOrder}) tmpl, err := tmpl.Parse(templateFormat) diff --git a/cli/command/system/version_test.go b/cli/command/system/version_test.go index 3ddf643290b2..5d7483c66c31 100644 --- a/cli/command/system/version_test.go +++ b/cli/command/system/version_test.go @@ -6,12 +6,11 @@ import ( "strings" "testing" + "github.com/docker/cli/internal/test" + "github.com/docker/docker/api/types" "gotest.tools/v3/assert" is "gotest.tools/v3/assert/cmp" "gotest.tools/v3/golden" - - "github.com/docker/cli/internal/test" - "github.com/docker/docker/api/types" ) func TestVersionWithoutServer(t *testing.T) { @@ -30,7 +29,7 @@ func TestVersionWithoutServer(t *testing.T) { assert.Assert(t, !strings.Contains(out, "Server:"), "actual: %s", out) } -func TestVersionAlign(t *testing.T) { +func TestVersionFormat(t *testing.T) { vi := versionInfo{ Client: clientVersion{ Version: "18.99.5-ce", @@ -104,10 +103,28 @@ func TestVersionAlign(t *testing.T) { }, }) - cli := test.NewFakeCli(&fakeClient{}) - tmpl, err := newVersionTemplate("") - assert.NilError(t, err) - assert.NilError(t, prettyPrintVersion(cli, vi, tmpl)) - assert.Check(t, golden.String(cli.OutBuffer().String(), "docker-client-version.golden")) - assert.Check(t, is.Equal("", cli.ErrBuffer().String())) + t.Run("default", func(t *testing.T) { + cli := test.NewFakeCli(&fakeClient{}) + tmpl, err := newVersionTemplate("") + assert.NilError(t, err) + assert.NilError(t, prettyPrintVersion(cli, vi, tmpl)) + assert.Check(t, golden.String(cli.OutBuffer().String(), "docker-client-version.golden")) + assert.Check(t, is.Equal("", cli.ErrBuffer().String())) + }) + t.Run("json", func(t *testing.T) { + cli := test.NewFakeCli(&fakeClient{}) + tmpl, err := newVersionTemplate("json") + assert.NilError(t, err) + assert.NilError(t, prettyPrintVersion(cli, vi, tmpl)) + assert.Check(t, golden.String(cli.OutBuffer().String(), "docker-client-version.json.golden")) + assert.Check(t, is.Equal("", cli.ErrBuffer().String())) + }) + t.Run("json template", func(t *testing.T) { + cli := test.NewFakeCli(&fakeClient{}) + tmpl, err := newVersionTemplate("{{json .}}") + assert.NilError(t, err) + assert.NilError(t, prettyPrintVersion(cli, vi, tmpl)) + assert.Check(t, golden.String(cli.OutBuffer().String(), "docker-client-version.json.golden")) + assert.Check(t, is.Equal("", cli.ErrBuffer().String())) + }) } diff --git a/docs/reference/commandline/version.md b/docs/reference/commandline/version.md index 9128380c1e72..60a6ba905d17 100644 --- a/docs/reference/commandline/version.md +++ b/docs/reference/commandline/version.md @@ -5,9 +5,9 @@ Show the Docker version information ### Options -| Name | Type | Default | Description | -|:---------------------------------------|:---------|:--------|:----------------------------------------------| -| [`-f`](#format), [`--format`](#format) | `string` | | Format the output using the given Go template | +| Name | Type | Default | Description | +|:---------------------------------------|:---------|:--------|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| [`-f`](#format), [`--format`](#format) | `string` | | Format output using a custom template:
'json': Print in JSON format
'TEMPLATE': Print output using the given Go template.
Refer to https://docs.docker.com/go/formatting/ for more information about formatting output with templates |