Compare commits

...

2 Commits

Author SHA1 Message Date
Vincent Batts 29603ae478 WIP: sort entries by full path name before compare 2018-08-15 17:42:36 -04:00
Vincent Batts a072d6d6e7 WIP 2018-08-13 23:09:49 -04:00
3 changed files with 43 additions and 9 deletions

View File

@ -5,18 +5,18 @@ package mtree
// If keywords is nil, the check all present in the DirectoryHierarchy // If keywords is nil, the check all present in the DirectoryHierarchy
// //
// This is equivalent to creating a new DirectoryHierarchy with Walk(root, nil, // This is equivalent to creating a new DirectoryHierarchy with Walk(root, nil,
// keywords, fs) and then doing a Compare(dh, newDh, keywords). // keywords, fs) and then doing a Compare(dh, curDh, keywords).
func Check(root string, dh *DirectoryHierarchy, keywords []Keyword, fs FsEval) ([]InodeDelta, error) { func Check(root string, dh *DirectoryHierarchy, keywords []Keyword, fs FsEval) ([]InodeDelta, error) {
if keywords == nil { if keywords == nil {
keywords = dh.UsedKeywords() keywords = dh.UsedKeywords()
} }
newDh, err := Walk(root, nil, keywords, fs) curDh, err := Walk(root, nil, keywords, fs)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return Compare(dh, newDh, keywords) return Compare(dh, curDh, keywords)
} }
// TarCheck is the tar equivalent of checking a file hierarchy spec against a // TarCheck is the tar equivalent of checking a file hierarchy spec against a

View File

@ -3,6 +3,7 @@ package mtree
import ( import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"sort"
"strconv" "strconv"
) )
@ -325,13 +326,17 @@ func compareEntry(oldEntry, newEntry Entry) ([]KeyDelta, error) {
// missing entries and the like). A missing or extra key is treated as a // missing entries and the like). A missing or extra key is treated as a
// Modified type. // Modified type.
// //
// If oldDh or newDh are empty, we assume they are a hierarchy that is // If thisDh or thatDh are empty, we assume they are a hierarchy that is
// completely empty. This is purely for helping callers create synthetic // completely empty. This is purely for helping callers create synthetic
// InodeDeltas. // InodeDeltas.
// //
// Comparing this directory hierarchy to that directory hierarchy is that
// sometimes it has few than all files, or may not have directories, etc.,
// so lack of presence of entries in thisDh may not be reportable.
//
// NB: The order of the parameters matters (old, new) because Extra and // NB: The order of the parameters matters (old, new) because Extra and
// Missing are considered as different discrepancy types. // Missing are considered as different discrepancy types.
func Compare(oldDh, newDh *DirectoryHierarchy, keys []Keyword) ([]InodeDelta, error) { func Compare(thisDh, thatDh *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
@ -343,8 +348,9 @@ func Compare(oldDh, newDh *DirectoryHierarchy, keys []Keyword) ([]InodeDelta, er
diffs := map[string]*stateT{} diffs := map[string]*stateT{}
// First, iterate over the old hierarchy. If nil, pretend it's empty. // First, iterate over the old hierarchy. If nil, pretend it's empty.
if oldDh != nil { if thisDh != nil {
for _, e := range oldDh.Entries { sort.Sort(byName(thisDh.Entries))
for _, e := range thisDh.Entries {
if e.Type == RelativeType || e.Type == FullType { if e.Type == RelativeType || e.Type == FullType {
path, err := e.Path() path, err := e.Path()
if err != nil { if err != nil {
@ -365,8 +371,9 @@ func Compare(oldDh, newDh *DirectoryHierarchy, keys []Keyword) ([]InodeDelta, er
} }
// Then, iterate over the new hierarchy. If nil, pretend it's empty. // Then, iterate over the new hierarchy. If nil, pretend it's empty.
if newDh != nil { if thatDh != nil {
for _, e := range newDh.Entries { sort.Sort(byName(thatDh.Entries))
for _, e := range thatDh.Entries {
if e.Type == RelativeType || e.Type == FullType { if e.Type == RelativeType || e.Type == FullType {
path, err := e.Path() path, err := e.Path()
if err != nil { if err != nil {

View File

@ -14,6 +14,33 @@ func (bp byPos) Len() int { return len(bp) }
func (bp byPos) Less(i, j int) bool { return bp[i].Pos < bp[j].Pos } func (bp byPos) Less(i, j int) bool { return bp[i].Pos < bp[j].Pos }
func (bp byPos) Swap(i, j int) { bp[i], bp[j] = bp[j], bp[i] } func (bp byPos) Swap(i, j int) { bp[i], bp[j] = bp[j], bp[i] }
type byName []Entry
func (bp byName) Len() int { return len(bp) }
func (bp byName) Less(i, j int) bool {
var iParent string
var jParent string
var err error
if bp[i].Parent != nil {
iParent, err = bp[i].Parent.Path()
if err != nil {
return false
}
}
iName := filepath.Clean(filepath.Join(iParent, bp[i].Name))
if bp[j].Parent != nil {
jParent, err = bp[j].Parent.Path()
if err != nil {
return false
}
}
jName := filepath.Clean(filepath.Join(jParent, bp[j].Name))
return iName < jName
}
func (bp byName) Swap(i, j int) { bp[i], bp[j] = bp[j], bp[i] }
// Entry is each component of content in the mtree spec file // Entry is each component of content in the mtree spec file
type Entry struct { type Entry struct {
Parent *Entry // up Parent *Entry // up