mirror of https://github.com/docker/cli.git
Merge pull request #31599 from ripcurld0/diff_cmd_format
Use formatter in docker diff
This commit is contained in:
commit
e3596db1a2
|
@ -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
|
||||||
}
|
}
|
||||||
|
diffCtx := formatter.Context{
|
||||||
for _, change := range changes {
|
Output: dockerCli.Out(),
|
||||||
var kind string
|
Format: formatter.NewDiffFormat("{{.Type}} {{.Path}}"),
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
|
return formatter.DiffWrite(diffCtx, changes)
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
|
@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue