소스 검색

Add --json option to commands

- docker ps
- docker context ls

Signed-off-by: Ulysses Souza <[email protected]>
Ulysses Souza 5 년 전
부모
커밋
f6aad0d7b4
6개의 변경된 파일116개의 추가작업 그리고 26개의 파일을 삭제
  1. 26 0
      cli/cmd/context/ls.go
  2. 3 4
      cli/cmd/inspect.go
  3. 24 0
      cli/cmd/ps.go
  4. 11 11
      cli/cmd/testdata/inspect-out-id.golden
  5. 41 0
      formatter/json.go
  6. 11 11
      tests/e2e/testdata/inspect-id.golden

+ 26 - 0
cli/cmd/context/ls.go

@@ -29,6 +29,7 @@ package context
 
 import (
 	"context"
+	"errors"
 	"fmt"
 	"os"
 	"sort"
@@ -39,10 +40,19 @@ import (
 
 	apicontext "github.com/docker/api/context"
 	"github.com/docker/api/context/store"
+	"github.com/docker/api/formatter"
 )
 
 type lsOpts struct {
 	quiet bool
+	json  bool
+}
+
+func (o lsOpts) validate() error {
+	if o.quiet && o.json {
+		return errors.New(`cannot combine "quiet" and "json" options`)
+	}
+	return nil
 }
 
 func listCommand() *cobra.Command {
@@ -57,10 +67,17 @@ func listCommand() *cobra.Command {
 		},
 	}
 	cmd.Flags().BoolVarP(&opts.quiet, "quiet", "q", false, "Only show context names")
+	cmd.Flags().BoolVar(&opts.json, "json", false, "Format output as JSON")
+
 	return cmd
 }
 
 func runList(ctx context.Context, opts lsOpts) error {
+	err := opts.validate()
+	if err != nil {
+		return err
+	}
+
 	currentContext := apicontext.CurrentContext(ctx)
 	s := store.ContextStore(ctx)
 	contexts, err := s.List()
@@ -79,6 +96,15 @@ func runList(ctx context.Context, opts lsOpts) error {
 		return nil
 	}
 
+	if opts.json {
+		j, err := formatter.ToStandardJSON(contexts)
+		if err != nil {
+			return err
+		}
+		fmt.Println(j)
+		return nil
+	}
+
 	w := tabwriter.NewWriter(os.Stdout, 20, 1, 3, ' ', 0)
 	fmt.Fprintln(w, "NAME\tTYPE\tDESCRIPTION\tDOCKER ENDPOINT\tKUBERNETES ENDPOINT\tORCHESTRATOR")
 	format := "%s\t%s\t%s\t%s\t%s\t%s\n"

+ 3 - 4
cli/cmd/inspect.go

@@ -2,13 +2,13 @@ package cmd
 
 import (
 	"context"
-	"encoding/json"
 	"fmt"
 
 	"github.com/pkg/errors"
 	"github.com/spf13/cobra"
 
 	"github.com/docker/api/client"
+	"github.com/docker/api/formatter"
 )
 
 // InspectCommand inspects into containers
@@ -36,12 +36,11 @@ func runInspect(ctx context.Context, id string) error {
 		return err
 	}
 
-	b, err := json.MarshalIndent(container, "", "  ")
+	j, err := formatter.ToStandardJSON(container)
 	if err != nil {
 		return err
 	}
-	containerString := string(b)
-	fmt.Println(containerString)
+	fmt.Println(j)
 
 	return nil
 }

+ 24 - 0
cli/cmd/ps.go

@@ -11,11 +11,20 @@ import (
 
 	"github.com/docker/api/cli/formatter"
 	"github.com/docker/api/client"
+	formatter2 "github.com/docker/api/formatter"
 )
 
 type psOpts struct {
 	all   bool
 	quiet bool
+	json  bool
+}
+
+func (o psOpts) validate() error {
+	if o.quiet && o.json {
+		return errors.New(`cannot combine "quiet" and "json" options`)
+	}
+	return nil
 }
 
 // PsCommand lists containers
