diff --git a/images.go b/images.go index d3481fa..abc5831 100644 --- a/images.go +++ b/images.go @@ -1,6 +1,7 @@ package main import ( + "bytes" "encoding/json" "fmt" "io/ioutil" @@ -32,28 +33,10 @@ func (x *ImagesCommand) Execute(args []string) error { return fmt.Errorf("error reading all input", err) } - var images []Image - err = json.Unmarshal(stdin, &images) - - if err != nil { - return fmt.Errorf("Error reading JSON: ", err) - } + images, err := parseJSON(stdin) if imagesCommand.Dot { - fmt.Printf("digraph docker {\n") - - for _, image := range images { - if image.ParentId == "" { - fmt.Printf(" base -> \"%s\" [style=invis]\n", truncate(image.Id)) - } else { - fmt.Printf(" \"%s\" -> \"%s\"\n", truncate(image.ParentId), truncate(image.Id)) - } - if image.RepoTags[0] != ":" { - fmt.Printf(" \"%s\" [label=\"%s\\n%s\",shape=box,fillcolor=\"paleturquoise\",style=\"filled,rounded\"];\n", truncate(image.Id), truncate(image.Id), strings.Join(image.RepoTags, "\\n")) - } - } - - fmt.Printf(" base [style=invisible]\n}\n") + fmt.Printf(jsonToDot(images)) } else if imagesCommand.Tree { fmt.Println("Tree output not implemented yet.") } @@ -65,6 +48,39 @@ func truncate(id string) string { return id[0:12] } +func parseJSON(rawJSON []byte) (*[]Image, error) { + + var images []Image + err := json.Unmarshal(rawJSON, &images) + + if err != nil { + return nil, fmt.Errorf("Error reading JSON: ", err) + } + + return &images, nil +} + +func jsonToDot(images *[]Image) string { + + var buffer bytes.Buffer + buffer.WriteString("digraph docker {\n") + + for _, image := range *images { + if image.ParentId == "" { + buffer.WriteString(fmt.Sprintf(" base -> \"%s\" [style=invis]\n", truncate(image.Id))) + } else { + buffer.WriteString(fmt.Sprintf(" \"%s\" -> \"%s\"\n", truncate(image.ParentId), truncate(image.Id))) + } + if image.RepoTags[0] != ":" { + buffer.WriteString(fmt.Sprintf(" \"%s\" [label=\"%s\\n%s\",shape=box,fillcolor=\"paleturquoise\",style=\"filled,rounded\"];\n", truncate(image.Id), truncate(image.Id), strings.Join(image.RepoTags, "\\n"))) + } + } + + buffer.WriteString(" base [style=invisible]\n}\n") + + return buffer.String() +} + func init() { parser.AddCommand("images", "Visualize docker images.", diff --git a/images_test.go b/images_test.go new file mode 100644 index 0000000..13a86ea --- /dev/null +++ b/images_test.go @@ -0,0 +1,24 @@ +package main + +import ( + "testing" +) + +func Test_Dot(t *testing.T) { + json := `[{ "VirtualSize": 662553464, "Size": 662553464, "RepoTags": [ ":" ], "ParentId": "", "Id": "4c1208b690c68af3476b437e7bc2bcc460f062bda2094d2d8f21a7e70368d358", "Created": 1386114144 }]` + + expectedResult := `digraph docker { + base -> "4c1208b690c6" [style=invis] + base [style=invisible] +} +` + + im, _ := parseJSON([]byte(json)) + result := jsonToDot(im) + + if result == expectedResult { + t.Log("Pass") + } else { + t.Errorf("|%s| and |%s| are different.", result, expectedResult) + } +}