mirror of
https://github.com/octoleo/restic.git
synced 2024-11-25 22:27:35 +00:00
Implement TagList and TagLists as pflag.Value
This commit is contained in:
parent
7362569cf5
commit
78d090aea5
@ -34,7 +34,7 @@ type FindOptions struct {
|
||||
ListLong bool
|
||||
Host string
|
||||
Paths []string
|
||||
Tags []string
|
||||
Tags restic.TagLists
|
||||
}
|
||||
|
||||
var findOptions FindOptions
|
||||
@ -50,7 +50,7 @@ func init() {
|
||||
f.BoolVarP(&findOptions.ListLong, "long", "l", false, "use a long listing format showing size and mode")
|
||||
|
||||
f.StringVarP(&findOptions.Host, "host", "H", "", "only consider snapshots for this `host`, when no snapshot ID is given")
|
||||
f.StringArrayVar(&findOptions.Tags, "tag", nil, "only consider snapshots which include the list of `tag,tag,...`, when no snapshot-ID is given")
|
||||
f.Var(&findOptions.Tags, "tag", "only consider snapshots which include this `taglist`, when no snapshot-ID is given")
|
||||
f.StringArrayVar(&findOptions.Paths, "path", nil, "only consider snapshots which include this (absolute) `path`, when no snapshot-ID is given")
|
||||
}
|
||||
|
||||
@ -290,15 +290,13 @@ func runFind(opts FindOptions, gopts GlobalOptions, args []string) error {
|
||||
ctx, cancel := context.WithCancel(gopts.ctx)
|
||||
defer cancel()
|
||||
|
||||
tagLists := restic.SplitTagLists(opts.Tags)
|
||||
|
||||
f := &Finder{
|
||||
repo: repo,
|
||||
pat: pat,
|
||||
out: statefulOutput{ListLong: opts.ListLong, JSON: globalOptions.JSON},
|
||||
notfound: restic.NewIDSet(),
|
||||
}
|
||||
for sn := range FindFilteredSnapshots(ctx, repo, opts.Host, tagLists, opts.Paths, opts.Snapshots) {
|
||||
for sn := range FindFilteredSnapshots(ctx, repo, opts.Host, opts.Tags, opts.Paths, opts.Snapshots) {
|
||||
if err = f.findInSnapshot(sn); err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -31,10 +31,10 @@ type ForgetOptions struct {
|
||||
Weekly int
|
||||
Monthly int
|
||||
Yearly int
|
||||
KeepTags []string
|
||||
KeepTags restic.TagLists
|
||||
|
||||
Host string
|
||||
Tags []string
|
||||
Tags restic.TagLists
|
||||
Paths []string
|
||||
|
||||
GroupByTags bool
|
||||
@ -55,13 +55,13 @@ func init() {
|
||||
f.IntVarP(&forgetOptions.Monthly, "keep-monthly", "m", 0, "keep the last `n` monthly snapshots")
|
||||
f.IntVarP(&forgetOptions.Yearly, "keep-yearly", "y", 0, "keep the last `n` yearly snapshots")
|
||||
|
||||
f.StringArrayVar(&forgetOptions.KeepTags, "keep-tag", []string{}, "keep snapshots with this `tag` (can be specified multiple times)")
|
||||
f.Var(&forgetOptions.KeepTags, "keep-tag", "keep snapshots with this `taglist` (can be specified multiple times)")
|
||||
f.BoolVarP(&forgetOptions.GroupByTags, "group-by-tags", "G", false, "Group by host,paths,tags instead of just host,paths")
|
||||
// Sadly the commonly used shortcut `H` is already used.
|
||||
f.StringVar(&forgetOptions.Host, "host", "", "only consider snapshots with the given `host`")
|
||||
// Deprecated since 2017-03-07.
|
||||
f.StringVar(&forgetOptions.Host, "hostname", "", "only consider snapshots with the given `hostname` (deprecated)")
|
||||
f.StringArrayVar(&forgetOptions.Tags, "tag", nil, "only consider snapshots which include this `tag` (can be specified multiple times)")
|
||||
f.Var(&forgetOptions.Tags, "tag", "only consider snapshots which include this `taglist` (can be specified multiple times)")
|
||||
f.StringArrayVar(&forgetOptions.Paths, "path", nil, "only consider snapshots which include this (absolute) `path` (can be specified multiple times)")
|
||||
|
||||
f.BoolVarP(&forgetOptions.DryRun, "dry-run", "n", false, "do not delete anything, just print what would be done")
|
||||
@ -92,7 +92,7 @@ func runForget(opts ForgetOptions, gopts GlobalOptions, args []string) error {
|
||||
|
||||
ctx, cancel := context.WithCancel(gopts.ctx)
|
||||
defer cancel()
|
||||
for sn := range FindFilteredSnapshots(ctx, repo, opts.Host, restic.SplitTagLists(opts.Tags), opts.Paths, args) {
|
||||
for sn := range FindFilteredSnapshots(ctx, repo, opts.Host, opts.Tags, opts.Paths, args) {
|
||||
if len(args) > 0 {
|
||||
// When explicit snapshots args are given, remove them immediately.
|
||||
if !opts.DryRun {
|
||||
@ -122,11 +122,6 @@ func runForget(opts ForgetOptions, gopts GlobalOptions, args []string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
var tagLists []restic.TagList
|
||||
for _, t := range opts.KeepTags {
|
||||
tagLists = append(tagLists, restic.SplitTagList(t))
|
||||
}
|
||||
|
||||
policy := restic.ExpirePolicy{
|
||||
Last: opts.Last,
|
||||
Hourly: opts.Hourly,
|
||||
@ -134,7 +129,7 @@ func runForget(opts ForgetOptions, gopts GlobalOptions, args []string) error {
|
||||
Weekly: opts.Weekly,
|
||||
Monthly: opts.Monthly,
|
||||
Yearly: opts.Yearly,
|
||||
Tags: tagLists,
|
||||
Tags: opts.KeepTags,
|
||||
}
|
||||
|
||||
if policy.Empty() {
|
||||
|
@ -28,7 +28,7 @@ The special snapshot-ID "latest" can be used to list files and directories of th
|
||||
type LsOptions struct {
|
||||
ListLong bool
|
||||
Host string
|
||||
Tags []string
|
||||
Tags restic.TagLists
|
||||
Paths []string
|
||||
}
|
||||
|
||||
@ -41,7 +41,7 @@ func init() {
|
||||
flags.BoolVarP(&lsOptions.ListLong, "long", "l", false, "use a long listing format showing size and mode")
|
||||
|
||||
flags.StringVarP(&lsOptions.Host, "host", "H", "", "only consider snapshots for this `host`, when no snapshot ID is given")
|
||||
flags.StringArrayVar(&lsOptions.Tags, "tag", nil, "only consider snapshots which include this `tag`, when no snapshot ID is given")
|
||||
flags.Var(&lsOptions.Tags, "tag", "only consider snapshots which include this `taglist`, when no snapshot ID is given")
|
||||
flags.StringArrayVar(&lsOptions.Paths, "path", nil, "only consider snapshots which include this (absolute) `path`, when no snapshot ID is given")
|
||||
}
|
||||
|
||||
@ -80,7 +80,7 @@ func runLs(opts LsOptions, gopts GlobalOptions, args []string) error {
|
||||
|
||||
ctx, cancel := context.WithCancel(gopts.ctx)
|
||||
defer cancel()
|
||||
for sn := range FindFilteredSnapshots(ctx, repo, opts.Host, restic.SplitTagLists(opts.Tags), opts.Paths, args) {
|
||||
for sn := range FindFilteredSnapshots(ctx, repo, opts.Host, opts.Tags, opts.Paths, args) {
|
||||
Verbosef("snapshot %s of %v at %s):\n", sn.ID().Str(), sn.Paths, sn.Time)
|
||||
|
||||
if err = printTree(repo, sn.Tree, string(filepath.Separator)); err != nil {
|
||||
|
@ -38,7 +38,7 @@ type MountOptions struct {
|
||||
AllowRoot bool
|
||||
AllowOther bool
|
||||
Host string
|
||||
Tags []string
|
||||
Tags restic.TagLists
|
||||
Paths []string
|
||||
}
|
||||
|
||||
@ -53,7 +53,7 @@ func init() {
|
||||
mountFlags.BoolVar(&mountOptions.AllowOther, "allow-other", false, "allow other users to access the data in the mounted directory")
|
||||
|
||||
mountFlags.StringVarP(&mountOptions.Host, "host", "H", "", `only consider snapshots for this host`)
|
||||
mountFlags.StringArrayVar(&mountOptions.Tags, "tag", nil, "only consider snapshots which include this `tag`")
|
||||
mountFlags.Var(&mountOptions.Tags, "tag", "only consider snapshots which include this `taglist`")
|
||||
mountFlags.StringArrayVar(&mountOptions.Paths, "path", nil, "only consider snapshots which include this (absolute) `path`")
|
||||
}
|
||||
|
||||
@ -104,7 +104,7 @@ func mount(opts MountOptions, gopts GlobalOptions, mountpoint string) error {
|
||||
cfg := fuse.Config{
|
||||
OwnerIsRoot: opts.OwnerRoot,
|
||||
Host: opts.Host,
|
||||
Tags: restic.SplitTagLists(opts.Tags),
|
||||
Tags: opts.Tags,
|
||||
Paths: opts.Paths,
|
||||
}
|
||||
root, err := fuse.NewRoot(context.TODO(), repo, cfg)
|
||||
|
@ -31,7 +31,7 @@ type RestoreOptions struct {
|
||||
Target string
|
||||
Host string
|
||||
Paths []string
|
||||
Tags []string
|
||||
Tags restic.TagLists
|
||||
}
|
||||
|
||||
var restoreOptions RestoreOptions
|
||||
@ -45,7 +45,7 @@ func init() {
|
||||
flags.StringVarP(&restoreOptions.Target, "target", "t", "", "directory to extract data to")
|
||||
|
||||
flags.StringVarP(&restoreOptions.Host, "host", "H", "", `only consider snapshots for this host when the snapshot ID is "latest"`)
|
||||
flags.StringArrayVar(&restoreOptions.Tags, "tag", nil, "only consider snapshots which include this `tag` for snapshot ID \"latest\"")
|
||||
flags.Var(&restoreOptions.Tags, "tag", "only consider snapshots which include this `taglist` for snapshot ID \"latest\"")
|
||||
flags.StringArrayVar(&restoreOptions.Paths, "path", nil, "only consider snapshots which include this (absolute) `path` for snapshot ID \"latest\"")
|
||||
}
|
||||
|
||||
@ -89,7 +89,7 @@ func runRestore(opts RestoreOptions, gopts GlobalOptions, args []string) error {
|
||||
var id restic.ID
|
||||
|
||||
if snapshotIDString == "latest" {
|
||||
id, err = restic.FindLatestSnapshot(ctx, repo, opts.Paths, restic.SplitTagLists(opts.Tags), opts.Host)
|
||||
id, err = restic.FindLatestSnapshot(ctx, repo, opts.Paths, opts.Tags, opts.Host)
|
||||
if err != nil {
|
||||
Exitf(1, "latest snapshot for criteria not found: %v Paths:%v Host:%v", err, opts.Paths, opts.Host)
|
||||
}
|
||||
|
@ -26,7 +26,7 @@ The "snapshots" command lists all snapshots stored in the repository.
|
||||
// SnapshotOptions bundles all options for the snapshots command.
|
||||
type SnapshotOptions struct {
|
||||
Host string
|
||||
Tags []string
|
||||
Tags restic.TagLists
|
||||
Paths []string
|
||||
}
|
||||
|
||||
@ -37,7 +37,7 @@ func init() {
|
||||
|
||||
f := cmdSnapshots.Flags()
|
||||
f.StringVarP(&snapshotOptions.Host, "host", "H", "", "only consider snapshots for this `host`")
|
||||
f.StringArrayVar(&snapshotOptions.Tags, "tag", nil, "only consider snapshots which include this `tag` (can be specified multiple times)")
|
||||
f.Var(&snapshotOptions.Tags, "tag", "only consider snapshots which include this `taglist` (can be specified multiple times)")
|
||||
f.StringArrayVar(&snapshotOptions.Paths, "path", nil, "only consider snapshots for this `path` (can be specified multiple times)")
|
||||
}
|
||||
|
||||
@ -59,7 +59,7 @@ func runSnapshots(opts SnapshotOptions, gopts GlobalOptions, args []string) erro
|
||||
defer cancel()
|
||||
|
||||
var list restic.Snapshots
|
||||
for sn := range FindFilteredSnapshots(ctx, repo, opts.Host, restic.SplitTagLists(opts.Tags), opts.Paths, args) {
|
||||
for sn := range FindFilteredSnapshots(ctx, repo, opts.Host, opts.Tags, opts.Paths, args) {
|
||||
list = append(list, sn)
|
||||
}
|
||||
sort.Sort(sort.Reverse(list))
|
||||
|
@ -31,7 +31,7 @@ When no snapshot-ID is given, all snapshots matching the host, tag and path filt
|
||||
type TagOptions struct {
|
||||
Host string
|
||||
Paths []string
|
||||
Tags []string
|
||||
Tags restic.TagLists
|
||||
SetTags []string
|
||||
AddTags []string
|
||||
RemoveTags []string
|
||||
@ -48,7 +48,7 @@ func init() {
|
||||
tagFlags.StringSliceVar(&tagOptions.RemoveTags, "remove", nil, "`tag` which will be removed from the existing tags (can be given multiple times)")
|
||||
|
||||
tagFlags.StringVarP(&tagOptions.Host, "host", "H", "", "only consider snapshots for this `host`, when no snapshot ID is given")
|
||||
tagFlags.StringArrayVar(&tagOptions.Tags, "tag", nil, "only consider snapshots which include this `tag`, when no snapshot-ID is given")
|
||||
tagFlags.Var(&tagOptions.Tags, "tag", "only consider snapshots which include this `taglist`, when no snapshot-ID is given")
|
||||
tagFlags.StringArrayVar(&tagOptions.Paths, "path", nil, "only consider snapshots which include this (absolute) `path`, when no snapshot-ID is given")
|
||||
}
|
||||
|
||||
@ -123,7 +123,7 @@ func runTag(opts TagOptions, gopts GlobalOptions, args []string) error {
|
||||
changeCnt := 0
|
||||
ctx, cancel := context.WithCancel(gopts.ctx)
|
||||
defer cancel()
|
||||
for sn := range FindFilteredSnapshots(ctx, repo, opts.Host, restic.SplitTagLists(opts.Tags), opts.Paths, args) {
|
||||
for sn := range FindFilteredSnapshots(ctx, repo, opts.Host, opts.Tags, opts.Paths, args) {
|
||||
changed, err := changeTags(repo, sn, opts.SetTags, opts.AddTags, opts.RemoveTags)
|
||||
if err != nil {
|
||||
Warnf("unable to modify the tags for snapshot ID %q, ignoring: %v\n", sn.ID(), err)
|
||||
|
@ -3,33 +3,9 @@ package restic
|
||||
import (
|
||||
"reflect"
|
||||
"sort"
|
||||
"strings"
|
||||
"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
|
||||
}
|
||||
|
||||
// SplitTagLists splits a slice of strings into a slice of TagLists using
|
||||
// SplitTagList.
|
||||
func SplitTagLists(s []string) (l []TagList) {
|
||||
l = make([]TagList, 0, len(s))
|
||||
for _, t := range s {
|
||||
l = append(l, SplitTagList(t))
|
||||
}
|
||||
return l
|
||||
}
|
||||
|
||||
// ExpirePolicy configures which snapshots should be automatically removed.
|
||||
type ExpirePolicy struct {
|
||||
Last int // keep the last n snapshots
|
||||
|
62
src/restic/tag_list.go
Normal file
62
src/restic/tag_list.go
Normal file
@ -0,0 +1,62 @@
|
||||
package restic
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
func (l TagList) String() string {
|
||||
return "[" + strings.Join(l, ", ") + "]"
|
||||
}
|
||||
|
||||
// Set updates the TagList's value.
|
||||
func (l *TagList) Set(s string) error {
|
||||
*l = SplitTagList(s)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Type returns a description of the type.
|
||||
func (TagList) Type() string {
|
||||
return "TagList"
|
||||
}
|
||||
|
||||
// TagLists consists of several TagList.
|
||||
type TagLists []TagList
|
||||
|
||||
// SplitTagLists splits a slice of strings into a slice of TagLists using
|
||||
// SplitTagList.
|
||||
func SplitTagLists(s []string) (l TagLists) {
|
||||
l = make([]TagList, 0, len(s))
|
||||
for _, t := range s {
|
||||
l = append(l, SplitTagList(t))
|
||||
}
|
||||
return l
|
||||
}
|
||||
|
||||
func (l TagLists) String() string {
|
||||
return fmt.Sprintf("%v", []TagList(l))
|
||||
}
|
||||
|
||||
// Set updates the TagList's value.
|
||||
func (l *TagLists) Set(s string) error {
|
||||
*l = append(*l, SplitTagList(s))
|
||||
return nil
|
||||
}
|
||||
|
||||
// Type returns a description of the type.
|
||||
func (TagLists) Type() string {
|
||||
return "TagLists"
|
||||
}
|
Loading…
Reference in New Issue
Block a user