Add TagList

This commit is contained in:
Alexander Neumann 2017-07-09 09:24:02 +02:00
parent c554cdac4c
commit f5b1c7e5f1
4 changed files with 44 additions and 53 deletions

View file

@ -122,6 +122,11 @@ func runForget(opts ForgetOptions, gopts GlobalOptions, args []string) error {
return nil return nil
} }
var tagLists []restic.TagList
for _, t := range opts.KeepTags {
tagLists = append(tagLists, restic.SplitTagList(t))
}
policy := restic.ExpirePolicy{ policy := restic.ExpirePolicy{
Last: opts.Last, Last: opts.Last,
Hourly: opts.Hourly, Hourly: opts.Hourly,
@ -129,7 +134,7 @@ func runForget(opts ForgetOptions, gopts GlobalOptions, args []string) error {
Weekly: opts.Weekly, Weekly: opts.Weekly,
Monthly: opts.Monthly, Monthly: opts.Monthly,
Yearly: opts.Yearly, Yearly: opts.Yearly,
Tags: opts.KeepTags, Tags: tagLists,
} }
if policy.Empty() { if policy.Empty() {

View file

@ -5,7 +5,6 @@ import (
"fmt" "fmt"
"os/user" "os/user"
"path/filepath" "path/filepath"
"strings"
"time" "time"
) )
@ -140,25 +139,15 @@ func (sn *Snapshot) hasTag(tag string) bool {
return false return false
} }
// HasTags returns true if the snapshot has at least one of the tags. Tags // HasTags returns true if the snapshot has all the tags in l.
// are compared as strings, unless they contain a comma. Then each of the comma func (sn *Snapshot) HasTags(l []string) bool {
// separated parts of the tag need to be present. for _, tag := range l {
func (sn *Snapshot) HasTags(tags []string) bool { if !sn.hasTag(tag) {
if len(tags) == 0 { return false
return true
}
nextTag:
for _, tag := range tags {
for _, s := range strings.Split(tag, ",") {
if !sn.hasTag(s) {
// fail, try next tag
continue nextTag
}
} }
return true
} }
return false return true
} }
func (sn *Snapshot) hasPath(path string) bool { func (sn *Snapshot) hasPath(path string) bool {
@ -170,33 +159,15 @@ func (sn *Snapshot) hasPath(path string) bool {
return false return false
} }
// HasPaths returns true if the snapshot has at least one of the paths. Paths // HasPaths returns true if the snapshot has all of the paths.
// are compared as strings unless they contain a comma. Then each of the comma
// separated parts of the path need to be present.
func (sn *Snapshot) HasPaths(paths []string) bool { func (sn *Snapshot) HasPaths(paths []string) bool {
if len(paths) == 0 {
return true
}
nextPath:
for _, path := range paths { for _, path := range paths {
for _, p := range strings.Split(path, ",") { if !sn.hasPath(path) {
if !sn.hasPath(p) { return false
// fail, try next path
continue nextPath
}
} }
return true
} }
return false return true
}
// SamePaths returns true if the snapshot matches the entire paths set
func (sn *Snapshot) SamePaths(paths []string) bool {
if len(sn.Paths) != len(paths) {
return false
}
return sn.HasPaths(paths)
} }
// Snapshots is a list of snapshots. // Snapshots is a list of snapshots.

View file

@ -3,18 +3,32 @@ package restic
import ( import (
"reflect" "reflect"
"sort" "sort"
"strings"
"time" "time"
) )
// TagList is a list of tags.
type TagList []string
// SplitTagList splits a string into a list of tags. The tags in the string
// need to be separated by commas. Whitespace is stripped around the individual
// tags.
func SplitTagList(s string) (l TagList) {
for _, t := range strings.Split(s, ",") {
l = append(l, strings.TrimSpace(t))
}
return l
}
// ExpirePolicy configures which snapshots should be automatically removed. // ExpirePolicy configures which snapshots should be automatically removed.
type ExpirePolicy struct { type ExpirePolicy struct {
Last int // keep the last n snapshots Last int // keep the last n snapshots
Hourly int // keep the last n hourly snapshots Hourly int // keep the last n hourly snapshots
Daily int // keep the last n daily snapshots Daily int // keep the last n daily snapshots
Weekly int // keep the last n weekly snapshots Weekly int // keep the last n weekly snapshots
Monthly int // keep the last n monthly snapshots Monthly int // keep the last n monthly snapshots
Yearly int // keep the last n yearly snapshots Yearly int // keep the last n yearly snapshots
Tags []string // keep all snapshots with these tags Tags []TagList // keep all snapshots that include at least one of the tag lists.
} }
// Sum returns the maximum number of snapshots to be kept according to this // Sum returns the maximum number of snapshots to be kept according to this
@ -94,11 +108,12 @@ func ApplyPolicy(list Snapshots, p ExpirePolicy) (keep, remove Snapshots) {
var keepSnap bool var keepSnap bool
// Tags are handled specially as they are not counted. // Tags are handled specially as they are not counted.
if len(p.Tags) > 0 { for _, l := range p.Tags {
if cur.HasTags(p.Tags) { if cur.HasTags(l) {
keepSnap = true keepSnap = true
} }
} }
// Now update the other buckets and see if they have some counts left. // Now update the other buckets and see if they have some counts left.
for i, b := range buckets { for i, b := range buckets {
if b.Count > 0 { if b.Count > 0 {

View file

@ -27,7 +27,7 @@ func TestExpireSnapshotOps(t *testing.T) {
p *restic.ExpirePolicy p *restic.ExpirePolicy
}{ }{
{true, 0, &restic.ExpirePolicy{}}, {true, 0, &restic.ExpirePolicy{}},
{true, 0, &restic.ExpirePolicy{Tags: []string{}}}, {true, 0, &restic.ExpirePolicy{Tags: []restic.TagList{}}},
{false, 22, &restic.ExpirePolicy{Daily: 7, Weekly: 2, Monthly: 3, Yearly: 10}}, {false, 22, &restic.ExpirePolicy{Daily: 7, Weekly: 2, Monthly: 3, Yearly: 10}},
} }
for i, d := range data { for i, d := range data {
@ -163,9 +163,9 @@ var expireTests = []restic.ExpirePolicy{
{Daily: 2, Weekly: 2, Monthly: 6}, {Daily: 2, Weekly: 2, Monthly: 6},
{Yearly: 10}, {Yearly: 10},
{Daily: 7, Weekly: 2, Monthly: 3, Yearly: 10}, {Daily: 7, Weekly: 2, Monthly: 3, Yearly: 10},
{Tags: []string{"foo"}}, {Tags: []restic.TagList{{"foo"}}},
{Tags: []string{"foo,bar"}}, {Tags: []restic.TagList{{"foo", "bar"}}},
{Tags: []string{"foo", "bar"}}, {Tags: []restic.TagList{{"foo"}, {"bar"}}},
} }
func TestApplyPolicy(t *testing.T) { func TestApplyPolicy(t *testing.T) {