mirror of
https://github.com/rclone/rclone.git
synced 2024-11-22 14:06:44 +08:00
Make filtering rules for help and listremotes more lenient
This commit is contained in:
parent
303358eeda
commit
da9faf1ffe
|
@ -74,7 +74,7 @@ var helpFlags = &cobra.Command{
|
|||
Root.SetUsageTemplate(docFlagsTemplate)
|
||||
} else {
|
||||
if len(args) > 0 {
|
||||
re, err := filter.GlobStringToRegexp(args[0], false)
|
||||
re, err := filter.GlobStringToRegexp(args[0], false, true)
|
||||
if err != nil {
|
||||
log.Fatalf("Invalid flag filter: %v", err)
|
||||
}
|
||||
|
|
|
@ -146,7 +146,7 @@ according to regular rclone filtering pattern syntax.
|
|||
"description": filterDescription,
|
||||
} {
|
||||
if v != "" {
|
||||
filterRe, err := filter.GlobStringToRegexp(v, false)
|
||||
filterRe, err := filter.GlobStringToRegexp(v, false, true)
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid %s filter argument: %w", k, err)
|
||||
}
|
||||
|
|
|
@ -17,8 +17,18 @@ func GlobPathToRegexp(glob string, ignoreCase bool) (*regexp.Regexp, error) {
|
|||
}
|
||||
|
||||
// GlobStringToRegexp converts an rsync style glob string to a regexp
|
||||
func GlobStringToRegexp(glob string, ignoreCase bool) (*regexp.Regexp, error) {
|
||||
return globToRegexp(glob, false, true, ignoreCase)
|
||||
//
|
||||
// Without adding of anchors but with ignoring of case, i.e. called
|
||||
// `GlobStringToRegexp(glob, false, true)`, it takes a lenient approach
|
||||
// where the glob "sum" would match "CheckSum", more similar to text
|
||||
// search functions than strict glob filtering.
|
||||
//
|
||||
// With adding of anchors and not ignoring case, i.e. called
|
||||
// `GlobStringToRegexp(glob, true, false)`, it uses a strict glob
|
||||
// interpretation where the previous example would have to be changed to
|
||||
// "*Sum" to match "CheckSum".
|
||||
func GlobStringToRegexp(glob string, addAnchors bool, ignoreCase bool) (*regexp.Regexp, error) {
|
||||
return globToRegexp(glob, false, addAnchors, ignoreCase)
|
||||
}
|
||||
|
||||
// globToRegexp converts an rsync style glob to a regexp
|
||||
|
|
|
@ -8,67 +8,6 @@ import (
|
|||
)
|
||||
|
||||
func TestGlobStringToRegexp(t *testing.T) {
|
||||
for _, test := range []struct {
|
||||
in string
|
||||
want string
|
||||
error string
|
||||
}{
|
||||
{``, `^$`, ``},
|
||||
{`potato`, `^potato$`, ``},
|
||||
{`potato,sausage`, `^potato,sausage$`, ``},
|
||||
{`/potato`, `^/potato$`, ``},
|
||||
{`potato?sausage`, `^potato.sausage$`, ``},
|
||||
{`potat[oa]`, `^potat[oa]$`, ``},
|
||||
{`potat[a-z]or`, `^potat[a-z]or$`, ``},
|
||||
{`potat[[:alpha:]]or`, `^potat[[:alpha:]]or$`, ``},
|
||||
{`'.' '+' '(' ')' '|' '^' '$'`, `^'\.' '\+' '\(' '\)' '\|' '\^' '\$'$`, ``},
|
||||
{`*.jpg`, `^.*\.jpg$`, ``},
|
||||
{`a{b,c,d}e`, `^a(b|c|d)e$`, ``},
|
||||
{`potato**`, ``, `too many stars`},
|
||||
{`potato**sausage`, ``, `too many stars`},
|
||||
{`*.p[lm]`, `^.*\.p[lm]$`, ``},
|
||||
{`[\[\]]`, `^[\[\]]$`, ``},
|
||||
{`***potato`, ``, `too many stars`},
|
||||
{`***`, ``, `too many stars`},
|
||||
{`ab]c`, ``, `mismatched ']'`},
|
||||
{`ab[c`, ``, `mismatched '[' and ']'`},
|
||||
{`ab{x{cd`, ``, `can't nest`},
|
||||
{`ab{}}cd`, ``, `mismatched '{' and '}'`},
|
||||
{`ab}c`, ``, `mismatched '{' and '}'`},
|
||||
{`ab{c`, ``, `mismatched '{' and '}'`},
|
||||
{`*.{jpg,png,gif}`, `^.*\.(jpg|png|gif)$`, ``},
|
||||
{`[a--b]`, ``, `bad glob pattern`},
|
||||
{`a\*b`, `^a\*b$`, ``},
|
||||
{`a\\b`, `^a\\b$`, ``},
|
||||
{`a{{.*}}b`, `^a(.*)b$`, ``},
|
||||
{`a{{.*}`, ``, `mismatched '{{' and '}}'`},
|
||||
{`{{regexp}}`, `^(regexp)$`, ``},
|
||||
{`\{{{regexp}}`, `^\{(regexp)$`, ``},
|
||||
{`/{{regexp}}`, `^/(regexp)$`, ``},
|
||||
{`/{{\d{8}}}`, `^/(\d{8})$`, ``},
|
||||
{`/{{\}}}`, `^/(\})$`, ``},
|
||||
{`{{(?i)regexp}}`, `^((?i)regexp)$`, ``},
|
||||
} {
|
||||
for _, ignoreCase := range []bool{false, true} {
|
||||
gotRe, err := GlobStringToRegexp(test.in, ignoreCase)
|
||||
if test.error == "" {
|
||||
require.NoError(t, err, test.in)
|
||||
prefix := ""
|
||||
if ignoreCase {
|
||||
prefix = "(?i)"
|
||||
}
|
||||
got := gotRe.String()
|
||||
assert.Equal(t, prefix+test.want, got, test.in)
|
||||
} else {
|
||||
require.Error(t, err, test.in)
|
||||
assert.Contains(t, err.Error(), test.error, test.in)
|
||||
assert.Nil(t, gotRe)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestGlobStringToRegexpWithoutAnchors(t *testing.T) {
|
||||
for _, test := range []struct {
|
||||
in string
|
||||
want string
|
||||
|
@ -111,15 +50,21 @@ func TestGlobStringToRegexpWithoutAnchors(t *testing.T) {
|
|||
{`{{(?i)regexp}}`, `((?i)regexp)`, ``},
|
||||
} {
|
||||
for _, ignoreCase := range []bool{false, true} {
|
||||
gotRe, err := globToRegexp(test.in, false, false, ignoreCase)
|
||||
for _, addAnchors := range []bool{false, true} {
|
||||
gotRe, err := GlobStringToRegexp(test.in, addAnchors, ignoreCase)
|
||||
if test.error == "" {
|
||||
require.NoError(t, err, test.in)
|
||||
prefix := ""
|
||||
suffix := ""
|
||||
if ignoreCase {
|
||||
prefix = "(?i)"
|
||||
prefix += "(?i)"
|
||||
}
|
||||
if addAnchors {
|
||||
prefix += "^"
|
||||
suffix += "$"
|
||||
}
|
||||
got := gotRe.String()
|
||||
assert.Equal(t, prefix+test.want, got, test.in)
|
||||
assert.Equal(t, prefix+test.want+suffix, got, test.in)
|
||||
} else {
|
||||
require.Error(t, err, test.in)
|
||||
assert.Contains(t, err.Error(), test.error, test.in)
|
||||
|
@ -128,6 +73,7 @@ func TestGlobStringToRegexpWithoutAnchors(t *testing.T) {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestGlobPathToRegexp(t *testing.T) {
|
||||
for _, test := range []struct {
|
||||
|
|
Loading…
Reference in New Issue
Block a user