From 0dfdf028852215bf2ac13981fda43cbfca6e63bb Mon Sep 17 00:00:00 2001 From: Alexander Neumann Date: Sun, 10 Sep 2017 14:34:28 +0200 Subject: [PATCH] Rework pattern excludes --- cmd/restic/cmd_backup.go | 26 ++++++++++---------------- cmd/restic/exclude.go | 22 +++++++++++++++++++++- 2 files changed, 31 insertions(+), 17 deletions(-) diff --git a/cmd/restic/cmd_backup.go b/cmd/restic/cmd_backup.go index 413dd8862..3ae109085 100644 --- a/cmd/restic/cmd_backup.go +++ b/cmd/restic/cmd_backup.go @@ -15,7 +15,6 @@ import ( "github.com/restic/restic/internal/archiver" "github.com/restic/restic/internal/debug" "github.com/restic/restic/internal/errors" - "github.com/restic/restic/internal/filter" "github.com/restic/restic/internal/fs" "github.com/restic/restic/internal/restic" ) @@ -416,39 +415,34 @@ func runBackup(opts BackupOptions, gopts GlobalOptions, args []string) error { Verbosef("scan %v\n", target) + // rejectFuncs collect functions that can reject items from the backup + var rejectFuncs []RejectFunc + // add patterns from file if len(opts.ExcludeFiles) > 0 { opts.Excludes = append(opts.Excludes, readExcludePatternsFromFiles(opts.ExcludeFiles)...) } + if len(opts.Excludes) > 0 { + rejectFuncs = append(rejectFuncs, rejectByPattern(opts.Excludes)) + } + if opts.ExcludeCaches { opts.ExcludeIfPresent = append(opts.ExcludeIfPresent, "CACHEDIR.TAG:Signature: 8a477f597d28d172789f06886806bc55") } - var excludesByFile []RejectFunc for _, spec := range opts.ExcludeIfPresent { f, err := rejectIfPresent(spec) if err != nil { return err } - excludesByFile = append(excludesByFile, f) + rejectFuncs = append(rejectFuncs, f) } selectFilter := func(item string, fi os.FileInfo) bool { - matched, _, err := filter.List(opts.Excludes, item) - if err != nil { - Warnf("error for exclude pattern: %v", err) - } - - if matched { - debug.Log("path %q excluded by a filter", item) - return false - } - - for _, excludeByFile := range excludesByFile { - if excludeByFile(item, fi) { - debug.Log("path %q excluded by tagfile", item) + for _, reject := range rejectFuncs { + if reject(item, fi) { return false } } diff --git a/cmd/restic/exclude.go b/cmd/restic/exclude.go index 34d3971f1..294a8e3eb 100644 --- a/cmd/restic/exclude.go +++ b/cmd/restic/exclude.go @@ -9,6 +9,8 @@ import ( "strings" "github.com/restic/restic/internal/debug" + "github.com/restic/restic/internal/errors" + "github.com/restic/restic/internal/filter" "github.com/restic/restic/internal/fs" ) @@ -17,6 +19,24 @@ import ( // should be excluded (rejected) from the backup. type RejectFunc func(filename string, fi os.FileInfo) bool +// rejectByPattern returns a RejectFunc which rejects files that match +// one of the patterns. +func rejectByPattern(patterns []string) RejectFunc { + return func(item string, fi os.FileInfo) bool { + matched, _, err := filter.List(patterns, item) + if err != nil { + Warnf("error for exclude pattern: %v", err) + } + + if matched { + debug.Log("path %q excluded by a filter", item) + return true + } + + return false + } +} + // rejectIfPresent returns a RejectFunc which itself returns whether a path // should be excluded. The RejectFunc considers a file to be excluded when // it resides in a directory with an exclusion file, that is specified by @@ -24,7 +44,7 @@ type RejectFunc func(filename string, fi os.FileInfo) bool // non-nil if the filename component of excludeFileSpec is empty. func rejectIfPresent(excludeFileSpec string) (RejectFunc, error) { if excludeFileSpec == "" { - return func(string, os.FileInfo) bool { return false }, nil + return nil, errors.New("name for exclusion tagfile is empty") } colon := strings.Index(excludeFileSpec, ":") if colon == 0 {