浏览代码

Use formatter in docker diff

Signed-off-by: Boaz Shuster <ripcurld.github@gmail.com>
Boaz Shuster 8 年之前
父节点
当前提交
3dad39b957
共有 3 个文件被更改,包括 136 次插入17 次删除
  1. 5 17
      cli/command/container/diff.go
  2. 72 0
      cli/command/formatter/diff.go
  3. 59 0
      cli/command/formatter/diff_test.go

+ 5 - 17
cli/command/container/diff.go

@@ -1,11 +1,9 @@
 package container
 package container
 
 
 import (
 import (
-	"fmt"
-
 	"github.com/docker/docker/cli"
 	"github.com/docker/docker/cli"
 	"github.com/docker/docker/cli/command"
 	"github.com/docker/docker/cli/command"
-	"github.com/docker/docker/pkg/archive"
+	"github.com/docker/docker/cli/command/formatter"
 	"github.com/pkg/errors"
 	"github.com/pkg/errors"
 	"github.com/spf13/cobra"
 	"github.com/spf13/cobra"
 	"golang.org/x/net/context"
 	"golang.org/x/net/context"
@@ -40,19 +38,9 @@ func runDiff(dockerCli *command.DockerCli, opts *diffOptions) error {
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}
-
-	for _, change := range changes {
-		var kind string
-		switch change.Kind {
-		case archive.ChangeModify:
-			kind = "C"
-		case archive.ChangeAdd:
-			kind = "A"
-		case archive.ChangeDelete:
-			kind = "D"
-		}
-		fmt.Fprintln(dockerCli.Out(), kind, change.Path)
+	diffCtx := formatter.Context{
+		Output: dockerCli.Out(),
+		Format: formatter.NewDiffFormat("{{.Type}} {{.Path}}"),
 	}
 	}
-
-	return nil
+	return formatter.DiffWrite(diffCtx, changes)
 }
 }

+ 72 - 0
cli/command/formatter/diff.go

@@ -0,0 +1,72 @@
+package formatter
+
+import (
+	"github.com/docker/docker/api/types/container"
+	"github.com/docker/docker/pkg/archive"
+)
+
+const (
+	defaultDiffTableFormat = "table {{.Type}}\t{{.Path}}"
+
+	changeTypeHeader = "CHANGE TYPE"
+	pathHeader       = "PATH"
+)
+
+// NewDiffFormat returns a format for use with a diff Context
+func NewDiffFormat(source string) Format {
+	switch source {
+	case TableFormatKey:
+		return defaultDiffTableFormat
+	}
+	return Format(source)
+}
+
+// DiffWrite writes formatted diff using the Context
+func DiffWrite(ctx Context, changes []container.ContainerChangeResponseItem) error {
+
+	render := func(format func(subContext subContext) error) error {
+		for _, change := range changes {
+			if err := format(&diffContext{c: change}); err != nil {
+				return err
+			}
+		}
+		return nil
+	}
+	return ctx.Write(newDiffContext(), render)
+}
+
+type diffContext struct {
+	HeaderContext
+	c container.ContainerChangeResponseItem
+}
+
+func newDiffContext() *diffContext {
+	diffCtx := diffContext{}
+	diffCtx.header = map[string]string{
+		"Type": changeTypeHeader,
+		"Path": pathHeader,
+	}
+	return &diffCtx
+}
+
+func (d *diffContext) MarshalJSON() ([]byte, error) {
+	return marshalJSON(d)
+}
+
+func (d *diffContext) Type() string {
+	var kind string
+	switch d.c.Kind {
+	case archive.ChangeModify:
+		kind = "C"
+	case archive.ChangeAdd:
+		kind = "A"
+	case archive.ChangeDelete:
+		kind = "D"
+	}
+	return kind
+
+}
+
+func (d *diffContext) Path() string {
+	return d.c.Path
+}

+ 59 - 0
cli/command/formatter/diff_test.go

@@ -0,0 +1,59 @@
+package formatter
+
+import (
+	"bytes"
+	"testing"
+
+	"github.com/docker/docker/api/types/container"
+	"github.com/docker/docker/pkg/archive"
+	"github.com/docker/docker/pkg/testutil/assert"
+)
+
+func TestDiffContextFormatWrite(t *testing.T) {
+	// Check default output format (verbose and non-verbose mode) for table headers
+	cases := []struct {
+		context  Context
+		expected string
+	}{
+		{
+			Context{Format: NewDiffFormat("table")},
+			`CHANGE TYPE         PATH
+C                   /var/log/app.log
+A                   /usr/app/app.js
+D                   /usr/app/old_app.js
+`,
+		},
+		{
+			Context{Format: NewDiffFormat("table {{.Path}}")},
+			`PATH
+/var/log/app.log
+/usr/app/app.js
+/usr/app/old_app.js
+`,
+		},
+		{
+			Context{Format: NewDiffFormat("{{.Type}}: {{.Path}}")},
+			`C: /var/log/app.log
+A: /usr/app/app.js
+D: /usr/app/old_app.js
+`,
+		},
+	}
+
+	diffs := []container.ContainerChangeResponseItem{
+		{archive.ChangeModify, "/var/log/app.log"},
+		{archive.ChangeAdd, "/usr/app/app.js"},
+		{archive.ChangeDelete, "/usr/app/old_app.js"},
+	}
+
+	for _, testcase := range cases {
+		out := bytes.NewBufferString("")
+		testcase.context.Output = out
+		err := DiffWrite(testcase.context, diffs)
+		if err != nil {
+			assert.Error(t, err, testcase.expected)
+		} else {
+			assert.Equal(t, out.String(), testcase.expected)
+		}
+	}
+}