Pārlūkot izejas kodu

Add diff.compareEntry helper to compare attribute entries

- Use it to compare the entry attributes for all entry types.
  Allows comparing differences in file attributes among the
  contents of two directories. This is useful for verifying
  restored contents in end-to-end tests.

- Print message about modified entries only when both entries
  are files and they are being compared.
Julio Lopez 5 gadi atpakaļ
vecāks
revīzija
d3f324f59b
2 mainītis faili ar 58 papildinājumiem un 7 dzēšanām
  1. 1 1
      cli/command_diff.go
  2. 57 6
      internal/diff/diff.go

+ 1 - 1
cli/command_diff.go

@@ -38,7 +38,7 @@ func runDiffCommand(ctx context.Context, rep *repo.Repository) error {
 		return errors.New("arguments do diff must both be directories or both non-directories")
 	}
 
-	d, err := diff.NewComparer(rep, os.Stdout)
+	d, err := diff.NewComparer(os.Stdout)
 	if err != nil {
 		return err
 	}

+ 57 - 6
internal/diff/diff.go

@@ -13,7 +13,6 @@ import (
 
 	"github.com/kopia/kopia/fs"
 	"github.com/kopia/kopia/internal/kopialogging"
-	"github.com/kopia/kopia/repo"
 	"github.com/kopia/kopia/repo/object"
 )
 
@@ -21,7 +20,6 @@ var log = kopialogging.Logger("diff")
 
 // Comparer outputs diff information between two filesystems.
 type Comparer struct {
-	rep    *repo.Repository
 	out    io.Writer
 	tmpDir string
 
@@ -109,6 +107,8 @@ func (c *Comparer) compareEntry(ctx context.Context, e1, e2 fs.Entry, path strin
 		return nil
 	}
 
+	compareEntry(e1, e2, path, c.out)
+
 	dir1, isDir1 := e1.(fs.Directory)
 	dir2, isDir2 := e2.(fs.Directory)
 
@@ -128,10 +128,10 @@ func (c *Comparer) compareEntry(ctx context.Context, e1, e2 fs.Entry, path strin
 		return nil
 	}
 
-	c.output("changed %v at %v (size %v -> %v)\n", path, e2.ModTime().String(), e1.Size(), e2.Size())
-
 	if f1, ok := e1.(fs.File); ok {
 		if f2, ok := e2.(fs.File); ok {
+			c.output("changed %v at %v (size %v -> %v)\n", path, e2.ModTime().String(), e1.Size(), e2.Size())
+
 			if err := c.compareFiles(ctx, f1, f2, path); err != nil {
 				return err
 			}
@@ -141,6 +141,57 @@ func (c *Comparer) compareEntry(ctx context.Context, e1, e2 fs.Entry, path strin
 	return nil
 }
 
+func compareEntry(e1, e2 fs.Entry, fullpath string, out io.Writer) bool {
+	if e1 == e2 { // in particular e1 == nil && e2 == nil
+		return true
+	}
+
+	if e1 == nil {
+		fmt.Fprintln(out, fullpath, "does not exist in source directory")
+		return false
+	}
+
+	if e2 == nil {
+		fmt.Fprintln(out, fullpath, "does not exist in destination directory")
+		return false
+	}
+
+	equal := true
+
+	if m1, m2 := e1.Mode(), e2.Mode(); m1 != m2 {
+		equal = false
+
+		fmt.Fprintln(out, fullpath, "modes differ: ", m1, m2)
+	}
+
+	if s1, s2 := e1.Size(), e2.Size(); s1 != s2 {
+		equal = false
+
+		fmt.Fprintln(out, fullpath, "sizes differ: ", s1, s2)
+	}
+
+	if mt1, mt2 := e1.ModTime(), e2.ModTime(); !mt1.Equal(mt2) {
+		equal = false
+
+		fmt.Fprintln(out, fullpath, "modification times differ: ", mt1, mt2)
+	}
+
+	o1, o2 := e1.Owner(), e2.Owner()
+	if o1.UserID != o2.UserID {
+		equal = false
+
+		fmt.Fprintln(out, fullpath, "owner users differ: ", o1.UserID, o2.UserID)
+	}
+
+	if o1.GroupID != o2.GroupID {
+		equal = false
+
+		fmt.Fprintln(out, fullpath, "owner groups differ: ", o1.GroupID, o2.GroupID)
+	}
+
+	return equal
+}
+
 func (c *Comparer) compareDirectoryEntries(ctx context.Context, entries1, entries2 fs.Entries, dirPath string) error {
 	e1byname := map[string]fs.Entry{}
 	for _, e1 := range entries1 {
@@ -238,11 +289,11 @@ func (c *Comparer) output(msg string, args ...interface{}) {
 }
 
 // NewComparer creates a comparer for a given repository that will output the results to a given writer.
-func NewComparer(rep *repo.Repository, out io.Writer) (*Comparer, error) {
+func NewComparer(out io.Writer) (*Comparer, error) {
 	tmp, err := ioutil.TempDir("", "kopia")
 	if err != nil {
 		return nil, err
 	}
 
-	return &Comparer{rep: rep, out: out, tmpDir: tmp}, nil
+	return &Comparer{out: out, tmpDir: tmp}, nil
 }