-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdiff.go
More file actions
119 lines (102 loc) · 2.64 KB
/
diff.go
File metadata and controls
119 lines (102 loc) · 2.64 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
package main
import (
"fmt"
"path/filepath"
)
type diffKind int
const (
diffOnlyA diffKind = iota
diffOnlyB
diffChanged
diffSynced
)
type diffEntry struct {
kind diffKind
relPath string
entryA *fileEntry
entryB *fileEntry
details []string
docxDetails []docxFileDiff
}
func computeDiff(listA, listB []fileEntry, rootA, rootB string) []diffEntry {
mapA := make(map[string]*fileEntry, len(listA))
for i := range listA {
mapA[listA[i].relPath] = &listA[i]
}
mapB := make(map[string]*fileEntry, len(listB))
for i := range listB {
mapB[listB[i].relPath] = &listB[i]
}
seen := make(map[string]bool)
var diffs []diffEntry
for _, a := range listA {
seen[a.relPath] = true
b, inB := mapB[a.relPath]
if !inB {
diffs = append(diffs, diffEntry{
kind: diffOnlyA,
relPath: a.relPath,
entryA: mapA[a.relPath],
})
continue
}
changes, docxDets := compareEntries(mapA[a.relPath], b, rootA, rootB)
if len(changes) > 0 {
diffs = append(diffs, diffEntry{
kind: diffChanged,
relPath: a.relPath,
entryA: mapA[a.relPath],
entryB: b,
details: changes,
docxDetails: docxDets,
})
}
}
for _, b := range listB {
if !seen[b.relPath] {
diffs = append(diffs, diffEntry{
kind: diffOnlyB,
relPath: b.relPath,
entryB: mapB[b.relPath],
})
}
}
return diffs
}
func compareEntries(a, b *fileEntry, rootA, rootB string) ([]string, []docxFileDiff) {
var changes []string
var docxDets []docxFileDiff
if a.info.Mode() != b.info.Mode() {
changes = append(changes, fmt.Sprintf("mode: %s vs %s", a.info.Mode(), b.info.Mode()))
}
sizeDiffers := false
if !a.info.IsDir() && !b.info.IsDir() {
if useHashes {
if a.hash != b.hash {
changes = append(changes, fmt.Sprintf("hash: %s vs %s", a.hash[:12], b.hash[:12]))
if a.info.Size() != b.info.Size() {
sizeDiffers = true
changes = append(changes, fmt.Sprintf("size: %d vs %d", a.info.Size(), b.info.Size()))
}
}
} else {
if a.info.Size() != b.info.Size() {
sizeDiffers = true
changes = append(changes, fmt.Sprintf("size: %d vs %d", a.info.Size(), b.info.Size()))
}
}
}
if sizeDiffers && isDocx(a.relPath) {
fullA := filepath.Join(rootA, a.relPath)
fullB := filepath.Join(rootB, b.relPath)
result := analyzeDocx(fullA, fullB)
changes = append(changes, result.label)
docxDets = result.details
}
if useDate && !a.info.ModTime().Equal(b.info.ModTime()) {
changes = append(changes, fmt.Sprintf("modified: %s vs %s",
a.info.ModTime().Format("2006-01-02 15:04:05"),
b.info.ModTime().Format("2006-01-02 15:04:05")))
}
return changes, docxDets
}