mirror of
https://github.com/octoleo/restic.git
synced 2024-12-23 11:28:54 +00:00
Remove combined include/exclude filters
This commit is contained in:
parent
b425ea19e5
commit
0d8bad273d
@ -106,79 +106,3 @@ func MatchList(patterns []string, str string) (matched bool, err error) {
|
|||||||
|
|
||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// matchList returns true if str matches one of the patterns.
|
|
||||||
func matchList(patterns [][]string, str []string) (matched bool, err error) {
|
|
||||||
for _, pat := range patterns {
|
|
||||||
matched, err = match(pat, str)
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if matched {
|
|
||||||
return true, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Filter contains include and exclude patterns. If both lists of patterns are
|
|
||||||
// empty, all files are accepted.
|
|
||||||
type Filter struct {
|
|
||||||
include, exclude [][]string
|
|
||||||
}
|
|
||||||
|
|
||||||
// New returns a new filter with the given include/exclude lists of patterns.
|
|
||||||
func New(include, exclude []string) *Filter {
|
|
||||||
f := &Filter{}
|
|
||||||
|
|
||||||
for _, pat := range include {
|
|
||||||
f.include = append(f.include, strings.Split(pat, string(filepath.Separator)))
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, pat := range exclude {
|
|
||||||
f.exclude = append(f.exclude, strings.Split(pat, string(filepath.Separator)))
|
|
||||||
}
|
|
||||||
|
|
||||||
return f
|
|
||||||
}
|
|
||||||
|
|
||||||
// Match tests a filename against the filter. If include and exclude patterns
|
|
||||||
// are both empty, true is returned.
|
|
||||||
//
|
|
||||||
// If only include patterns and no exclude patterns are configured, true is
|
|
||||||
// returned iff name matches one of the include patterns.
|
|
||||||
//
|
|
||||||
// If only exclude patterns and no include patterns are configured, true is
|
|
||||||
// returned iff name does not match all of the exclude patterns.
|
|
||||||
func (f Filter) Match(name string) (matched bool, err error) {
|
|
||||||
if name == "" {
|
|
||||||
return false, ErrBadString
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(f.include) == 0 && len(f.exclude) == 0 {
|
|
||||||
return true, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
names := strings.Split(name, string(filepath.Separator))
|
|
||||||
if len(f.exclude) == 0 {
|
|
||||||
return matchList(f.include, names)
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(f.include) == 0 {
|
|
||||||
match, err := matchList(f.exclude, names)
|
|
||||||
return !match, err
|
|
||||||
}
|
|
||||||
|
|
||||||
excluded, err := matchList(f.exclude, names)
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if !excluded {
|
|
||||||
return true, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return matchList(f.include, names)
|
|
||||||
}
|
|
||||||
|
@ -222,138 +222,31 @@ func BenchmarkFilterLines(b *testing.B) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkFilterSingle(b *testing.B) {
|
func BenchmarkFilterPatterns(b *testing.B) {
|
||||||
pattern := "sdk/*/cpp/*/*vars.html"
|
patterns := []string{
|
||||||
line := "/usr/share/doc/libreoffice/sdk/docs/cpp/ref/a00517.html"
|
"sdk/*",
|
||||||
|
"*.html",
|
||||||
|
}
|
||||||
|
lines := extractTestLines(b)
|
||||||
|
var c uint
|
||||||
|
|
||||||
b.ResetTimer()
|
b.ResetTimer()
|
||||||
|
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
filter.Match(pattern, line)
|
c = 0
|
||||||
}
|
for _, line := range lines {
|
||||||
}
|
match, err := filter.MatchList(patterns, line)
|
||||||
|
|
||||||
type test struct {
|
|
||||||
path string
|
|
||||||
match bool
|
|
||||||
}
|
|
||||||
|
|
||||||
var filterTests = []struct {
|
|
||||||
include, exclude []string
|
|
||||||
tests []test
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
[]string{"*.go", "/home/user"},
|
|
||||||
[]string{},
|
|
||||||
[]test{
|
|
||||||
{"/home/user/foo/test.c", true},
|
|
||||||
{"/home/user/foo/test.go", true},
|
|
||||||
{"/home/foo/test.go", true},
|
|
||||||
{"/home/foo/test.doc", false},
|
|
||||||
{"/x", false},
|
|
||||||
{"main.go", true},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
nil,
|
|
||||||
[]string{"*.docx", "*.xlsx"},
|
|
||||||
[]test{
|
|
||||||
{"/home/user/foo/test.c", true},
|
|
||||||
{"/home/user/foo/test.docx", false},
|
|
||||||
{"/home/foo/test.xlsx", false},
|
|
||||||
{"/home/foo/test.doc", true},
|
|
||||||
{"/x", true},
|
|
||||||
{"main.go", true},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
[]string{"accounting.*", "*Partner*"},
|
|
||||||
[]string{"*.docx", "*.xlsx"},
|
|
||||||
[]test{
|
|
||||||
{"/home/user/foo/test.c", true},
|
|
||||||
{"/home/user/Partner/test.docx", true},
|
|
||||||
{"/home/user/bar/test.docx", false},
|
|
||||||
{"/home/user/test.xlsx", false},
|
|
||||||
{"/home/foo/test.doc", true},
|
|
||||||
{"/x", true},
|
|
||||||
{"main.go", true},
|
|
||||||
{"/users/A/accounting.xlsx", true},
|
|
||||||
{"/users/A/Calculation Partner.xlsx", true},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
[]string{"accounting.*", "*Partner*", "user/**/important*"},
|
|
||||||
[]string{"*.docx", "*.xlsx", "user/**/*hidden*"},
|
|
||||||
[]test{
|
|
||||||
{"/home/user/foo/test.c", true},
|
|
||||||
{"/home/user/Partner/test.docx", true},
|
|
||||||
{"/home/user/bar/test.docx", false},
|
|
||||||
{"/home/user/test.xlsx", false},
|
|
||||||
{"/home/foo/test.doc", true},
|
|
||||||
{"/x", true},
|
|
||||||
{"main.go", true},
|
|
||||||
{"/users/A/accounting.xlsx", true},
|
|
||||||
{"/users/A/Calculation Partner.xlsx", true},
|
|
||||||
{"/home/user/work/shared/test/important Calculations/help.txt", true},
|
|
||||||
{"/home/user/work/shared/test/important.xlsx", true},
|
|
||||||
{"/home/user/work/x/y/hidden/x", false},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestFilter(t *testing.T) {
|
|
||||||
for i, test := range filterTests {
|
|
||||||
f := filter.New(test.include, test.exclude)
|
|
||||||
|
|
||||||
for _, testfile := range test.tests {
|
|
||||||
matched, err := f.Match(testfile.path)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
b.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if matched != testfile.match {
|
if match {
|
||||||
t.Errorf("test %d: filter.Match(%q): expected %v, got %v",
|
c++
|
||||||
i, testfile.path, testfile.match, matched)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkFilter(b *testing.B) {
|
if c != 22185 {
|
||||||
lines := extractTestLines(b)
|
b.Fatalf("wrong number of matches: expected 22185, got %d", c)
|
||||||
f := filter.New([]string{"sdk", "*.html"}, []string{"*.png"})
|
|
||||||
|
|
||||||
b.ResetTimer()
|
|
||||||
|
|
||||||
for i := 0; i < b.N; i++ {
|
|
||||||
for _, line := range lines {
|
|
||||||
f.Match(line)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkFilterInclude(b *testing.B) {
|
|
||||||
lines := extractTestLines(b)
|
|
||||||
f := filter.New([]string{"sdk", "*.html"}, nil)
|
|
||||||
|
|
||||||
b.ResetTimer()
|
|
||||||
|
|
||||||
for i := 0; i < b.N; i++ {
|
|
||||||
for _, line := range lines {
|
|
||||||
f.Match(line)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkFilterExclude(b *testing.B) {
|
|
||||||
lines := extractTestLines(b)
|
|
||||||
f := filter.New(nil, []string{"*.png"})
|
|
||||||
|
|
||||||
b.ResetTimer()
|
|
||||||
|
|
||||||
for i := 0; i < b.N; i++ {
|
|
||||||
for _, line := range lines {
|
|
||||||
f.Match(line)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user