[#373] pruning: add optional regex field to last_n rule

fixes #373
This commit is contained in:
Christian Schwarz
2020-08-31 14:05:32 +02:00
parent 428a60870a
commit b1f8cdf385
5 changed files with 76 additions and 18 deletions
+31 -9
View File
@@ -1,6 +1,7 @@
package pruning
import (
"regexp"
"sort"
"strings"
@@ -8,14 +9,27 @@ import (
)
type KeepLastN struct {
n int
n int
re *regexp.Regexp
}
func NewKeepLastN(n int) (*KeepLastN, error) {
func MustKeepLastN(n int, regex string) *KeepLastN {
k, err := NewKeepLastN(n, regex)
if err != nil {
panic(err)
}
return k
}
func NewKeepLastN(n int, regex string) (*KeepLastN, error) {
if n <= 0 {
return nil, errors.Errorf("must specify positive number as 'keep last count', got %d", n)
}
return &KeepLastN{n}, nil
re, err := regexp.Compile(regex)
if err != nil {
return nil, errors.Errorf("invalid regex %q: %s", regex, err)
}
return &KeepLastN{n, re}, nil
}
func (k KeepLastN) KeepRule(snaps []Snapshot) (destroyList []Snapshot) {
@@ -24,17 +38,25 @@ func (k KeepLastN) KeepRule(snaps []Snapshot) (destroyList []Snapshot) {
return []Snapshot{}
}
res := shallowCopySnapList(snaps)
matching, notMatching := partitionSnapList(snaps, func(snapshot Snapshot) bool {
return k.re.MatchString(snapshot.Name())
})
// snaps that don't match the regex are not kept by this rule
destroyList = append(destroyList, notMatching...)
sort.Slice(res, func(i, j int) bool {
if len(matching) == 0 {
return destroyList
}
sort.Slice(matching, func(i, j int) bool {
// by date (youngest first)
id, jd := res[i].Date(), res[j].Date()
id, jd := matching[i].Date(), matching[j].Date()
if !id.Equal(jd) {
return id.After(jd)
}
// then lexicographically descending (e.g. b, a)
return strings.Compare(res[i].Name(), res[j].Name()) == 1
return strings.Compare(matching[i].Name(), matching[j].Name()) == 1
})
return res[k.n:]
destroyList = append(destroyList, matching[k.n:]...)
return destroyList
}