From e9285539bedfa72d8ad0f62ef7c6903a838184a4 Mon Sep 17 00:00:00 2001 From: Alexander Neumann Date: Mon, 13 Jul 2015 22:51:35 +0200 Subject: [PATCH] filter: implement handling `**` --- filter/filter.go | 32 ++++++++++++++++++++++++++++++++ filter/filter_test.go | 16 +++++++++++++++- 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/filter/filter.go b/filter/filter.go index 493483a88..18f7aa718 100644 --- a/filter/filter.go +++ b/filter/filter.go @@ -31,7 +31,39 @@ func Match(pattern, str string) (matched bool, err error) { return match(patterns, strs) } +func hasDoubleWildcard(list []string) (ok bool, pos int) { + for i, item := range list { + if item == "**" { + return true, i + } + } + + return false, 0 +} + func match(patterns, strs []string) (matched bool, err error) { + if ok, pos := hasDoubleWildcard(patterns); ok { + // gradually expand '**' into separate wildcards + for i := 0; i <= len(strs)-len(patterns)+1; i++ { + newPat := patterns[:pos] + for k := 0; k < i; k++ { + newPat = append(newPat, "*") + } + newPat = append(newPat, patterns[pos+1:]...) + + matched, err := match(newPat, strs) + if err != nil { + return false, err + } + + if matched { + return true, nil + } + } + + return false, nil + } + if len(patterns) == 0 && len(strs) == 0 { return true, nil } diff --git a/filter/filter_test.go b/filter/filter_test.go index cd21ec054..fb4ab94b7 100644 --- a/filter/filter_test.go +++ b/filter/filter_test.go @@ -54,7 +54,21 @@ var matchTests = []struct { {"*.c", "bar/baz/test.go", false}, {"sdk", "/foo/bar/sdk", true}, {"sdk", "/foo/bar/sdk/test/sdk_foo.go", true}, - {"sdk/*/cpp/*/*vars*.html", "/usr/share/doc/libreoffice/sdk/docs/cpp/ref/a00517.html", false}, + { + "sdk/*/cpp/*/*vars*.html", + "/usr/share/doc/libreoffice/sdk/docs/cpp/ref/a00517.html", + false, + }, + {"foo/**/bar/*.go", "/home/user/foo/work/special/project/bar/test.go", true}, + {"foo/**/bar/*.go", "/home/user/foo/bar/test.go", true}, + {"foo/**/bar/*.go", "x/foo/bar/test.go", true}, + {"foo/**/bar/*.go", "foo/bar/test.go", true}, + {"foo/**/bar/*.go", "/home/user/foo/test.c", false}, + {"foo/**/bar/*.go", "bar/foo/main.go", false}, + {"foo/**/bar/*.go", "/foo/bar/main.go", true}, + {"foo/**/bar/*.go", "bar/main.go", false}, + {"foo/**/bar", "/home/user/foo/x/y/bar", true}, + {"foo/**/bar", "/home/user/foo/x/y/bar/main.go", true}, } func TestMatch(t *testing.T) {