From d8d43cd80704346b4f59ed6a77fa78fed444d3c1 Mon Sep 17 00:00:00 2001 From: Tycho Andersen Date: Mon, 7 Jan 2019 12:21:33 -0700 Subject: [PATCH] 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 --- compare.go | 63 ++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 44 insertions(+), 19 deletions(-) diff --git a/compare.go b/compare.go index 458df85..6871bf2 100644 --- a/compare.go +++ b/compare.go @@ -30,6 +30,10 @@ const ( // manifests). 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 // a keyword that failed ErrorDifference DifferenceType = "errored" @@ -313,25 +317,8 @@ func compareEntry(oldEntry, newEntry Entry) ([]KeyDelta, error) { 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) { +// compare is the actual workhorse for Compare() and CompareSame() +func compare(oldDh, newDh *DirectoryHierarchy, keys []Keyword, same bool) ([]InodeDelta, error) { // Represents the new and old states for an entry. type stateT struct { Old *Entry @@ -440,9 +427,47 @@ func Compare(oldDh, newDh *DirectoryHierarchy, keys []Keyword) ([]InodeDelta, er new: *diff.New, 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 } + +// 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) +}