mirror of
https://github.com/vbatts/go-mtree.git
synced 2025-10-04 12:31:00 +00:00
cmd: validate: restructure filtering to use filter functions
This lets us modernise the filtering logic a little bit, and also allows us to configure which filters we wish to apply (a future patch will move some of the filtering done in the top-level go-mtree package to the cmd/validate package). Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
This commit is contained in:
parent
f0d9d5891f
commit
ae454c4a6f
1 changed files with 49 additions and 42 deletions
|
@ -362,11 +362,15 @@ func validateAction(c *cli.Context) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if res != nil {
|
|
||||||
if isTarSpec(specDh) || c.String("tar") != "" {
|
|
||||||
res = filterMissingKeywords(res)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// Apply filters.
|
||||||
|
var filters []deltaFilterFn
|
||||||
|
if isTarSpec(specDh) || c.String("tar") != "" {
|
||||||
|
filters = append(filters, tarKeywordFilter)
|
||||||
|
}
|
||||||
|
res = filterDeltas(res, filters...)
|
||||||
|
|
||||||
|
if len(res) > 0 {
|
||||||
out := formatFunc(res)
|
out := formatFunc(res)
|
||||||
if _, err := os.Stdout.Write([]byte(out)); err != nil {
|
if _, err := os.Stdout.Write([]byte(out)); err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -430,48 +434,51 @@ func isDirEntry(e mtree.Entry) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// filterMissingKeywords is a fairly annoying hack to get around the fact that
|
// tarKeywordFilter is a filter for diffs produced where one half is a tar
|
||||||
// tar archive manifest generation has certain unsolveable problems regarding
|
// archive. tar archive manifests do not have a "size" key associated with
|
||||||
// certain keywords. For example, the size=... keyword cannot be implemented
|
// directories (due to limitations in manifest generation for tar archives) and
|
||||||
// for directories in a tar archive (which causes Missing errors for that
|
// so any deltas due to size missing should be removed.
|
||||||
// keyword).
|
func tarKeywordFilter(delta *mtree.InodeDelta) bool {
|
||||||
//
|
if delta.Path() == "." {
|
||||||
// This function just removes all instances of Missing errors for keywords.
|
// Not all tar archives include a root entry so we should skip that
|
||||||
// This makes certain assumptions about the type of issues tar archives have.
|
// entry if we run into a diff that claims there is an issue with
|
||||||
// Only call this on tar archive manifest comparisons.
|
// it.
|
||||||
func filterMissingKeywords(diffs []mtree.InodeDelta) []mtree.InodeDelta {
|
return false
|
||||||
newDiffs := []mtree.InodeDelta{}
|
}
|
||||||
loop:
|
if delta.Type() != mtree.Modified {
|
||||||
for _, diff := range diffs {
|
return true
|
||||||
if diff.Type() == mtree.Modified {
|
}
|
||||||
// We only apply this filtering to directories.
|
// Strip out "size" entries for directory entries.
|
||||||
// NOTE: This will probably break if someone drops the size keyword.
|
if isDirEntry(*delta.Old()) || isDirEntry(*delta.New()) {
|
||||||
if isDirEntry(*diff.Old()) || isDirEntry(*diff.New()) {
|
keys := delta.DiffPtr()
|
||||||
// If this applies to '.' then we just filter everything
|
*keys = slices.DeleteFunc(*keys, func(kd mtree.KeyDelta) bool {
|
||||||
// (meaning we remove this entry). This is because note all tar
|
return kd.Name() == "size"
|
||||||
// archives include a '.' entry. Which makes checking this not
|
})
|
||||||
// practical.
|
}
|
||||||
if diff.Path() == "." {
|
return true
|
||||||
continue
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Only filter out the size keyword.
|
type deltaFilterFn func(*mtree.InodeDelta) bool
|
||||||
keys := diff.DiffPtr()
|
|
||||||
*keys = slices.DeleteFunc(*keys, func(kd mtree.KeyDelta) bool {
|
// filterDeltas takes the set of deltas generated by mtree and applies the
|
||||||
return kd.Name() == "size"
|
// given set of filters to it.
|
||||||
})
|
func filterDeltas(deltas []mtree.InodeDelta, filters ...deltaFilterFn) []mtree.InodeDelta {
|
||||||
// If there are no key deltas left after filtering, the entry
|
filtered := make([]mtree.InodeDelta, 0, len(deltas))
|
||||||
// should be filtered out entirely.
|
next:
|
||||||
if len(*keys) == 0 {
|
for _, delta := range deltas {
|
||||||
continue loop
|
for _, filter := range filters {
|
||||||
}
|
if !filter(&delta) {
|
||||||
|
continue next
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Some filters might modify the entry to remove keyword deltas --
|
||||||
// If we got here, append to the new set.
|
// if there are no deltas left then we should skip the entry entirely.
|
||||||
newDiffs = append(newDiffs, diff)
|
if delta.Type() == mtree.Modified && len(delta.Diff()) == 0 {
|
||||||
|
continue next
|
||||||
|
}
|
||||||
|
filtered = append(filtered, delta)
|
||||||
}
|
}
|
||||||
return newDiffs
|
return filtered
|
||||||
}
|
}
|
||||||
|
|
||||||
// isTarSpec returns whether the spec provided came from the tar generator.
|
// isTarSpec returns whether the spec provided came from the tar generator.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue