Re: [PATCH 4 of 6] match: add prefixdirmatcher to adapt subrepo matcher back
On Sat, 07 Jul 2018 04:38:48 -0400, Yuya Nishihara wrote: # HG changeset patch # User Yuya Nishihara # Date 1528549447 -32400 # Sat Jun 09 22:04:07 2018 +0900 # Node ID 609c30cc3b87da9523988402ad0a1ba8899411cc # Parent f037e8dfa6c2047d0ef86efc2e83fece0fa08d80 match: add prefixdirmatcher to adapt subrepo matcher back This breaks test-doctest.py on Windows. Any ideas? I assumed it's a '/' vs '\' thing, but the little bit of playing around with it a couple weeks ago didn't yield any clues, and it looked like the code that gets called handles those differences. --- c:/Users/Matt/projects/hg/tests/test-doctest.py.out +++ c:/Users/Matt/projects/hg/tests/test-doctest.py.err @@ -0,0 +1,142 @@ +** +File "c:\Users\Matt\projects\hg\mercurial\match.py", line 696, in mercurial.match.prefixdirmatcher +Failed example: +m1 = match(b'root/d/e', b'f', [b'../a.txt', b'b.txt']) +Exception raised: +Traceback (most recent call last): + File "c:\Python27\lib\doctest.py", line 1315, in __run +compileflags, 1) in test.globs + File "", line 1, in +m1 = match(b'root/d/e', b'f', [b'../a.txt', b'b.txt']) + File "c:\Users\Matt\projects\hg\mercurial\match.py", line 176, in match +kindpats = normalize(patterns, default, root, cwd, auditor, warn) + File "c:\Users\Matt\projects\hg\mercurial\match.py", line 223, in _donormalize +pat = pathutil.canonpath(root, cwd, pat, auditor) + File "c:\Users\Matt\projects\hg\mercurial\pathutil.py", line 236, in canonpath +hint=hint) +Abort: ../a.txt not under root 'root/d/e' ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 4 of 6] match: add prefixdirmatcher to adapt subrepo matcher back
# HG changeset patch # User Yuya Nishihara # Date 1528549447 -32400 # Sat Jun 09 22:04:07 2018 +0900 # Node ID 609c30cc3b87da9523988402ad0a1ba8899411cc # Parent f037e8dfa6c2047d0ef86efc2e83fece0fa08d80 match: add prefixdirmatcher to adapt subrepo matcher back This serves as an inverse function to the subdirmatcher, and will be used to wrap a fileset matcher of subrepositories. One of the root/prefix paths could be deduced from the matcher attributes to be wrapped, but we don't since the callers of this class know the root/prefix paths and can simply pass them in. diff --git a/mercurial/match.py b/mercurial/match.py --- a/mercurial/match.py +++ b/mercurial/match.py @@ -684,6 +684,78 @@ class subdirmatcher(basematcher): return ('' % (self._path, self._matcher)) +class prefixdirmatcher(basematcher): +"""Adapt a matcher to work on a parent directory. + +The matcher's non-matching-attributes (root, cwd, bad, explicitdir, +traversedir) are ignored. + +The prefix path should usually be the relative path from the root of +this matcher to the root of the wrapped matcher. + +>>> m1 = match(b'root/d/e', b'f', [b'../a.txt', b'b.txt']) +>>> m2 = prefixdirmatcher(b'root', b'd/e/f', b'd/e', m1) +>>> bool(m2(b'a.txt'),) +False +>>> bool(m2(b'd/e/a.txt')) +True +>>> bool(m2(b'd/e/b.txt')) +False +>>> m2.files() +['d/e/a.txt', 'd/e/f/b.txt'] +>>> m2.exact(b'd/e/a.txt') +True +>>> m2.visitdir(b'd') +True +>>> m2.visitdir(b'd/e') +True +>>> m2.visitdir(b'd/e/f') +True +>>> m2.visitdir(b'd/e/g') +False +>>> m2.visitdir(b'd/ef') +False +""" + +def __init__(self, root, cwd, path, matcher, badfn=None): +super(prefixdirmatcher, self).__init__(root, cwd, badfn) +if not path: +raise error.ProgrammingError('prefix path must not be empty') +self._path = path +self._pathprefix = path + '/' +self._matcher = matcher + +@propertycache +def _files(self): +return [self._pathprefix + f for f in self._matcher._files] + +def matchfn(self, f): +if not f.startswith(self._pathprefix): +return False +return self._matcher.matchfn(f[len(self._pathprefix):]) + +@propertycache +def _pathdirs(self): +return set(util.finddirs(self._path)) | {'.'} + +def visitdir(self, dir): +if dir == self._path: +return self._matcher.visitdir('.') +if dir.startswith(self._pathprefix): +return self._matcher.visitdir(dir[len(self._pathprefix):]) +return dir in self._pathdirs + +def isexact(self): +return self._matcher.isexact() + +def prefix(self): +return self._matcher.prefix() + +@encoding.strmethod +def __repr__(self): +return ('' +% (pycompat.bytestr(self._path), self._matcher)) + class unionmatcher(basematcher): """A matcher that is the union of several matchers. ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel