compare: add CompareSame()

I have a use case where I'd like to know the files that are the same in the
tree, as well as the differences.

I could do this with a separate walk and excluding the paths that were
different, but since mtree is already doing all of this for me, it makes
sense to include it here. I've added a new function so that the behavior
stays the same for existing users of Compare(), since I assume mostly this
will be slower given that most files stay the same. I'd be happy to merge
it into one, though.

Signed-off-by: Tycho Andersen <tycho@tycho.ws>
This commit is contained in:
Tycho Andersen 2019-01-07 12:21:33 -07:00
parent 37d776ac40
commit d8d43cd807

View file

@ -30,6 +30,10 @@ const (
// manifests). // manifests).
Modified DifferenceType = "modified" Modified DifferenceType = "modified"
// Same represents the case where two files are the same. These are
// only generated from CompareSame().
Same DifferenceType = "same"
// ErrorDifference represents an attempted update to the values of // ErrorDifference represents an attempted update to the values of
// a keyword that failed // a keyword that failed
ErrorDifference DifferenceType = "errored" ErrorDifference DifferenceType = "errored"
@ -313,25 +317,8 @@ func compareEntry(oldEntry, newEntry Entry) ([]KeyDelta, error) {
return results, nil return results, nil
} }
// Compare compares two directory hierarchy manifests, and returns the // compare is the actual workhorse for Compare() and CompareSame()
// list of discrepancies between the two. All of the entries in the func compare(oldDh, newDh *DirectoryHierarchy, keys []Keyword, same bool) ([]InodeDelta, error) {
// manifest are considered, with differences being generated for
// RelativeType and FullType entries. Differences in structure (such as
// the way /set and /unset are written) are not considered to be
// discrepancies. The list of differences are all filesystem objects.
//
// keys controls which keys will be compared, but if keys is nil then all
// possible keys will be compared between the two manifests (allowing for
// missing entries and the like). A missing or extra key is treated as a
// Modified type.
//
// If oldDh or newDh are empty, we assume they are a hierarchy that is
// completely empty. This is purely for helping callers create synthetic
// InodeDeltas.
//
// NB: The order of the parameters matters (old, new) because Extra and
// Missing are considered as different discrepancy types.
func Compare(oldDh, newDh *DirectoryHierarchy, keys []Keyword) ([]InodeDelta, error) {
// Represents the new and old states for an entry. // Represents the new and old states for an entry.
type stateT struct { type stateT struct {
Old *Entry Old *Entry
@ -440,9 +427,47 @@ func Compare(oldDh, newDh *DirectoryHierarchy, keys []Keyword) ([]InodeDelta, er
new: *diff.New, new: *diff.New,
keys: changed, keys: changed,
}) })
} else if same {
// this means that nothing changed, i.e. that
// the files are the same.
results = append(results, InodeDelta{
diff: Same,
path: path,
old: *diff.Old,
new: *diff.New,
keys: changed,
})
} }
} }
} }
return results, nil return results, nil
} }
// Compare compares two directory hierarchy manifests, and returns the
// list of discrepancies between the two. All of the entries in the
// manifest are considered, with differences being generated for
// RelativeType and FullType entries. Differences in structure (such as
// the way /set and /unset are written) are not considered to be
// discrepancies. The list of differences are all filesystem objects.
//
// keys controls which keys will be compared, but if keys is nil then all
// possible keys will be compared between the two manifests (allowing for
// missing entries and the like). A missing or extra key is treated as a
// Modified type.
//
// If oldDh or newDh are empty, we assume they are a hierarchy that is
// completely empty. This is purely for helping callers create synthetic
// InodeDeltas.
//
// NB: The order of the parameters matters (old, new) because Extra and
// Missing are considered as different discrepancy types.
func Compare(oldDh, newDh *DirectoryHierarchy, keys []Keyword) ([]InodeDelta, error) {
return compare(oldDh, newDh, keys, false)
}
// CompareSame is the same as Compare, except it also includes the entries
// that are the same with a Same DifferenceType.
func CompareSame(oldDh, newDh *DirectoryHierarchy, keys []Keyword) ([]InodeDelta, error) {
return compare(oldDh, newDh, keys, true)
}