@@ -31,11 +40,17 @@ func PsCommand() *cobra.Command {
 
 	cmd.Flags().BoolVarP(&opts.quiet, "quiet", "q", false, "Only display IDs")
 	cmd.Flags().BoolVarP(&opts.all, "all", "a", false, "Show all containers (default shows just running)")
+	cmd.Flags().BoolVar(&opts.json, "json", false, "Format output as JSON")
 
 	return cmd
 }
 
 func runPs(ctx context.Context, opts psOpts) error {
+	err := opts.validate()
+	if err != nil {
+		return err
+	}
+
 	c, err := client.New(ctx)
 	if err != nil {
 		return errors.Wrap(err, "cannot connect to backend")
@@ -53,6 +68,15 @@ func runPs(ctx context.Context, opts psOpts) error {
 		return nil
 	}
 
+	if opts.json {
+		j, err := formatter2.ToStandardJSON(containers)
+		if err != nil {
+			return err
+		}
+		fmt.Println(j)
+		return nil
+	}
+
 	w := tabwriter.NewWriter(os.Stdout, 20, 1, 3, ' ', 0)
 	fmt.Fprintf(w, "CONTAINER ID\tIMAGE\tCOMMAND\tSTATUS\tPORTS\n")
 	format := "%s\t%s\t%s\t%s\t%s\n"

+ 11 - 11
cli/cmd/testdata/inspect-out-id.golden

@@ -1,13 +1,13 @@
 {
-  "ID": "id",
-  "Status": "",
-  "Image": "nginx",
-  "Command": "",
-  "CPUTime": 0,
-  "MemoryUsage": 0,
-  "MemoryLimit": 0,
-  "PidsCurrent": 0,
-  "PidsLimit": 0,
-  "Labels": null,
-  "Ports": null
+    "ID": "id",
+    "Status": "",
+    "Image": "nginx",
+    "Command": "",
+    "CPUTime": 0,
+    "MemoryUsage": 0,
+    "MemoryLimit": 0,
+    "PidsCurrent": 0,
+    "PidsLimit": 0,
+    "Labels": null,
+    "Ports": null
 }

+ 41 - 0
formatter/json.go

@@ -0,0 +1,41 @@
+/*
+	Copyright (c) 2020 Docker Inc.
+
+	Permission is hereby granted, free of charge, to any person
+	obtaining a copy of this software and associated documentation
+	files (the "Software"), to deal in the Software without
+	restriction, including without limitation the rights to use, copy,
+	modify, merge, publish, distribute, sublicense, and/or sell copies
+	of the Software, and to permit persons to whom the Software is
+	furnished to do so, subject to the following conditions:
+
+	The above copyright notice and this permission notice shall be
+	included in all copies or substantial portions of the Software.
+
+	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+	EXPRESS OR IMPLIED,
+	INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+	FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+	IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+	HOLDERS BE LIABLE FOR ANY CLAIM,
+	DAMAGES OR OTHER LIABILITY,
+	WHETHER IN AN ACTION OF CONTRACT,
+	TORT OR OTHERWISE,
+	ARISING FROM, OUT OF OR IN CONNECTION WITH
+	THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+package formatter
+
+import "encoding/json"
+
+const standardIndentation = "    "
+
+// ToStandardJSON return a string with the JSON representation of the interface{}
+func ToStandardJSON(i interface{}) (string, error) {
+	b, err := json.MarshalIndent(i, "", standardIndentation)
+	if err != nil {
+		return "", err
+	}
+	return string(b), nil
+}

+ 11 - 11
tests/e2e/testdata/inspect-id.golden

@@ -1,13 +1,13 @@
 {
-  "ID": "id",
-  "Status": "",
-  "Image": "nginx",
-  "Command": "",
-  "CPUTime": 0,
-  "MemoryUsage": 0,
-  "MemoryLimit": 0,
-  "PidsCurrent": 0,
-  "PidsLimit": 0,
-  "Labels": null,
-  "Ports": null
+    "ID": "id",
+    "Status": "",
+    "Image": "nginx",
+    "Command": "",
+    "CPUTime": 0,
+    "MemoryUsage": 0,
+    "MemoryLimit": 0,
+    "PidsCurrent": 0,
+    "PidsLimit": 0,
+    "Labels": null,
+    "Ports": null
 }