Show More
@@ -684,6 +684,78 b' class subdirmatcher(basematcher):' | |||||
684 | return ('<subdirmatcher path=%r, matcher=%r>' % |
|
684 | return ('<subdirmatcher path=%r, matcher=%r>' % | |
685 | (self._path, self._matcher)) |
|
685 | (self._path, self._matcher)) | |
686 |
|
686 | |||
|
687 | class prefixdirmatcher(basematcher): | |||
|
688 | """Adapt a matcher to work on a parent directory. | |||
|
689 | ||||
|
690 | The matcher's non-matching-attributes (root, cwd, bad, explicitdir, | |||
|
691 | traversedir) are ignored. | |||
|
692 | ||||
|
693 | The prefix path should usually be the relative path from the root of | |||
|
694 | this matcher to the root of the wrapped matcher. | |||
|
695 | ||||
|
696 | >>> m1 = match(b'root/d/e', b'f', [b'../a.txt', b'b.txt']) | |||
|
697 | >>> m2 = prefixdirmatcher(b'root', b'd/e/f', b'd/e', m1) | |||
|
698 | >>> bool(m2(b'a.txt'),) | |||
|
699 | False | |||
|
700 | >>> bool(m2(b'd/e/a.txt')) | |||
|
701 | True | |||
|
702 | >>> bool(m2(b'd/e/b.txt')) | |||
|
703 | False | |||
|
704 | >>> m2.files() | |||
|
705 | ['d/e/a.txt', 'd/e/f/b.txt'] | |||
|
706 | >>> m2.exact(b'd/e/a.txt') | |||
|
707 | True | |||
|
708 | >>> m2.visitdir(b'd') | |||
|
709 | True | |||
|
710 | >>> m2.visitdir(b'd/e') | |||
|
711 | True | |||
|
712 | >>> m2.visitdir(b'd/e/f') | |||
|
713 | True | |||
|
714 | >>> m2.visitdir(b'd/e/g') | |||
|
715 | False | |||
|
716 | >>> m2.visitdir(b'd/ef') | |||
|
717 | False | |||
|
718 | """ | |||
|
719 | ||||
|
720 | def __init__(self, root, cwd, path, matcher, badfn=None): | |||
|
721 | super(prefixdirmatcher, self).__init__(root, cwd, badfn) | |||
|
722 | if not path: | |||
|
723 | raise error.ProgrammingError('prefix path must not be empty') | |||
|
724 | self._path = path | |||
|
725 | self._pathprefix = path + '/' | |||
|
726 | self._matcher = matcher | |||
|
727 | ||||
|
728 | @propertycache | |||
|
729 | def _files(self): | |||
|
730 | return [self._pathprefix + f for f in self._matcher._files] | |||
|
731 | ||||
|
732 | def matchfn(self, f): | |||
|
733 | if not f.startswith(self._pathprefix): | |||
|
734 | return False | |||
|
735 | return self._matcher.matchfn(f[len(self._pathprefix):]) | |||
|
736 | ||||
|
737 | @propertycache | |||
|
738 | def _pathdirs(self): | |||
|
739 | return set(util.finddirs(self._path)) | {'.'} | |||
|
740 | ||||
|
741 | def visitdir(self, dir): | |||
|
742 | if dir == self._path: | |||
|
743 | return self._matcher.visitdir('.') | |||
|
744 | if dir.startswith(self._pathprefix): | |||
|
745 | return self._matcher.visitdir(dir[len(self._pathprefix):]) | |||
|
746 | return dir in self._pathdirs | |||
|
747 | ||||
|
748 | def isexact(self): | |||
|
749 | return self._matcher.isexact() | |||
|
750 | ||||
|
751 | def prefix(self): | |||
|
752 | return self._matcher.prefix() | |||
|
753 | ||||
|
754 | @encoding.strmethod | |||
|
755 | def __repr__(self): | |||
|
756 | return ('<prefixdirmatcher path=%r, matcher=%r>' | |||
|
757 | % (pycompat.bytestr(self._path), self._matcher)) | |||
|
758 | ||||
687 | class unionmatcher(basematcher): |
|
759 | class unionmatcher(basematcher): | |
688 | """A matcher that is the union of several matchers. |
|
760 | """A matcher that is the union of several matchers. | |
689 |
|
761 |
General Comments 0
You need to be logged in to leave comments.
Login now