Mercurial > hg
changeset 32395:24245b54aa8a
match: replace match class by match function (API)
The matcher class is getting hard to understand. It will be easier to
follow if we can break it up into simpler matchers that we then
compose. I'm hoping to have one matcher that accepts regular
(non-include) patterns, one for exact file matches, one that always
matches (and maybe one that never does) and then compose them by
intersection and difference.
This patch takes a simple but important step towards that goal by
making match.match() a function (and renaming the matcher class itself
from "match" to "matcher"). The new function will eventually be
responsible for creating the simple matchers and composing them.
icasefsmatcher similarly gets a factory function (called
"icasefsmatch"). I also moved the other factory functions nearby.
author | Martin von Zweigbergk <martinvonz@google.com> |
---|---|
date | Fri, 12 May 2017 23:11:41 -0700 |
parents | 38a2b9d90131 |
children | ec0311a3a4da |
files | mercurial/context.py mercurial/match.py |
diffstat | 2 files changed, 65 insertions(+), 50 deletions(-) [+] |
line wrap: on
line diff
--- a/mercurial/context.py Sun May 21 18:36:28 2017 -0400 +++ b/mercurial/context.py Fri May 12 23:11:41 2017 -0700 @@ -1595,7 +1595,7 @@ # to actual case in the filesystem. matcherfunc = matchmod.match if not util.fscasesensitive(r.root): - matcherfunc = matchmod.icasefsmatcher + matcherfunc = matchmod.icasefsmatch return matcherfunc(r.root, r.getcwd(), pats, include, exclude, default, auditor=r.auditor, ctx=self,
--- a/mercurial/match.py Sun May 21 18:36:28 2017 -0400 +++ b/mercurial/match.py Fri May 12 23:11:41 2017 -0700 @@ -84,39 +84,71 @@ return False return True -class match(object): +def match(root, cwd, patterns, include=None, exclude=None, default='glob', + exact=False, auditor=None, ctx=None, listsubrepos=False, warn=None, + badfn=None): + """build an object to match a set of file patterns + + arguments: + root - the canonical root of the tree you're matching against + cwd - the current working directory, if relevant + patterns - patterns to find + include - patterns to include (unless they are excluded) + exclude - patterns to exclude (even if they are included) + default - if a pattern in patterns has no explicit type, assume this one + exact - patterns are actually filenames (include/exclude still apply) + warn - optional function used for printing warnings + badfn - optional bad() callback for this matcher instead of the default + + a pattern is one of: + 'glob:<glob>' - a glob relative to cwd + 're:<regexp>' - a regular expression + 'path:<path>' - a path relative to repository root, which is matched + recursively + 'rootfilesin:<path>' - a path relative to repository root, which is + matched non-recursively (will not match subdirectories) + 'relglob:<glob>' - an unrooted glob (*.c matches C files in all dirs) + 'relpath:<path>' - a path relative to cwd + 'relre:<regexp>' - a regexp that needn't match the start of a name + 'set:<fileset>' - a fileset expression + 'include:<path>' - a file of patterns to read and include + 'subinclude:<path>' - a file of patterns to match against files under + the same directory + '<something>' - a pattern of the specified default type + """ + return matcher(root, cwd, patterns, include=include, exclude=exclude, + default=default, exact=exact, auditor=auditor, ctx=ctx, + listsubrepos=listsubrepos, warn=warn, badfn=badfn) + +def icasefsmatch(root, cwd, patterns, include=None, exclude=None, + default='glob', auditor=None, ctx=None, + listsubrepos=False, badfn=None): + """A matcher for wdir on case insensitive filesystems, which normalizes the + given patterns to the case in the filesystem. + """ + return icasefsmatcher(root, cwd, patterns, include=include, exclude=exclude, + default=default, auditor=auditor, ctx=ctx, + listsubrepos=listsubrepos, badfn=badfn) + +def exact(root, cwd, files, badfn=None): + return match(root, cwd, files, exact=True, badfn=badfn) + +def always(root, cwd): + return match(root, cwd, []) + +def badmatch(match, badfn): + """Make a copy of the given matcher, replacing its bad method with the given + one. + """ + m = copy.copy(match) + m.bad = badfn + return m + +class matcher(object): + def __init__(self, root, cwd, patterns, include=None, exclude=None, default='glob', exact=False, auditor=None, ctx=None, listsubrepos=False, warn=None, badfn=None): - """build an object to match a set of file patterns - - arguments: - root - the canonical root of the tree you're matching against - cwd - the current working directory, if relevant - patterns - patterns to find - include - patterns to include (unless they are excluded) - exclude - patterns to exclude (even if they are included) - default - if a pattern in patterns has no explicit type, assume this one - exact - patterns are actually filenames (include/exclude still apply) - warn - optional function used for printing warnings - badfn - optional bad() callback for this matcher instead of the default - - a pattern is one of: - 'glob:<glob>' - a glob relative to cwd - 're:<regexp>' - a regular expression - 'path:<path>' - a path relative to repository root, which is matched - recursively - 'rootfilesin:<path>' - a path relative to repository root, which is - matched non-recursively (will not match subdirectories) - 'relglob:<glob>' - an unrooted glob (*.c matches C files in all dirs) - 'relpath:<path>' - a path relative to cwd - 'relre:<regexp>' - a regexp that needn't match the start of a name - 'set:<fileset>' - a fileset expression - 'include:<path>' - a file of patterns to read and include - 'subinclude:<path>' - a file of patterns to match against files under - the same directory - '<something>' - a pattern of the specified default type - """ if include is None: include = [] if exclude is None: @@ -331,21 +363,7 @@ kindpats.append((kind, pat, '')) return kindpats -def exact(root, cwd, files, badfn=None): - return match(root, cwd, files, exact=True, badfn=badfn) - -def always(root, cwd): - return match(root, cwd, []) - -def badmatch(match, badfn): - """Make a copy of the given matcher, replacing its bad method with the given - one. - """ - m = copy.copy(match) - m.bad = badfn - return m - -class subdirmatcher(match): +class subdirmatcher(matcher): """Adapt a matcher to work on a subdirectory only. The paths are remapped to remove/insert the path as needed: @@ -416,10 +434,7 @@ dir = self._path + "/" + dir return self._matcher.visitdir(dir) -class icasefsmatcher(match): - """A matcher for wdir on case insensitive filesystems, which normalizes the - given patterns to the case in the filesystem. - """ +class icasefsmatcher(matcher): def __init__(self, root, cwd, patterns, include, exclude, default, auditor, ctx, listsubrepos=False, badfn=None):