Skip to content

Commit

Permalink
Merge pull request moby#31599 from ripcurld0/diff_cmd_format
Browse files Browse the repository at this point in the history
Use formatter in docker diff
  • Loading branch information
mlaventure authored Mar 31, 2017
2 parents d57825c + 3dad39b commit 3d31198
Show file tree
Hide file tree
Showing 3 changed files with 136 additions and 17 deletions.
22 changes: 5 additions & 17 deletions cli/command/container/diff.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
package container

import (
"fmt"

"github.com/docker/docker/cli"
"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/spf13/cobra"
"golang.org/x/net/context"
Expand Down Expand Up @@ -40,19 +38,9 @@ func runDiff(dockerCli *command.DockerCli, opts *diffOptions) error {
if err != nil {
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 changes: 72 additions & 0 deletions cli/command/formatter/diff.go
Original file line number Diff line number Diff line change
@@ -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 changes: 59 additions & 0 deletions cli/command/formatter/diff_test.go
Original file line number Diff line number Diff line change
@@ -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)
}
}
}

0 comments on commit 3d31198

Please sign in to comment.