From c93a17481c6e896f66f24f37098b3c2b4edab2ee Mon Sep 17 00:00:00 2001 From: Dave Henderson Date: Mon, 30 Mar 2015 19:03:23 -0400 Subject: [PATCH] Adding --format/-f option to `inspect` subcommand Signed-off-by: Dave Henderson --- commands/commands.go | 7 +++ commands/inspect.go | 41 +++++++++++++--- commands/inspect_test.go | 102 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 143 insertions(+), 7 deletions(-) diff --git a/commands/commands.go b/commands/commands.go index 3e7455a113..cedd5d6adf 100644 --- a/commands/commands.go +++ b/commands/commands.go @@ -223,6 +223,13 @@ var Commands = []cli.Command{ Usage: "Inspect information about a machine", Description: "Argument is a machine name. Will use the active machine if none is provided.", Action: cmdInspect, + Flags: []cli.Flag{ + cli.StringFlag{ + Name: "format, f", + Usage: "Format the output using the given go template.", + Value: "", + }, + }, }, { Name: "ip", diff --git a/commands/inspect.go b/commands/inspect.go index 60d1e5ac8b..7aae28f000 100644 --- a/commands/inspect.go +++ b/commands/inspect.go @@ -3,17 +3,44 @@ package commands import ( "encoding/json" "fmt" + "os" + "text/template" log "github.com/Sirupsen/logrus" "github.com/codegangsta/cli" ) -func cmdInspect(c *cli.Context) { - prettyJSON, err := json.MarshalIndent(getHost(c), "", " ") - if err != nil { - log.Fatal(err) - } - - fmt.Println(string(prettyJSON)) +var funcMap = template.FuncMap{ + "json": func(v interface{}) string { + a, _ := json.Marshal(v) + return string(a) + }, + "prettyJSON": func(v interface{}) string { + a, _ := json.MarshalIndent(v, "", " ") + return string(a) + }, +} + +func cmdInspect(c *cli.Context) { + tmplString := c.String("format") + if tmplString != "" { + var tmpl *template.Template + var err error + if tmpl, err = template.New("").Funcs(funcMap).Parse(tmplString); err != nil { + log.Fatalf("Template parsing error: %v\n", err) + } + + if err := tmpl.Execute(os.Stderr, getHost(c)); err != nil { + log.Fatal(err) + } + os.Stderr.Write([]byte{'\n'}) + } else { + prettyJSON, err := json.MarshalIndent(getHost(c), "", " ") + if err != nil { + log.Fatal(err) + } + + fmt.Println(string(prettyJSON)) + } } diff --git a/commands/inspect_test.go b/commands/inspect_test.go index cdff10da75..2b36e4a58c 100644 --- a/commands/inspect_test.go +++ b/commands/inspect_test.go @@ -1 +1,103 @@ package commands + +import ( + "bytes" + "encoding/json" + "flag" + "io" + "os" + "strings" + "testing" + + "github.com/codegangsta/cli" + "github.com/docker/machine/libmachine" + "github.com/docker/machine/libmachine/auth" + "github.com/docker/machine/libmachine/engine" + "github.com/docker/machine/libmachine/swarm" + "github.com/stretchr/testify/assert" +) + +func TestCmdInspectFormat(t *testing.T) { + actual, host := runInspectCommand(t, []string{}) + expected, _ := json.MarshalIndent(host, "", " ") + assert.Equal(t, string(expected), actual) + + actual, _ = runInspectCommand(t, []string{"--format", "{{.DriverName}}"}) + assert.Equal(t, "none", actual) + + actual, _ = runInspectCommand(t, []string{"--format", "{{json .DriverName}}"}) + assert.Equal(t, "\"none\"", actual) + + actual, _ = runInspectCommand(t, []string{"--format", "{{prettyJSON .Driver}}"}) + assert.Equal(t, "{\n \"URL\": \"unix:///var/run/docker.sock\"\n}", actual) +} + +func runInspectCommand(t *testing.T, args []string) (string, *libmachine.Host) { + stdout := os.Stdout + stderr := os.Stderr + shell := os.Getenv("SHELL") + r, w, _ := os.Pipe() + + os.Stdout = w + os.Stderr = w + os.Setenv("MACHINE_STORAGE_PATH", TestStoreDir) + os.Setenv("SHELL", "/bin/bash") + + defer func() { + os.Setenv("MACHINE_STORAGE_PATH", "") + os.Setenv("SHELL", shell) + os.Stdout = stdout + os.Stderr = stderr + }() + + if err := clearHosts(); err != nil { + t.Fatal(err) + } + + store, sErr := getTestStore() + if sErr != nil { + t.Fatal(sErr) + } + + mcn, err := libmachine.New(store) + if err != nil { + t.Fatal(err) + } + + hostOptions := &libmachine.HostOptions{ + EngineOptions: &engine.EngineOptions{}, + SwarmOptions: &swarm.SwarmOptions{ + Master: false, + Discovery: "", + Address: "", + Host: "", + }, + AuthOptions: &auth.AuthOptions{}, + } + + flags := getTestDriverFlags() + _, err = mcn.Create("test-a", "none", hostOptions, flags) + if err != nil { + t.Fatal(err) + } + + outStr := make(chan string) + + go func() { + var testOutput bytes.Buffer + io.Copy(&testOutput, r) + outStr <- testOutput.String() + }() + + set := flag.NewFlagSet("inspect", 0) + set.String("format", "", "") + set.Parse(args) + c := cli.NewContext(nil, set, set) + cmdInspect(c) + + w.Close() + + out := <-outStr + + return strings.TrimSpace(out), getHost(c) +}