annotate mercurial/match.py @ 38993:081cc9a95b65

match: add visitchildrenset complement to visitdir `visitdir(d)` lets a caller query whether the directory is part of the matcher. It can receive a response of 'all' (yes, and all children, you can stop calling visitdir now), False (no, and no children either), or True (yes, either something in this directory or a child is part of the matcher). `visitchildrenset(d)` augments that by instead of returning True, it returns a list of items to actually investigate. With this, code can be modified from: for f in self.all_items: if match.visitdir(self.dir + '/' + f): <do stuff> to be: for f in self.all_items.intersect(match.visitchildrenset(self.dir)): <do stuff> use of this function can provide significant performance improvements, especially when using narrow (so that the matcher is much smaller than the stuff we see on disk) and/or treemanifests (so that we can avoid loading manifests for trees that aren't part of the matcher). Differential Revision: https://phab.mercurial-scm.org/D4130
author spectral <spectral@google.com>
date Mon, 06 Aug 2018 12:52:33 -0700
parents 5a7df82de142
children f356be1a7ba3
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
8761
0289f384e1e5 Generally replace "file name" with "filename" in help and comments.
timeless <timeless@gmail.com>
parents: 8682
diff changeset
1 # match.py - filename matching
8231
5d4d88a4f5e6 match: add copyright and license header
Martin Geisler <mg@lazybytes.net>
parents: 8152
diff changeset
2 #
5d4d88a4f5e6 match: add copyright and license header
Martin Geisler <mg@lazybytes.net>
parents: 8152
diff changeset
3 # Copyright 2008, 2009 Matt Mackall <mpm@selenic.com> and others
5d4d88a4f5e6 match: add copyright and license header
Martin Geisler <mg@lazybytes.net>
parents: 8152
diff changeset
4 #
5d4d88a4f5e6 match: add copyright and license header
Martin Geisler <mg@lazybytes.net>
parents: 8152
diff changeset
5 # This software may be used and distributed according to the terms of the
10263
25e572394f5c Update license to GPLv2+
Matt Mackall <mpm@selenic.com>
parents: 9036
diff changeset
6 # GNU General Public License version 2 or any later version.
8231
5d4d88a4f5e6 match: add copyright and license header
Martin Geisler <mg@lazybytes.net>
parents: 8152
diff changeset
7
34152
a8994d08e4a2 doctest: use print_function and convert bytes to unicode where needed
Yuya Nishihara <yuya@tcha.org>
parents: 34146
diff changeset
8 from __future__ import absolute_import, print_function
25958
c4ccf2d394a7 match: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25875
diff changeset
9
c4ccf2d394a7 match: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25875
diff changeset
10 import copy
38993
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
11 import itertools
25958
c4ccf2d394a7 match: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25875
diff changeset
12 import os
c4ccf2d394a7 match: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25875
diff changeset
13 import re
c4ccf2d394a7 match: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25875
diff changeset
14
c4ccf2d394a7 match: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25875
diff changeset
15 from .i18n import _
c4ccf2d394a7 match: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25875
diff changeset
16 from . import (
36088
c4fa47f880d3 py3: make sure we return str from __repr__
Pulkit Goyal <7895pulkit@gmail.com>
parents: 35659
diff changeset
17 encoding,
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26014
diff changeset
18 error,
25958
c4ccf2d394a7 match: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25875
diff changeset
19 pathutil,
36601
9adfa48792a7 match: some minimal pycompat fixes guided by test-hgignore.t
Augie Fackler <augie@google.com>
parents: 36088
diff changeset
20 pycompat,
25958
c4ccf2d394a7 match: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25875
diff changeset
21 util,
c4ccf2d394a7 match: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25875
diff changeset
22 )
37087
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36601
diff changeset
23 from .utils import (
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36601
diff changeset
24 stringutil,
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36601
diff changeset
25 )
6576
69f3e9ac7c56 walk: introduce match objects
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
26
33710
2be0bf186950 match: expose some data and functionality to other modules
Kostia Balytskyi <ikostia@fb.com>
parents: 33582
diff changeset
27 allpatternkinds = ('re', 'glob', 'path', 'relglob', 'relpath', 'relre',
2be0bf186950 match: expose some data and functionality to other modules
Kostia Balytskyi <ikostia@fb.com>
parents: 33582
diff changeset
28 'listfile', 'listfile0', 'set', 'include', 'subinclude',
2be0bf186950 match: expose some data and functionality to other modules
Kostia Balytskyi <ikostia@fb.com>
parents: 33582
diff changeset
29 'rootfilesin')
2be0bf186950 match: expose some data and functionality to other modules
Kostia Balytskyi <ikostia@fb.com>
parents: 33582
diff changeset
30 cwdrelativepatternkinds = ('relpath', 'glob')
2be0bf186950 match: expose some data and functionality to other modules
Kostia Balytskyi <ikostia@fb.com>
parents: 33582
diff changeset
31
24636
36872036169b treemanifest: further optimize treemanifest.matches()
Drew Gottlieb <drgott@google.com>
parents: 24452
diff changeset
32 propertycache = util.propertycache
36872036169b treemanifest: further optimize treemanifest.matches()
Drew Gottlieb <drgott@google.com>
parents: 24452
diff changeset
33
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
34 def _rematcher(regex):
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
35 '''compile the regexp with the best available regexp engine and return a
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
36 matcher function'''
21909
335bb8b80443 match: use util.re.compile instead of util.compilere
Siddharth Agarwal <sid0@fb.com>
parents: 21815
diff changeset
37 m = util.re.compile(regex)
16943
8d08a28aa63e matcher: use re2 bindings if available
Bryan O'Sullivan <bryano@fb.com>
parents: 16791
diff changeset
38 try:
8d08a28aa63e matcher: use re2 bindings if available
Bryan O'Sullivan <bryano@fb.com>
parents: 16791
diff changeset
39 # slightly faster, provided by facebook's re2 bindings
8d08a28aa63e matcher: use re2 bindings if available
Bryan O'Sullivan <bryano@fb.com>
parents: 16791
diff changeset
40 return m.test_match
8d08a28aa63e matcher: use re2 bindings if available
Bryan O'Sullivan <bryano@fb.com>
parents: 16791
diff changeset
41 except AttributeError:
8d08a28aa63e matcher: use re2 bindings if available
Bryan O'Sullivan <bryano@fb.com>
parents: 16791
diff changeset
42 return m.match
8d08a28aa63e matcher: use re2 bindings if available
Bryan O'Sullivan <bryano@fb.com>
parents: 16791
diff changeset
43
38613
760cc5dc01e8 fileset: restrict getfileset() to not return a computed set (API)
Yuya Nishihara <yuya@tcha.org>
parents: 38612
diff changeset
44 def _expandsets(root, cwd, kindpats, ctx, listsubrepos, badfn):
760cc5dc01e8 fileset: restrict getfileset() to not return a computed set (API)
Yuya Nishihara <yuya@tcha.org>
parents: 38612
diff changeset
45 '''Returns the kindpats list with the 'set' patterns expanded to matchers'''
760cc5dc01e8 fileset: restrict getfileset() to not return a computed set (API)
Yuya Nishihara <yuya@tcha.org>
parents: 38612
diff changeset
46 matchers = []
14675
cfc89398f710 match: introduce basic fileset support
Matt Mackall <mpm@selenic.com>
parents: 14674
diff changeset
47 other = []
cfc89398f710 match: introduce basic fileset support
Matt Mackall <mpm@selenic.com>
parents: 14674
diff changeset
48
25213
08a8e9da0ae7 match: add source to kindpats list
Durham Goode <durham@fb.com>
parents: 25195
diff changeset
49 for kind, pat, source in kindpats:
14675
cfc89398f710 match: introduce basic fileset support
Matt Mackall <mpm@selenic.com>
parents: 14674
diff changeset
50 if kind == 'set':
cfc89398f710 match: introduce basic fileset support
Matt Mackall <mpm@selenic.com>
parents: 14674
diff changeset
51 if not ctx:
32482
57d6c0c74b1b match: use ProgrammingError where appropriate
Martin von Zweigbergk <martinvonz@google.com>
parents: 32453
diff changeset
52 raise error.ProgrammingError("fileset expression with no "
57d6c0c74b1b match: use ProgrammingError where appropriate
Martin von Zweigbergk <martinvonz@google.com>
parents: 32453
diff changeset
53 "context")
38613
760cc5dc01e8 fileset: restrict getfileset() to not return a computed set (API)
Yuya Nishihara <yuya@tcha.org>
parents: 38612
diff changeset
54 matchers.append(ctx.matchfileset(pat, badfn=badfn))
25122
755d23a49170 match: resolve filesets in subrepos for commands given the '-S' argument
Matt Harbison <matt_harbison@yahoo.com>
parents: 25114
diff changeset
55
755d23a49170 match: resolve filesets in subrepos for commands given the '-S' argument
Matt Harbison <matt_harbison@yahoo.com>
parents: 25114
diff changeset
56 if listsubrepos:
755d23a49170 match: resolve filesets in subrepos for commands given the '-S' argument
Matt Harbison <matt_harbison@yahoo.com>
parents: 25114
diff changeset
57 for subpath in ctx.substate:
38613
760cc5dc01e8 fileset: restrict getfileset() to not return a computed set (API)
Yuya Nishihara <yuya@tcha.org>
parents: 38612
diff changeset
58 sm = ctx.sub(subpath).matchfileset(pat, badfn=badfn)
760cc5dc01e8 fileset: restrict getfileset() to not return a computed set (API)
Yuya Nishihara <yuya@tcha.org>
parents: 38612
diff changeset
59 pm = prefixdirmatcher(root, cwd, subpath, sm, badfn=badfn)
760cc5dc01e8 fileset: restrict getfileset() to not return a computed set (API)
Yuya Nishihara <yuya@tcha.org>
parents: 38612
diff changeset
60 matchers.append(pm)
25122
755d23a49170 match: resolve filesets in subrepos for commands given the '-S' argument
Matt Harbison <matt_harbison@yahoo.com>
parents: 25114
diff changeset
61
14675
cfc89398f710 match: introduce basic fileset support
Matt Mackall <mpm@selenic.com>
parents: 14674
diff changeset
62 continue
25213
08a8e9da0ae7 match: add source to kindpats list
Durham Goode <durham@fb.com>
parents: 25195
diff changeset
63 other.append((kind, pat, source))
38613
760cc5dc01e8 fileset: restrict getfileset() to not return a computed set (API)
Yuya Nishihara <yuya@tcha.org>
parents: 38612
diff changeset
64 return matchers, other
14675
cfc89398f710 match: introduce basic fileset support
Matt Mackall <mpm@selenic.com>
parents: 14674
diff changeset
65
25283
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
66 def _expandsubinclude(kindpats, root):
32185
6dea1701f170 match: make subinclude construction lazy
Durham Goode <durham@fb.com>
parents: 31442
diff changeset
67 '''Returns the list of subinclude matcher args and the kindpats without the
25283
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
68 subincludes in it.'''
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
69 relmatchers = []
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
70 other = []
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
71
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
72 for kind, pat, source in kindpats:
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
73 if kind == 'subinclude':
25301
caaf4045eca8 match: normpath the ignore source when expanding the 'subinclude' kind
Matt Harbison <matt_harbison@yahoo.com>
parents: 25283
diff changeset
74 sourceroot = pathutil.dirname(util.normpath(source))
25283
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
75 pat = util.pconvert(pat)
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
76 path = pathutil.join(sourceroot, pat)
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
77
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
78 newroot = pathutil.dirname(path)
32185
6dea1701f170 match: make subinclude construction lazy
Durham Goode <durham@fb.com>
parents: 31442
diff changeset
79 matcherargs = (newroot, '', [], ['include:%s' % path])
25283
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
80
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
81 prefix = pathutil.canonpath(root, root, newroot)
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
82 if prefix:
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
83 prefix += '/'
32185
6dea1701f170 match: make subinclude construction lazy
Durham Goode <durham@fb.com>
parents: 31442
diff changeset
84 relmatchers.append((prefix, matcherargs))
25283
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
85 else:
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
86 other.append((kind, pat, source))
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
87
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
88 return relmatchers, other
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
89
24447
d44d53bc9a1e matcher: make e.g. 'relpath:.' lead to fast paths
Martin von Zweigbergk <martinvonz@google.com>
parents: 23686
diff changeset
90 def _kindpatsalwaysmatch(kindpats):
d44d53bc9a1e matcher: make e.g. 'relpath:.' lead to fast paths
Martin von Zweigbergk <martinvonz@google.com>
parents: 23686
diff changeset
91 """"Checks whether the kindspats match everything, as e.g.
d44d53bc9a1e matcher: make e.g. 'relpath:.' lead to fast paths
Martin von Zweigbergk <martinvonz@google.com>
parents: 23686
diff changeset
92 'relpath:.' does.
d44d53bc9a1e matcher: make e.g. 'relpath:.' lead to fast paths
Martin von Zweigbergk <martinvonz@google.com>
parents: 23686
diff changeset
93 """
25213
08a8e9da0ae7 match: add source to kindpats list
Durham Goode <durham@fb.com>
parents: 25195
diff changeset
94 for kind, pat, source in kindpats:
24447
d44d53bc9a1e matcher: make e.g. 'relpath:.' lead to fast paths
Martin von Zweigbergk <martinvonz@google.com>
parents: 23686
diff changeset
95 if pat != '' or kind not in ['relpath', 'glob']:
d44d53bc9a1e matcher: make e.g. 'relpath:.' lead to fast paths
Martin von Zweigbergk <martinvonz@google.com>
parents: 23686
diff changeset
96 return False
d44d53bc9a1e matcher: make e.g. 'relpath:.' lead to fast paths
Martin von Zweigbergk <martinvonz@google.com>
parents: 23686
diff changeset
97 return True
d44d53bc9a1e matcher: make e.g. 'relpath:.' lead to fast paths
Martin von Zweigbergk <martinvonz@google.com>
parents: 23686
diff changeset
98
38581
9f9ffe5f687c match: compose 'set:' pattern as matcher
Yuya Nishihara <yuya@tcha.org>
parents: 38580
diff changeset
99 def _buildkindpatsmatcher(matchercls, root, cwd, kindpats, ctx=None,
9f9ffe5f687c match: compose 'set:' pattern as matcher
Yuya Nishihara <yuya@tcha.org>
parents: 38580
diff changeset
100 listsubrepos=False, badfn=None):
9f9ffe5f687c match: compose 'set:' pattern as matcher
Yuya Nishihara <yuya@tcha.org>
parents: 38580
diff changeset
101 matchers = []
38613
760cc5dc01e8 fileset: restrict getfileset() to not return a computed set (API)
Yuya Nishihara <yuya@tcha.org>
parents: 38612
diff changeset
102 fms, kindpats = _expandsets(root, cwd, kindpats, ctx=ctx,
760cc5dc01e8 fileset: restrict getfileset() to not return a computed set (API)
Yuya Nishihara <yuya@tcha.org>
parents: 38612
diff changeset
103 listsubrepos=listsubrepos, badfn=badfn)
38581
9f9ffe5f687c match: compose 'set:' pattern as matcher
Yuya Nishihara <yuya@tcha.org>
parents: 38580
diff changeset
104 if kindpats:
38582
6467286b829c match: remove ctx argument from code path down to _buildmatch()
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
105 m = matchercls(root, cwd, kindpats, listsubrepos=listsubrepos,
38581
9f9ffe5f687c match: compose 'set:' pattern as matcher
Yuya Nishihara <yuya@tcha.org>
parents: 38580
diff changeset
106 badfn=badfn)
9f9ffe5f687c match: compose 'set:' pattern as matcher
Yuya Nishihara <yuya@tcha.org>
parents: 38580
diff changeset
107 matchers.append(m)
38613
760cc5dc01e8 fileset: restrict getfileset() to not return a computed set (API)
Yuya Nishihara <yuya@tcha.org>
parents: 38612
diff changeset
108 if fms:
760cc5dc01e8 fileset: restrict getfileset() to not return a computed set (API)
Yuya Nishihara <yuya@tcha.org>
parents: 38612
diff changeset
109 matchers.extend(fms)
38581
9f9ffe5f687c match: compose 'set:' pattern as matcher
Yuya Nishihara <yuya@tcha.org>
parents: 38580
diff changeset
110 if not matchers:
9f9ffe5f687c match: compose 'set:' pattern as matcher
Yuya Nishihara <yuya@tcha.org>
parents: 38580
diff changeset
111 return nevermatcher(root, cwd, badfn=badfn)
9f9ffe5f687c match: compose 'set:' pattern as matcher
Yuya Nishihara <yuya@tcha.org>
parents: 38580
diff changeset
112 if len(matchers) == 1:
9f9ffe5f687c match: compose 'set:' pattern as matcher
Yuya Nishihara <yuya@tcha.org>
parents: 38580
diff changeset
113 return matchers[0]
9f9ffe5f687c match: compose 'set:' pattern as matcher
Yuya Nishihara <yuya@tcha.org>
parents: 38580
diff changeset
114 return unionmatcher(matchers)
9f9ffe5f687c match: compose 'set:' pattern as matcher
Yuya Nishihara <yuya@tcha.org>
parents: 38580
diff changeset
115
32748
3e8eb6d84a5c match: allow pats to be None
Martin von Zweigbergk <martinvonz@google.com>
parents: 32673
diff changeset
116 def match(root, cwd, patterns=None, include=None, exclude=None, default='glob',
32433
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
117 exact=False, auditor=None, ctx=None, listsubrepos=False, warn=None,
32439
284b18303f61 match: replace icasefsmatch() function by flag to regular match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32438
diff changeset
118 badfn=None, icasefs=False):
32433
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
119 """build an object to match a set of file patterns
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
120
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
121 arguments:
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
122 root - the canonical root of the tree you're matching against
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
123 cwd - the current working directory, if relevant
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
124 patterns - patterns to find
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
125 include - patterns to include (unless they are excluded)
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
126 exclude - patterns to exclude (even if they are included)
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
127 default - if a pattern in patterns has no explicit type, assume this one
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
128 exact - patterns are actually filenames (include/exclude still apply)
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
129 warn - optional function used for printing warnings
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
130 badfn - optional bad() callback for this matcher instead of the default
32439
284b18303f61 match: replace icasefsmatch() function by flag to regular match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32438
diff changeset
131 icasefs - make a matcher for wdir on case insensitive filesystems, which
284b18303f61 match: replace icasefsmatch() function by flag to regular match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32438
diff changeset
132 normalizes the given patterns to the case in the filesystem
32433
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
133
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
134 a pattern is one of:
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
135 'glob:<glob>' - a glob relative to cwd
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
136 're:<regexp>' - a regular expression
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
137 'path:<path>' - a path relative to repository root, which is matched
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
138 recursively
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
139 'rootfilesin:<path>' - a path relative to repository root, which is
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
140 matched non-recursively (will not match subdirectories)
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
141 'relglob:<glob>' - an unrooted glob (*.c matches C files in all dirs)
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
142 'relpath:<path>' - a path relative to cwd
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
143 'relre:<regexp>' - a regexp that needn't match the start of a name
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
144 'set:<fileset>' - a fileset expression
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
145 'include:<path>' - a file of patterns to read and include
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
146 'subinclude:<path>' - a file of patterns to match against files under
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
147 the same directory
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
148 '<something>' - a pattern of the specified default type
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
149 """
32439
284b18303f61 match: replace icasefsmatch() function by flag to regular match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32438
diff changeset
150 normalize = _donormalize
284b18303f61 match: replace icasefsmatch() function by flag to regular match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32438
diff changeset
151 if icasefs:
32453
9695aca1a3a0 match: catch attempts to create case-insenstive exact matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
152 if exact:
32482
57d6c0c74b1b match: use ProgrammingError where appropriate
Martin von Zweigbergk <martinvonz@google.com>
parents: 32453
diff changeset
153 raise error.ProgrammingError("a case-insensitive exact matcher "
57d6c0c74b1b match: use ProgrammingError where appropriate
Martin von Zweigbergk <martinvonz@google.com>
parents: 32453
diff changeset
154 "doesn't make sense")
32439
284b18303f61 match: replace icasefsmatch() function by flag to regular match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32438
diff changeset
155 dirstate = ctx.repo().dirstate
284b18303f61 match: replace icasefsmatch() function by flag to regular match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32438
diff changeset
156 dsnormalize = dirstate.normalize
284b18303f61 match: replace icasefsmatch() function by flag to regular match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32438
diff changeset
157
284b18303f61 match: replace icasefsmatch() function by flag to regular match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32438
diff changeset
158 def normalize(patterns, default, root, cwd, auditor, warn):
284b18303f61 match: replace icasefsmatch() function by flag to regular match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32438
diff changeset
159 kp = _donormalize(patterns, default, root, cwd, auditor, warn)
284b18303f61 match: replace icasefsmatch() function by flag to regular match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32438
diff changeset
160 kindpats = []
284b18303f61 match: replace icasefsmatch() function by flag to regular match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32438
diff changeset
161 for kind, pats, source in kp:
284b18303f61 match: replace icasefsmatch() function by flag to regular match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32438
diff changeset
162 if kind not in ('re', 'relre'): # regex can't be normalized
284b18303f61 match: replace icasefsmatch() function by flag to regular match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32438
diff changeset
163 p = pats
284b18303f61 match: replace icasefsmatch() function by flag to regular match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32438
diff changeset
164 pats = dsnormalize(pats)
284b18303f61 match: replace icasefsmatch() function by flag to regular match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32438
diff changeset
165
284b18303f61 match: replace icasefsmatch() function by flag to regular match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32438
diff changeset
166 # Preserve the original to handle a case only rename.
284b18303f61 match: replace icasefsmatch() function by flag to regular match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32438
diff changeset
167 if p != pats and p in dirstate:
284b18303f61 match: replace icasefsmatch() function by flag to regular match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32438
diff changeset
168 kindpats.append((kind, p, source))
284b18303f61 match: replace icasefsmatch() function by flag to regular match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32438
diff changeset
169
284b18303f61 match: replace icasefsmatch() function by flag to regular match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32438
diff changeset
170 kindpats.append((kind, pats, source))
284b18303f61 match: replace icasefsmatch() function by flag to regular match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32438
diff changeset
171 return kindpats
284b18303f61 match: replace icasefsmatch() function by flag to regular match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32438
diff changeset
172
32532
a3583852861a match: handle exact matching using new exactmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32530
diff changeset
173 if exact:
a3583852861a match: handle exact matching using new exactmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32530
diff changeset
174 m = exactmatcher(root, cwd, patterns, badfn)
32586
20c9f3ecc192 match: handle everything-matching using new alwaysmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32585
diff changeset
175 elif patterns:
32589
5f08eca8f8d3 match: move normalize() call out of matcher constructors
Martin von Zweigbergk <martinvonz@google.com>
parents: 32588
diff changeset
176 kindpats = normalize(patterns, default, root, cwd, auditor, warn)
32590
3fdcc34c0aba match: remove special-casing of always-matching patterns in patternmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32589
diff changeset
177 if _kindpatsalwaysmatch(kindpats):
3fdcc34c0aba match: remove special-casing of always-matching patterns in patternmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32589
diff changeset
178 m = alwaysmatcher(root, cwd, badfn, relativeuipath=True)
3fdcc34c0aba match: remove special-casing of always-matching patterns in patternmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32589
diff changeset
179 else:
38581
9f9ffe5f687c match: compose 'set:' pattern as matcher
Yuya Nishihara <yuya@tcha.org>
parents: 38580
diff changeset
180 m = _buildkindpatsmatcher(patternmatcher, root, cwd, kindpats,
9f9ffe5f687c match: compose 'set:' pattern as matcher
Yuya Nishihara <yuya@tcha.org>
parents: 38580
diff changeset
181 ctx=ctx, listsubrepos=listsubrepos,
9f9ffe5f687c match: compose 'set:' pattern as matcher
Yuya Nishihara <yuya@tcha.org>
parents: 38580
diff changeset
182 badfn=badfn)
32586
20c9f3ecc192 match: handle everything-matching using new alwaysmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32585
diff changeset
183 else:
20c9f3ecc192 match: handle everything-matching using new alwaysmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32585
diff changeset
184 # It's a little strange that no patterns means to match everything.
32673
783394c0c978 match: simplify nevermatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32631
diff changeset
185 # Consider changing this to match nothing (probably using nevermatcher).
32586
20c9f3ecc192 match: handle everything-matching using new alwaysmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32585
diff changeset
186 m = alwaysmatcher(root, cwd, badfn)
20c9f3ecc192 match: handle everything-matching using new alwaysmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32585
diff changeset
187
32530
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
188 if include:
32589
5f08eca8f8d3 match: move normalize() call out of matcher constructors
Martin von Zweigbergk <martinvonz@google.com>
parents: 32588
diff changeset
189 kindpats = normalize(include, 'glob', root, cwd, auditor, warn)
38581
9f9ffe5f687c match: compose 'set:' pattern as matcher
Yuya Nishihara <yuya@tcha.org>
parents: 38580
diff changeset
190 im = _buildkindpatsmatcher(includematcher, root, cwd, kindpats, ctx=ctx,
9f9ffe5f687c match: compose 'set:' pattern as matcher
Yuya Nishihara <yuya@tcha.org>
parents: 38580
diff changeset
191 listsubrepos=listsubrepos, badfn=None)
32530
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
192 m = intersectmatchers(m, im)
32499
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32498
diff changeset
193 if exclude:
32589
5f08eca8f8d3 match: move normalize() call out of matcher constructors
Martin von Zweigbergk <martinvonz@google.com>
parents: 32588
diff changeset
194 kindpats = normalize(exclude, 'glob', root, cwd, auditor, warn)
38581
9f9ffe5f687c match: compose 'set:' pattern as matcher
Yuya Nishihara <yuya@tcha.org>
parents: 38580
diff changeset
195 em = _buildkindpatsmatcher(includematcher, root, cwd, kindpats, ctx=ctx,
9f9ffe5f687c match: compose 'set:' pattern as matcher
Yuya Nishihara <yuya@tcha.org>
parents: 38580
diff changeset
196 listsubrepos=listsubrepos, badfn=None)
32499
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32498
diff changeset
197 m = differencematcher(m, em)
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32498
diff changeset
198 return m
32433
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
199
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
200 def exact(root, cwd, files, badfn=None):
32532
a3583852861a match: handle exact matching using new exactmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32530
diff changeset
201 return exactmatcher(root, cwd, files, badfn=badfn)
32433
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
202
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
203 def always(root, cwd):
32586
20c9f3ecc192 match: handle everything-matching using new alwaysmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32585
diff changeset
204 return alwaysmatcher(root, cwd)
32433
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
205
32631
e6ff007e107e match: introduce nevermatcher for when no ignore files are present
Siddharth Agarwal <sid0@fb.com>
parents: 32590
diff changeset
206 def never(root, cwd):
e6ff007e107e match: introduce nevermatcher for when no ignore files are present
Siddharth Agarwal <sid0@fb.com>
parents: 32590
diff changeset
207 return nevermatcher(root, cwd)
e6ff007e107e match: introduce nevermatcher for when no ignore files are present
Siddharth Agarwal <sid0@fb.com>
parents: 32590
diff changeset
208
32433
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
209 def badmatch(match, badfn):
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
210 """Make a copy of the given matcher, replacing its bad method with the given
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
211 one.
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
212 """
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
213 m = copy.copy(match)
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
214 m.bad = badfn
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
215 return m
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
216
32435
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32434
diff changeset
217 def _donormalize(patterns, default, root, cwd, auditor, warn):
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32434
diff changeset
218 '''Convert 'kind:pat' from the patterns list to tuples with kind and
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32434
diff changeset
219 normalized and rooted patterns and with listfiles expanded.'''
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32434
diff changeset
220 kindpats = []
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32434
diff changeset
221 for kind, pat in [_patsplit(p, default) for p in patterns]:
33710
2be0bf186950 match: expose some data and functionality to other modules
Kostia Balytskyi <ikostia@fb.com>
parents: 33582
diff changeset
222 if kind in cwdrelativepatternkinds:
32435
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32434
diff changeset
223 pat = pathutil.canonpath(root, cwd, pat, auditor)
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32434
diff changeset
224 elif kind in ('relglob', 'path', 'rootfilesin'):
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32434
diff changeset
225 pat = util.normpath(pat)
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32434
diff changeset
226 elif kind in ('listfile', 'listfile0'):
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32434
diff changeset
227 try:
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32434
diff changeset
228 files = util.readfile(pat)
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32434
diff changeset
229 if kind == 'listfile0':
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32434
diff changeset
230 files = files.split('\0')
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32434
diff changeset
231 else:
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32434
diff changeset
232 files = files.splitlines()
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32434
diff changeset
233 files = [f for f in files if f]
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32434
diff changeset
234 except EnvironmentError:
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32434
diff changeset
235 raise error.Abort(_("unable to read file list (%s)") % pat)
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32434
diff changeset
236 for k, p, source in _donormalize(files, default, root, cwd,
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32434
diff changeset
237 auditor, warn):
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32434
diff changeset
238 kindpats.append((k, p, pat))
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32434
diff changeset
239 continue
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32434
diff changeset
240 elif kind == 'include':
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32434
diff changeset
241 try:
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32434
diff changeset
242 fullpath = os.path.join(root, util.localpath(pat))
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32434
diff changeset
243 includepats = readpatternfile(fullpath, warn)
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32434
diff changeset
244 for k, p, source in _donormalize(includepats, default,
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32434
diff changeset
245 root, cwd, auditor, warn):
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32434
diff changeset
246 kindpats.append((k, p, source or pat))
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32434
diff changeset
247 except error.Abort as inst:
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32434
diff changeset
248 raise error.Abort('%s: %s' % (pat, inst[0]))
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32434
diff changeset
249 except IOError as inst:
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32434
diff changeset
250 if warn:
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32434
diff changeset
251 warn(_("skipping unreadable pattern file '%s': %s\n") %
37087
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36601
diff changeset
252 (pat, stringutil.forcebytestr(inst.strerror)))
32435
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32434
diff changeset
253 continue
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32434
diff changeset
254 # else: re or relre - which cannot be normalized
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32434
diff changeset
255 kindpats.append((kind, pat, ''))
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32434
diff changeset
256 return kindpats
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32434
diff changeset
257
32492
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
258 class basematcher(object):
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
259
32529
ca77a243ffa7 match: move entire uipath() implementation to basematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32500
diff changeset
260 def __init__(self, root, cwd, badfn=None, relativeuipath=True):
32492
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
261 self._root = root
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
262 self._cwd = cwd
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
263 if badfn is not None:
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
264 self.bad = badfn
32529
ca77a243ffa7 match: move entire uipath() implementation to basematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32500
diff changeset
265 self._relativeuipath = relativeuipath
32492
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
266
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
267 def __call__(self, fn):
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
268 return self.matchfn(fn)
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
269 def __iter__(self):
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
270 for f in self._files:
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
271 yield f
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
272 # Callbacks related to how the matcher is used by dirstate.walk.
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
273 # Subscribers to these events must monkeypatch the matcher object.
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
274 def bad(self, f, msg):
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
275 '''Callback from dirstate.walk for each explicit file that can't be
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
276 found/accessed, with an error message.'''
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
277
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
278 # If an explicitdir is set, it will be called when an explicitly listed
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
279 # directory is visited.
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
280 explicitdir = None
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
281
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
282 # If an traversedir is set, it will be called when a directory discovered
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
283 # by recursive traversal is visited.
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
284 traversedir = None
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
285
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
286 def abs(self, f):
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
287 '''Convert a repo path back to path that is relative to the root of the
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
288 matcher.'''
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
289 return f
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
290
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
291 def rel(self, f):
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
292 '''Convert repo path back to path that is relative to cwd of matcher.'''
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
293 return util.pathto(self._root, self._cwd, f)
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
294
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
295 def uipath(self, f):
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
296 '''Convert repo path to a display path. If patterns or -I/-X were used
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
297 to create this matcher, the display path will be relative to cwd.
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
298 Otherwise it is relative to the root of the repo.'''
32529
ca77a243ffa7 match: move entire uipath() implementation to basematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32500
diff changeset
299 return (self._relativeuipath and self.rel(f)) or self.abs(f)
32492
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
300
32493
9f781f43f2ce match: make basematcher._files a @propertycache
Martin von Zweigbergk <martinvonz@google.com>
parents: 32492
diff changeset
301 @propertycache
9f781f43f2ce match: make basematcher._files a @propertycache
Martin von Zweigbergk <martinvonz@google.com>
parents: 32492
diff changeset
302 def _files(self):
9f781f43f2ce match: make basematcher._files a @propertycache
Martin von Zweigbergk <martinvonz@google.com>
parents: 32492
diff changeset
303 return []
9f781f43f2ce match: make basematcher._files a @propertycache
Martin von Zweigbergk <martinvonz@google.com>
parents: 32492
diff changeset
304
32492
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
305 def files(self):
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
306 '''Explicitly listed files or patterns or roots:
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
307 if no patterns or .always(): empty list,
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
308 if exact: list exact files,
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
309 if not .anypats(): list all files and dirs,
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
310 else: optimal roots'''
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
311 return self._files
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
312
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
313 @propertycache
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
314 def _fileset(self):
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
315 return set(self._files)
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
316
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
317 def exact(self, f):
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
318 '''Returns True if f is in .files().'''
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
319 return f in self._fileset
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
320
32497
43e091847c4d match: make matchfn a method on the class
Martin von Zweigbergk <martinvonz@google.com>
parents: 32495
diff changeset
321 def matchfn(self, f):
43e091847c4d match: make matchfn a method on the class
Martin von Zweigbergk <martinvonz@google.com>
parents: 32495
diff changeset
322 return False
43e091847c4d match: make matchfn a method on the class
Martin von Zweigbergk <martinvonz@google.com>
parents: 32495
diff changeset
323
32492
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
324 def visitdir(self, dir):
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
325 '''Decides whether a directory should be visited based on whether it
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
326 has potential matches in it or one of its subdirectories. This is
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
327 based on the match's primary, included, and excluded patterns.
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
328
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
329 Returns the string 'all' if the given directory and all subdirectories
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
330 should be visited. Otherwise returns True or False indicating whether
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
331 the given directory should be visited.
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
332 '''
33478
cf15c3cc304c match: make base matcher return True for visitdir
Durham Goode <durham@fb.com>
parents: 33448
diff changeset
333 return True
32492
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
334
38993
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
335 def visitchildrenset(self, dir):
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
336 '''Decides whether a directory should be visited based on whether it
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
337 has potential matches in it or one of its subdirectories, and
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
338 potentially lists which subdirectories of that directory should be
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
339 visited. This is based on the match's primary, included, and excluded
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
340 patterns.
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
341
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
342 This function is very similar to 'visitdir', and the following mapping
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
343 can be applied:
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
344
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
345 visitdir | visitchildrenlist
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
346 ----------+-------------------
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
347 False | set()
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
348 'all' | 'all'
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
349 True | 'this' OR non-empty set of subdirs to visit
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
350
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
351 Example:
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
352 Assume matchers ['path:foo/bar', 'rootfilesin:qux'], we would return
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
353 the following values (assuming the implementation of visitchildrenset
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
354 is capable of recognizing this; some implementations are not).
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
355
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
356 '.' -> {'foo', 'qux'}
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
357 'baz' -> set()
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
358 'foo' -> {'bar'}
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
359 # Ideally this would be 'all', but since the prefix nature of matchers
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
360 # is applied to the entire matcher, we have to downgrade to this
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
361 # 'this' due to the non-prefix 'rootfilesin'-kind matcher.
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
362 'foo/bar' -> 'this'
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
363 'qux' -> 'this'
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
364 '''
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
365 return 'this'
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
366
32492
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
367 def always(self):
33379
7ddb2aa2b7af match: express anypats(), not prefix(), in terms of the others
Martin von Zweigbergk <martinvonz@google.com>
parents: 33378
diff changeset
368 '''Matcher will match everything and .files() will be empty --
7ddb2aa2b7af match: express anypats(), not prefix(), in terms of the others
Martin von Zweigbergk <martinvonz@google.com>
parents: 33378
diff changeset
369 optimization might be possible.'''
32492
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
370 return False
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
371
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
372 def isexact(self):
33379
7ddb2aa2b7af match: express anypats(), not prefix(), in terms of the others
Martin von Zweigbergk <martinvonz@google.com>
parents: 33378
diff changeset
373 '''Matcher will match exactly the list of files in .files() --
7ddb2aa2b7af match: express anypats(), not prefix(), in terms of the others
Martin von Zweigbergk <martinvonz@google.com>
parents: 33378
diff changeset
374 optimization might be possible.'''
32492
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
375 return False
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
376
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
377 def prefix(self):
33379
7ddb2aa2b7af match: express anypats(), not prefix(), in terms of the others
Martin von Zweigbergk <martinvonz@google.com>
parents: 33378
diff changeset
378 '''Matcher will match the paths in .files() recursively --
7ddb2aa2b7af match: express anypats(), not prefix(), in terms of the others
Martin von Zweigbergk <martinvonz@google.com>
parents: 33378
diff changeset
379 optimization might be possible.'''
7ddb2aa2b7af match: express anypats(), not prefix(), in terms of the others
Martin von Zweigbergk <martinvonz@google.com>
parents: 33378
diff changeset
380 return False
7ddb2aa2b7af match: express anypats(), not prefix(), in terms of the others
Martin von Zweigbergk <martinvonz@google.com>
parents: 33378
diff changeset
381
7ddb2aa2b7af match: express anypats(), not prefix(), in terms of the others
Martin von Zweigbergk <martinvonz@google.com>
parents: 33378
diff changeset
382 def anypats(self):
7ddb2aa2b7af match: express anypats(), not prefix(), in terms of the others
Martin von Zweigbergk <martinvonz@google.com>
parents: 33378
diff changeset
383 '''None of .always(), .isexact(), and .prefix() is true --
7ddb2aa2b7af match: express anypats(), not prefix(), in terms of the others
Martin von Zweigbergk <martinvonz@google.com>
parents: 33378
diff changeset
384 optimizations will be difficult.'''
7ddb2aa2b7af match: express anypats(), not prefix(), in terms of the others
Martin von Zweigbergk <martinvonz@google.com>
parents: 33378
diff changeset
385 return not self.always() and not self.isexact() and not self.prefix()
32492
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
386
32586
20c9f3ecc192 match: handle everything-matching using new alwaysmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32585
diff changeset
387 class alwaysmatcher(basematcher):
20c9f3ecc192 match: handle everything-matching using new alwaysmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32585
diff changeset
388 '''Matches everything.'''
20c9f3ecc192 match: handle everything-matching using new alwaysmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32585
diff changeset
389
32590
3fdcc34c0aba match: remove special-casing of always-matching patterns in patternmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32589
diff changeset
390 def __init__(self, root, cwd, badfn=None, relativeuipath=False):
32586
20c9f3ecc192 match: handle everything-matching using new alwaysmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32585
diff changeset
391 super(alwaysmatcher, self).__init__(root, cwd, badfn,
32590
3fdcc34c0aba match: remove special-casing of always-matching patterns in patternmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32589
diff changeset
392 relativeuipath=relativeuipath)
32586
20c9f3ecc192 match: handle everything-matching using new alwaysmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32585
diff changeset
393
20c9f3ecc192 match: handle everything-matching using new alwaysmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32585
diff changeset
394 def always(self):
20c9f3ecc192 match: handle everything-matching using new alwaysmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32585
diff changeset
395 return True
20c9f3ecc192 match: handle everything-matching using new alwaysmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32585
diff changeset
396
20c9f3ecc192 match: handle everything-matching using new alwaysmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32585
diff changeset
397 def matchfn(self, f):
20c9f3ecc192 match: handle everything-matching using new alwaysmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32585
diff changeset
398 return True
20c9f3ecc192 match: handle everything-matching using new alwaysmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32585
diff changeset
399
20c9f3ecc192 match: handle everything-matching using new alwaysmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32585
diff changeset
400 def visitdir(self, dir):
20c9f3ecc192 match: handle everything-matching using new alwaysmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32585
diff changeset
401 return 'all'
20c9f3ecc192 match: handle everything-matching using new alwaysmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32585
diff changeset
402
38993
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
403 def visitchildrenset(self, dir):
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
404 return 'all'
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
405
32586
20c9f3ecc192 match: handle everything-matching using new alwaysmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32585
diff changeset
406 def __repr__(self):
36088
c4fa47f880d3 py3: make sure we return str from __repr__
Pulkit Goyal <7895pulkit@gmail.com>
parents: 35659
diff changeset
407 return r'<alwaysmatcher>'
32586
20c9f3ecc192 match: handle everything-matching using new alwaysmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32585
diff changeset
408
32631
e6ff007e107e match: introduce nevermatcher for when no ignore files are present
Siddharth Agarwal <sid0@fb.com>
parents: 32590
diff changeset
409 class nevermatcher(basematcher):
e6ff007e107e match: introduce nevermatcher for when no ignore files are present
Siddharth Agarwal <sid0@fb.com>
parents: 32590
diff changeset
410 '''Matches nothing.'''
e6ff007e107e match: introduce nevermatcher for when no ignore files are present
Siddharth Agarwal <sid0@fb.com>
parents: 32590
diff changeset
411
32673
783394c0c978 match: simplify nevermatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32631
diff changeset
412 def __init__(self, root, cwd, badfn=None):
783394c0c978 match: simplify nevermatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32631
diff changeset
413 super(nevermatcher, self).__init__(root, cwd, badfn)
32631
e6ff007e107e match: introduce nevermatcher for when no ignore files are present
Siddharth Agarwal <sid0@fb.com>
parents: 32590
diff changeset
414
33378
adf95bfb423a match: make nevermatcher an exact matcher and a prefix matcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 33358
diff changeset
415 # It's a little weird to say that the nevermatcher is an exact matcher
adf95bfb423a match: make nevermatcher an exact matcher and a prefix matcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 33358
diff changeset
416 # or a prefix matcher, but it seems to make sense to let callers take
adf95bfb423a match: make nevermatcher an exact matcher and a prefix matcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 33358
diff changeset
417 # fast paths based on either. There will be no exact matches, nor any
adf95bfb423a match: make nevermatcher an exact matcher and a prefix matcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 33358
diff changeset
418 # prefixes (files() returns []), so fast paths iterating over them should
adf95bfb423a match: make nevermatcher an exact matcher and a prefix matcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 33358
diff changeset
419 # be efficient (and correct).
adf95bfb423a match: make nevermatcher an exact matcher and a prefix matcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 33358
diff changeset
420 def isexact(self):
adf95bfb423a match: make nevermatcher an exact matcher and a prefix matcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 33358
diff changeset
421 return True
adf95bfb423a match: make nevermatcher an exact matcher and a prefix matcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 33358
diff changeset
422
adf95bfb423a match: make nevermatcher an exact matcher and a prefix matcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 33358
diff changeset
423 def prefix(self):
adf95bfb423a match: make nevermatcher an exact matcher and a prefix matcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 33358
diff changeset
424 return True
adf95bfb423a match: make nevermatcher an exact matcher and a prefix matcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 33358
diff changeset
425
33582
44bc181b9835 match: override visitdir() in nevermatcher to return False
Martin von Zweigbergk <martinvonz@google.com>
parents: 33497
diff changeset
426 def visitdir(self, dir):
44bc181b9835 match: override visitdir() in nevermatcher to return False
Martin von Zweigbergk <martinvonz@google.com>
parents: 33497
diff changeset
427 return False
44bc181b9835 match: override visitdir() in nevermatcher to return False
Martin von Zweigbergk <martinvonz@google.com>
parents: 33497
diff changeset
428
38993
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
429 def visitchildrenset(self, dir):
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
430 return set()
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
431
32631
e6ff007e107e match: introduce nevermatcher for when no ignore files are present
Siddharth Agarwal <sid0@fb.com>
parents: 32590
diff changeset
432 def __repr__(self):
36088
c4fa47f880d3 py3: make sure we return str from __repr__
Pulkit Goyal <7895pulkit@gmail.com>
parents: 35659
diff changeset
433 return r'<nevermatcher>'
32631
e6ff007e107e match: introduce nevermatcher for when no ignore files are present
Siddharth Agarwal <sid0@fb.com>
parents: 32590
diff changeset
434
38578
76838305b9dd match: add basic wrapper for boolean function
Yuya Nishihara <yuya@tcha.org>
parents: 38479
diff changeset
435 class predicatematcher(basematcher):
76838305b9dd match: add basic wrapper for boolean function
Yuya Nishihara <yuya@tcha.org>
parents: 38479
diff changeset
436 """A matcher adapter for a simple boolean function"""
76838305b9dd match: add basic wrapper for boolean function
Yuya Nishihara <yuya@tcha.org>
parents: 38479
diff changeset
437
76838305b9dd match: add basic wrapper for boolean function
Yuya Nishihara <yuya@tcha.org>
parents: 38479
diff changeset
438 def __init__(self, root, cwd, predfn, predrepr=None, badfn=None):
76838305b9dd match: add basic wrapper for boolean function
Yuya Nishihara <yuya@tcha.org>
parents: 38479
diff changeset
439 super(predicatematcher, self).__init__(root, cwd, badfn)
76838305b9dd match: add basic wrapper for boolean function
Yuya Nishihara <yuya@tcha.org>
parents: 38479
diff changeset
440 self.matchfn = predfn
76838305b9dd match: add basic wrapper for boolean function
Yuya Nishihara <yuya@tcha.org>
parents: 38479
diff changeset
441 self._predrepr = predrepr
76838305b9dd match: add basic wrapper for boolean function
Yuya Nishihara <yuya@tcha.org>
parents: 38479
diff changeset
442
76838305b9dd match: add basic wrapper for boolean function
Yuya Nishihara <yuya@tcha.org>
parents: 38479
diff changeset
443 @encoding.strmethod
76838305b9dd match: add basic wrapper for boolean function
Yuya Nishihara <yuya@tcha.org>
parents: 38479
diff changeset
444 def __repr__(self):
76838305b9dd match: add basic wrapper for boolean function
Yuya Nishihara <yuya@tcha.org>
parents: 38479
diff changeset
445 s = (stringutil.buildrepr(self._predrepr)
76838305b9dd match: add basic wrapper for boolean function
Yuya Nishihara <yuya@tcha.org>
parents: 38479
diff changeset
446 or pycompat.byterepr(self.matchfn))
76838305b9dd match: add basic wrapper for boolean function
Yuya Nishihara <yuya@tcha.org>
parents: 38479
diff changeset
447 return '<predicatenmatcher pred=%s>' % s
76838305b9dd match: add basic wrapper for boolean function
Yuya Nishihara <yuya@tcha.org>
parents: 38479
diff changeset
448
32534
7095dbc266e3 match: split up main matcher into patternmatcher and includematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32533
diff changeset
449 class patternmatcher(basematcher):
32433
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
450
38582
6467286b829c match: remove ctx argument from code path down to _buildmatch()
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
451 def __init__(self, root, cwd, kindpats, listsubrepos=False, badfn=None):
32588
b3083be7dcb9 match: drop support for empty pattern list in patternmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32587
diff changeset
452 super(patternmatcher, self).__init__(root, cwd, badfn)
8581
101d305c1d0b match: fold _matcher into match.__init__
Matt Mackall <mpm@selenic.com>
parents: 8580
diff changeset
453
32590
3fdcc34c0aba match: remove special-casing of always-matching patterns in patternmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32589
diff changeset
454 self._files = _explicitfiles(kindpats)
33405
6aa643762641 match: inverse _anypats(), making it _prefix()
Martin von Zweigbergk <martinvonz@google.com>
parents: 33380
diff changeset
455 self._prefix = _prefix(kindpats)
38582
6467286b829c match: remove ctx argument from code path down to _buildmatch()
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
456 self._pats, self.matchfn = _buildmatch(kindpats, '$', listsubrepos,
33306
a9808bd1449e match: minor cleanups to patternmatcher and includematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32748
diff changeset
457 root)
8587
8f15d54437b9 match: fold match into _match base class
Matt Mackall <mpm@selenic.com>
parents: 8586
diff changeset
458
32362
23c9a2a71c6e match: make _fileroots a @propertycache and rename it to _fileset
Martin von Zweigbergk <martinvonz@google.com>
parents: 32352
diff changeset
459 @propertycache
24636
36872036169b treemanifest: further optimize treemanifest.matches()
Drew Gottlieb <drgott@google.com>
parents: 24452
diff changeset
460 def _dirs(self):
32362
23c9a2a71c6e match: make _fileroots a @propertycache and rename it to _fileset
Martin von Zweigbergk <martinvonz@google.com>
parents: 32352
diff changeset
461 return set(util.dirs(self._fileset)) | {'.'}
24636
36872036169b treemanifest: further optimize treemanifest.matches()
Drew Gottlieb <drgott@google.com>
parents: 24452
diff changeset
462
36872036169b treemanifest: further optimize treemanifest.matches()
Drew Gottlieb <drgott@google.com>
parents: 24452
diff changeset
463 def visitdir(self, dir):
33405
6aa643762641 match: inverse _anypats(), making it _prefix()
Martin von Zweigbergk <martinvonz@google.com>
parents: 33380
diff changeset
464 if self._prefix and dir in self._fileset:
27343
c59647c6694d treemanifest: don't iterate entire matching submanifests on match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 27327
diff changeset
465 return 'all'
32587
f44ea253ffe2 match: optimize visitdir() for when no explicit files are listed
Martin von Zweigbergk <martinvonz@google.com>
parents: 32586
diff changeset
466 return ('.' in self._fileset or
32362
23c9a2a71c6e match: make _fileroots a @propertycache and rename it to _fileset
Martin von Zweigbergk <martinvonz@google.com>
parents: 32352
diff changeset
467 dir in self._fileset or
25576
d02f4b3e71f5 match: break boolean expressions into one operand per line
Martin von Zweigbergk <martinvonz@google.com>
parents: 25575
diff changeset
468 dir in self._dirs or
32362
23c9a2a71c6e match: make _fileroots a @propertycache and rename it to _fileset
Martin von Zweigbergk <martinvonz@google.com>
parents: 32352
diff changeset
469 any(parentdir in self._fileset
25577
a410479c7ee7 match: drop optimization (?) of 'parentdirs' calculation
Martin von Zweigbergk <martinvonz@google.com>
parents: 25576
diff changeset
470 for parentdir in util.finddirs(dir)))
24636
36872036169b treemanifest: further optimize treemanifest.matches()
Drew Gottlieb <drgott@google.com>
parents: 24452
diff changeset
471
38993
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
472 def visitchildrenset(self, dir):
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
473 ret = self.visitdir(dir)
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
474 if ret is True:
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
475 return 'this'
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
476 elif not ret:
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
477 return set()
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
478 assert ret == 'all'
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
479 return 'all'
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
480
33379
7ddb2aa2b7af match: express anypats(), not prefix(), in terms of the others
Martin von Zweigbergk <martinvonz@google.com>
parents: 33378
diff changeset
481 def prefix(self):
33405
6aa643762641 match: inverse _anypats(), making it _prefix()
Martin von Zweigbergk <martinvonz@google.com>
parents: 33380
diff changeset
482 return self._prefix
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
483
36088
c4fa47f880d3 py3: make sure we return str from __repr__
Pulkit Goyal <7895pulkit@gmail.com>
parents: 35659
diff changeset
484 @encoding.strmethod
32444
952017471f93 match: implement __repr__() and update users (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32439
diff changeset
485 def __repr__(self):
38061
2f406142d7b4 py3: use pycompat.bytestr() on bytes before %r-ing it
Pulkit Goyal <7895pulkit@gmail.com>
parents: 37087
diff changeset
486 return ('<patternmatcher patterns=%r>' % pycompat.bytestr(self._pats))
32534
7095dbc266e3 match: split up main matcher into patternmatcher and includematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32533
diff changeset
487
7095dbc266e3 match: split up main matcher into patternmatcher and includematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32533
diff changeset
488 class includematcher(basematcher):
7095dbc266e3 match: split up main matcher into patternmatcher and includematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32533
diff changeset
489
38582
6467286b829c match: remove ctx argument from code path down to _buildmatch()
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
490 def __init__(self, root, cwd, kindpats, listsubrepos=False, badfn=None):
32535
3026f19b4b01 match: remove support for non-include patterns from includematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32534
diff changeset
491 super(includematcher, self).__init__(root, cwd, badfn)
32534
7095dbc266e3 match: split up main matcher into patternmatcher and includematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32533
diff changeset
492
38582
6467286b829c match: remove ctx argument from code path down to _buildmatch()
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
493 self._pats, self.matchfn = _buildmatch(kindpats, '(?:/|$)',
33306
a9808bd1449e match: minor cleanups to patternmatcher and includematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32748
diff changeset
494 listsubrepos, root)
33405
6aa643762641 match: inverse _anypats(), making it _prefix()
Martin von Zweigbergk <martinvonz@google.com>
parents: 33380
diff changeset
495 self._prefix = _prefix(kindpats)
38992
5a7df82de142 includematcher: separate "parents" from "dirs"
spectral <spectral@google.com>
parents: 38750
diff changeset
496 roots, dirs, parents = _rootsdirsandparents(kindpats)
32535
3026f19b4b01 match: remove support for non-include patterns from includematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32534
diff changeset
497 # roots are directories which are recursively included.
32536
361808a2b0b8 match: simplify includematcher a bit
Martin von Zweigbergk <martinvonz@google.com>
parents: 32535
diff changeset
498 self._roots = set(roots)
32535
3026f19b4b01 match: remove support for non-include patterns from includematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32534
diff changeset
499 # dirs are directories which are non-recursively included.
32536
361808a2b0b8 match: simplify includematcher a bit
Martin von Zweigbergk <martinvonz@google.com>
parents: 32535
diff changeset
500 self._dirs = set(dirs)
38992
5a7df82de142 includematcher: separate "parents" from "dirs"
spectral <spectral@google.com>
parents: 38750
diff changeset
501 # parents are directories which are non-recursively included because
5a7df82de142 includematcher: separate "parents" from "dirs"
spectral <spectral@google.com>
parents: 38750
diff changeset
502 # they are needed to get to items in _dirs or _roots.
5a7df82de142 includematcher: separate "parents" from "dirs"
spectral <spectral@google.com>
parents: 38750
diff changeset
503 self._parents = set(parents)
32534
7095dbc266e3 match: split up main matcher into patternmatcher and includematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32533
diff changeset
504
7095dbc266e3 match: split up main matcher into patternmatcher and includematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32533
diff changeset
505 def visitdir(self, dir):
33405
6aa643762641 match: inverse _anypats(), making it _prefix()
Martin von Zweigbergk <martinvonz@google.com>
parents: 33380
diff changeset
506 if self._prefix and dir in self._roots:
32534
7095dbc266e3 match: split up main matcher into patternmatcher and includematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32533
diff changeset
507 return 'all'
32536
361808a2b0b8 match: simplify includematcher a bit
Martin von Zweigbergk <martinvonz@google.com>
parents: 32535
diff changeset
508 return ('.' in self._roots or
361808a2b0b8 match: simplify includematcher a bit
Martin von Zweigbergk <martinvonz@google.com>
parents: 32535
diff changeset
509 dir in self._roots or
361808a2b0b8 match: simplify includematcher a bit
Martin von Zweigbergk <martinvonz@google.com>
parents: 32535
diff changeset
510 dir in self._dirs or
38992
5a7df82de142 includematcher: separate "parents" from "dirs"
spectral <spectral@google.com>
parents: 38750
diff changeset
511 dir in self._parents or
32536
361808a2b0b8 match: simplify includematcher a bit
Martin von Zweigbergk <martinvonz@google.com>
parents: 32535
diff changeset
512 any(parentdir in self._roots
361808a2b0b8 match: simplify includematcher a bit
Martin von Zweigbergk <martinvonz@google.com>
parents: 32535
diff changeset
513 for parentdir in util.finddirs(dir)))
32534
7095dbc266e3 match: split up main matcher into patternmatcher and includematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32533
diff changeset
514
38993
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
515 def visitchildrenset(self, dir):
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
516 if self._prefix and dir in self._roots:
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
517 return 'all'
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
518 # Note: this does *not* include the 'dir in self._parents' case from
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
519 # visitdir, that's handled below.
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
520 if ('.' in self._roots or
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
521 dir in self._roots or
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
522 dir in self._dirs or
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
523 any(parentdir in self._roots
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
524 for parentdir in util.finddirs(dir))):
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
525 return 'this'
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
526
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
527 ret = set()
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
528 if dir in self._parents:
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
529 # We add a '/' on to `dir` so that we don't return items that are
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
530 # prefixed by `dir` but are actually siblings of `dir`.
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
531 suffixeddir = dir + '/' if dir != '.' else ''
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
532 # Look in all _roots, _dirs, and _parents for things that start with
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
533 # 'suffixeddir'.
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
534 for d in [q for q in
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
535 itertools.chain(self._roots, self._dirs, self._parents) if
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
536 q.startswith(suffixeddir)]:
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
537 # Don't emit '.' in the response for the root directory
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
538 if not suffixeddir and d == '.':
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
539 continue
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
540
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
541 # We return the item name without the `suffixeddir` prefix or a
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
542 # slash suffix
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
543 d = d[len(suffixeddir):]
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
544 if '/' in d:
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
545 # This is a subdirectory-of-a-subdirectory, i.e.
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
546 # suffixeddir='foo/', d was 'foo/bar/baz' before removing
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
547 # 'foo/'.
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
548 d = d[:d.index('/')]
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
549 ret.add(d)
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
550 return ret
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
551
36088
c4fa47f880d3 py3: make sure we return str from __repr__
Pulkit Goyal <7895pulkit@gmail.com>
parents: 35659
diff changeset
552 @encoding.strmethod
32534
7095dbc266e3 match: split up main matcher into patternmatcher and includematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32533
diff changeset
553 def __repr__(self):
36601
9adfa48792a7 match: some minimal pycompat fixes guided by test-hgignore.t
Augie Fackler <augie@google.com>
parents: 36088
diff changeset
554 return ('<includematcher includes=%r>' % pycompat.bytestr(self._pats))
32444
952017471f93 match: implement __repr__() and update users (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32439
diff changeset
555
32532
a3583852861a match: handle exact matching using new exactmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32530
diff changeset
556 class exactmatcher(basematcher):
a3583852861a match: handle exact matching using new exactmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32530
diff changeset
557 '''Matches the input files exactly. They are interpreted as paths, not
a3583852861a match: handle exact matching using new exactmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32530
diff changeset
558 patterns (so no kind-prefixes).
a3583852861a match: handle exact matching using new exactmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32530
diff changeset
559 '''
a3583852861a match: handle exact matching using new exactmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32530
diff changeset
560
a3583852861a match: handle exact matching using new exactmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32530
diff changeset
561 def __init__(self, root, cwd, files, badfn=None):
a3583852861a match: handle exact matching using new exactmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32530
diff changeset
562 super(exactmatcher, self).__init__(root, cwd, badfn)
a3583852861a match: handle exact matching using new exactmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32530
diff changeset
563
a3583852861a match: handle exact matching using new exactmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32530
diff changeset
564 if isinstance(files, list):
a3583852861a match: handle exact matching using new exactmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32530
diff changeset
565 self._files = files
a3583852861a match: handle exact matching using new exactmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32530
diff changeset
566 else:
a3583852861a match: handle exact matching using new exactmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32530
diff changeset
567 self._files = list(files)
32576
cf7c88986e9f match: define exactmatcher.matchfn statically
Yuya Nishihara <yuya@tcha.org>
parents: 32575
diff changeset
568
cf7c88986e9f match: define exactmatcher.matchfn statically
Yuya Nishihara <yuya@tcha.org>
parents: 32575
diff changeset
569 matchfn = basematcher.exact
32532
a3583852861a match: handle exact matching using new exactmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32530
diff changeset
570
a3583852861a match: handle exact matching using new exactmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32530
diff changeset
571 @propertycache
a3583852861a match: handle exact matching using new exactmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32530
diff changeset
572 def _dirs(self):
a3583852861a match: handle exact matching using new exactmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32530
diff changeset
573 return set(util.dirs(self._fileset)) | {'.'}
a3583852861a match: handle exact matching using new exactmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32530
diff changeset
574
a3583852861a match: handle exact matching using new exactmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32530
diff changeset
575 def visitdir(self, dir):
a3583852861a match: handle exact matching using new exactmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32530
diff changeset
576 return dir in self._dirs
a3583852861a match: handle exact matching using new exactmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32530
diff changeset
577
38993
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
578 def visitchildrenset(self, dir):
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
579 if dir in self._dirs:
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
580 candidates = self._dirs - {'.'}
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
581 if dir != '.':
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
582 d = dir + '/'
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
583 candidates = set(c[len(d):] for c in candidates if
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
584 c.startswith(d))
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
585 # self._dirs includes all of the directories, recursively, so if
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
586 # we're attempting to match foo/bar/baz.txt, it'll have '.', 'foo',
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
587 # 'foo/bar' in it. Thus we can safely ignore a candidate that has a
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
588 # '/' in it, indicating a it's for a subdir-of-a-subdir; the
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
589 # immediate subdir will be in there without a slash.
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
590 ret = set(c for c in candidates if '/' not in c)
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
591 # We need to emit 'this' for foo/bar, not set(), not {'baz.txt'}.
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
592 if not ret:
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
593 return 'this'
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
594 return ret
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
595 return set()
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
596
32532
a3583852861a match: handle exact matching using new exactmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32530
diff changeset
597 def isexact(self):
a3583852861a match: handle exact matching using new exactmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32530
diff changeset
598 return True
a3583852861a match: handle exact matching using new exactmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32530
diff changeset
599
36088
c4fa47f880d3 py3: make sure we return str from __repr__
Pulkit Goyal <7895pulkit@gmail.com>
parents: 35659
diff changeset
600 @encoding.strmethod
32532
a3583852861a match: handle exact matching using new exactmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32530
diff changeset
601 def __repr__(self):
a3583852861a match: handle exact matching using new exactmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32530
diff changeset
602 return ('<exactmatcher files=%r>' % self._files)
a3583852861a match: handle exact matching using new exactmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32530
diff changeset
603
32499
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32498
diff changeset
604 class differencematcher(basematcher):
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32498
diff changeset
605 '''Composes two matchers by matching if the first matches and the second
35659
821d8a5ab4ff match: do not weirdly include explicit files excluded by -X option
Yuya Nishihara <yuya@tcha.org>
parents: 35185
diff changeset
606 does not.
32499
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32498
diff changeset
607
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32498
diff changeset
608 The second matcher's non-matching-attributes (root, cwd, bad, explicitdir,
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32498
diff changeset
609 traversedir) are ignored.
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32498
diff changeset
610 '''
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32498
diff changeset
611 def __init__(self, m1, m2):
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32498
diff changeset
612 super(differencematcher, self).__init__(m1._root, m1._cwd)
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32498
diff changeset
613 self._m1 = m1
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32498
diff changeset
614 self._m2 = m2
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32498
diff changeset
615 self.bad = m1.bad
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32498
diff changeset
616 self.explicitdir = m1.explicitdir
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32498
diff changeset
617 self.traversedir = m1.traversedir
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32498
diff changeset
618
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32498
diff changeset
619 def matchfn(self, f):
35659
821d8a5ab4ff match: do not weirdly include explicit files excluded by -X option
Yuya Nishihara <yuya@tcha.org>
parents: 35185
diff changeset
620 return self._m1(f) and not self._m2(f)
32499
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32498
diff changeset
621
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32498
diff changeset
622 @propertycache
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32498
diff changeset
623 def _files(self):
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32498
diff changeset
624 if self.isexact():
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32498
diff changeset
625 return [f for f in self._m1.files() if self(f)]
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32498
diff changeset
626 # If m1 is not an exact matcher, we can't easily figure out the set of
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32498
diff changeset
627 # files, because its files() are not always files. For example, if
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32498
diff changeset
628 # m1 is "path:dir" and m2 is "rootfileins:.", we don't
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32498
diff changeset
629 # want to remove "dir" from the set even though it would match m2,
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32498
diff changeset
630 # because the "dir" in m1 may not be a file.
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32498
diff changeset
631 return self._m1.files()
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32498
diff changeset
632
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32498
diff changeset
633 def visitdir(self, dir):
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32498
diff changeset
634 if self._m2.visitdir(dir) == 'all':
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32498
diff changeset
635 return False
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32498
diff changeset
636 return bool(self._m1.visitdir(dir))
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32498
diff changeset
637
38993
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
638 def visitchildrenset(self, dir):
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
639 m2_set = self._m2.visitchildrenset(dir)
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
640 if m2_set == 'all':
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
641 return set()
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
642 m1_set = self._m1.visitchildrenset(dir)
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
643 # Possible values for m1: 'all', 'this', set(...), set()
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
644 # Possible values for m2: 'this', set(...), set()
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
645 # If m2 has nothing under here that we care about, return m1, even if
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
646 # it's 'all'. This is a change in behavior from visitdir, which would
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
647 # return True, not 'all', for some reason.
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
648 if not m2_set:
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
649 return m1_set
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
650 if m1_set in ['all', 'this']:
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
651 # Never return 'all' here if m2_set is any kind of non-empty (either
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
652 # 'this' or set(foo)), since m2 might return set() for a
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
653 # subdirectory.
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
654 return 'this'
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
655 # Possible values for m1: set(...), set()
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
656 # Possible values for m2: 'this', set(...)
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
657 # We ignore m2's set results. They're possibly incorrect:
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
658 # m1 = path:dir/subdir, m2=rootfilesin:dir, visitchildrenset('.'):
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
659 # m1 returns {'dir'}, m2 returns {'dir'}, if we subtracted we'd
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
660 # return set(), which is *not* correct, we still need to visit 'dir'!
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
661 return m1_set
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
662
32499
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32498
diff changeset
663 def isexact(self):
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32498
diff changeset
664 return self._m1.isexact()
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32498
diff changeset
665
36088
c4fa47f880d3 py3: make sure we return str from __repr__
Pulkit Goyal <7895pulkit@gmail.com>
parents: 35659
diff changeset
666 @encoding.strmethod
32499
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32498
diff changeset
667 def __repr__(self):
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32498
diff changeset
668 return ('<differencematcher m1=%r, m2=%r>' % (self._m1, self._m2))
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32498
diff changeset
669
32530
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
670 def intersectmatchers(m1, m2):
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
671 '''Composes two matchers by matching if both of them match.
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
672
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
673 The second matcher's non-matching-attributes (root, cwd, bad, explicitdir,
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
674 traversedir) are ignored.
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
675 '''
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
676 if m1 is None or m2 is None:
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
677 return m1 or m2
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
678 if m1.always():
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
679 m = copy.copy(m2)
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
680 # TODO: Consider encapsulating these things in a class so there's only
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
681 # one thing to copy from m1.
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
682 m.bad = m1.bad
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
683 m.explicitdir = m1.explicitdir
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
684 m.traversedir = m1.traversedir
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
685 m.abs = m1.abs
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
686 m.rel = m1.rel
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
687 m._relativeuipath |= m1._relativeuipath
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
688 return m
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
689 if m2.always():
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
690 m = copy.copy(m1)
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
691 m._relativeuipath |= m2._relativeuipath
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
692 return m
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
693 return intersectionmatcher(m1, m2)
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
694
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
695 class intersectionmatcher(basematcher):
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
696 def __init__(self, m1, m2):
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
697 super(intersectionmatcher, self).__init__(m1._root, m1._cwd)
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
698 self._m1 = m1
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
699 self._m2 = m2
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
700 self.bad = m1.bad
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
701 self.explicitdir = m1.explicitdir
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
702 self.traversedir = m1.traversedir
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
703
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
704 @propertycache
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
705 def _files(self):
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
706 if self.isexact():
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
707 m1, m2 = self._m1, self._m2
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
708 if not m1.isexact():
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
709 m1, m2 = m2, m1
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
710 return [f for f in m1.files() if m2(f)]
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
711 # It neither m1 nor m2 is an exact matcher, we can't easily intersect
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
712 # the set of files, because their files() are not always files. For
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
713 # example, if intersecting a matcher "-I glob:foo.txt" with matcher of
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
714 # "path:dir2", we don't want to remove "dir2" from the set.
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
715 return self._m1.files() + self._m2.files()
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
716
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
717 def matchfn(self, f):
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
718 return self._m1(f) and self._m2(f)
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
719
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
720 def visitdir(self, dir):
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
721 visit1 = self._m1.visitdir(dir)
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
722 if visit1 == 'all':
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
723 return self._m2.visitdir(dir)
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
724 # bool() because visit1=True + visit2='all' should not be 'all'
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
725 return bool(visit1 and self._m2.visitdir(dir))
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
726
38993
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
727 def visitchildrenset(self, dir):
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
728 m1_set = self._m1.visitchildrenset(dir)
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
729 if not m1_set:
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
730 return set()
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
731 m2_set = self._m2.visitchildrenset(dir)
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
732 if not m2_set:
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
733 return set()
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
734
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
735 if m1_set == 'all':
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
736 return m2_set
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
737 elif m2_set == 'all':
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
738 return m1_set
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
739
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
740 if m1_set == 'this' or m2_set == 'this':
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
741 return 'this'
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
742
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
743 assert isinstance(m1_set, set) and isinstance(m2_set, set)
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
744 return m1_set.intersection(m2_set)
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
745
32530
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
746 def always(self):
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
747 return self._m1.always() and self._m2.always()
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
748
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
749 def isexact(self):
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
750 return self._m1.isexact() or self._m2.isexact()
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
751
36088
c4fa47f880d3 py3: make sure we return str from __repr__
Pulkit Goyal <7895pulkit@gmail.com>
parents: 35659
diff changeset
752 @encoding.strmethod
32530
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
753 def __repr__(self):
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
754 return ('<intersectionmatcher m1=%r, m2=%r>' % (self._m1, self._m2))
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
755
32494
f9445b528687 match: make subdirmatcher extend basematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32493
diff changeset
756 class subdirmatcher(basematcher):
12165
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
757 """Adapt a matcher to work on a subdirectory only.
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
758
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
759 The paths are remapped to remove/insert the path as needed:
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
760
34152
a8994d08e4a2 doctest: use print_function and convert bytes to unicode where needed
Yuya Nishihara <yuya@tcha.org>
parents: 34146
diff changeset
761 >>> from . import pycompat
34146
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33710
diff changeset
762 >>> m1 = match(b'root', b'', [b'a.txt', b'sub/b.txt'])
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33710
diff changeset
763 >>> m2 = subdirmatcher(b'sub', m1)
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33710
diff changeset
764 >>> bool(m2(b'a.txt'))
12165
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
765 False
34146
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33710
diff changeset
766 >>> bool(m2(b'b.txt'))
12165
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
767 True
34146
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33710
diff changeset
768 >>> bool(m2.matchfn(b'a.txt'))
12165
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
769 False
34146
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33710
diff changeset
770 >>> bool(m2.matchfn(b'b.txt'))
12165
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
771 True
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
772 >>> m2.files()
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
773 ['b.txt']
34146
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33710
diff changeset
774 >>> m2.exact(b'b.txt')
12165
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
775 True
34146
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33710
diff changeset
776 >>> util.pconvert(m2.rel(b'b.txt'))
23686
164915e8ef7b narrowmatcher: propagate the rel() method
Matt Harbison <matt_harbison@yahoo.com>
parents: 23685
diff changeset
777 'sub/b.txt'
12268
83aaeba32b88 narrowmatcher: propagate bad method
Martin Geisler <mg@lazybytes.net>
parents: 12267
diff changeset
778 >>> def bad(f, msg):
34152
a8994d08e4a2 doctest: use print_function and convert bytes to unicode where needed
Yuya Nishihara <yuya@tcha.org>
parents: 34146
diff changeset
779 ... print(pycompat.sysstr(b"%s: %s" % (f, msg)))
12268
83aaeba32b88 narrowmatcher: propagate bad method
Martin Geisler <mg@lazybytes.net>
parents: 12267
diff changeset
780 >>> m1.bad = bad
34146
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33710
diff changeset
781 >>> m2.bad(b'x.txt', b'No such file')
12268
83aaeba32b88 narrowmatcher: propagate bad method
Martin Geisler <mg@lazybytes.net>
parents: 12267
diff changeset
782 sub/x.txt: No such file
34146
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33710
diff changeset
783 >>> m2.abs(b'c.txt')
23685
5b1eac343ccd match: add the abs() method
Matt Harbison <matt_harbison@yahoo.com>
parents: 23549
diff changeset
784 'sub/c.txt'
12165
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
785 """
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
786
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
787 def __init__(self, path, matcher):
32494
f9445b528687 match: make subdirmatcher extend basematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32493
diff changeset
788 super(subdirmatcher, self).__init__(matcher._root, matcher._cwd)
12165
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
789 self._path = path
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
790 self._matcher = matcher
32494
f9445b528687 match: make subdirmatcher extend basematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32493
diff changeset
791 self._always = matcher.always()
12165
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
792
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
793 self._files = [f[len(path) + 1:] for f in matcher._files
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
794 if f.startswith(path + "/")]
25194
ef4538ba67ef match: explicitly naming a subrepo implies always() for the submatcher
Matt Harbison <matt_harbison@yahoo.com>
parents: 24790
diff changeset
795
32365
763d72925691 match: use match.prefix() in subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32364
diff changeset
796 # If the parent repo had a path to this subrepo and the matcher is
763d72925691 match: use match.prefix() in subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32364
diff changeset
797 # a prefix matcher, this submatcher always matches.
763d72925691 match: use match.prefix() in subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32364
diff changeset
798 if matcher.prefix():
25195
472a685a4961 merge with stable
Matt Mackall <mpm@selenic.com>
parents: 25189 25194
diff changeset
799 self._always = any(f == path for f in matcher._files)
25194
ef4538ba67ef match: explicitly naming a subrepo implies always() for the submatcher
Matt Harbison <matt_harbison@yahoo.com>
parents: 24790
diff changeset
800
32364
77dac8fd30ee match: avoid accessing match._pathrestricted from subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32363
diff changeset
801 def bad(self, f, msg):
77dac8fd30ee match: avoid accessing match._pathrestricted from subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32363
diff changeset
802 self._matcher.bad(self._path + "/" + f, msg)
77dac8fd30ee match: avoid accessing match._pathrestricted from subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32363
diff changeset
803
23685
5b1eac343ccd match: add the abs() method
Matt Harbison <matt_harbison@yahoo.com>
parents: 23549
diff changeset
804 def abs(self, f):
5b1eac343ccd match: add the abs() method
Matt Harbison <matt_harbison@yahoo.com>
parents: 23549
diff changeset
805 return self._matcher.abs(self._path + "/" + f)
5b1eac343ccd match: add the abs() method
Matt Harbison <matt_harbison@yahoo.com>
parents: 23549
diff changeset
806
23686
164915e8ef7b narrowmatcher: propagate the rel() method
Matt Harbison <matt_harbison@yahoo.com>
parents: 23685
diff changeset
807 def rel(self, f):
164915e8ef7b narrowmatcher: propagate the rel() method
Matt Harbison <matt_harbison@yahoo.com>
parents: 23685
diff changeset
808 return self._matcher.rel(self._path + "/" + f)
164915e8ef7b narrowmatcher: propagate the rel() method
Matt Harbison <matt_harbison@yahoo.com>
parents: 23685
diff changeset
809
32364
77dac8fd30ee match: avoid accessing match._pathrestricted from subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32363
diff changeset
810 def uipath(self, f):
77dac8fd30ee match: avoid accessing match._pathrestricted from subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32363
diff changeset
811 return self._matcher.uipath(self._path + "/" + f)
77dac8fd30ee match: avoid accessing match._pathrestricted from subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32363
diff changeset
812
32498
2e80a691e575 match: override matchfn() the usual way in subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32497
diff changeset
813 def matchfn(self, f):
2e80a691e575 match: override matchfn() the usual way in subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32497
diff changeset
814 # Some information is lost in the superclass's constructor, so we
2e80a691e575 match: override matchfn() the usual way in subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32497
diff changeset
815 # can not accurately create the matching function for the subdirectory
2e80a691e575 match: override matchfn() the usual way in subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32497
diff changeset
816 # from the inputs. Instead, we override matchfn() and visitdir() to
2e80a691e575 match: override matchfn() the usual way in subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32497
diff changeset
817 # call the original matcher with the subdirectory path prepended.
2e80a691e575 match: override matchfn() the usual way in subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32497
diff changeset
818 return self._matcher.matchfn(self._path + "/" + f)
2e80a691e575 match: override matchfn() the usual way in subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32497
diff changeset
819
32363
0aa4032a97e1 match: override visitdir() the usual way in subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32362
diff changeset
820 def visitdir(self, dir):
0aa4032a97e1 match: override visitdir() the usual way in subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32362
diff changeset
821 if dir == '.':
0aa4032a97e1 match: override visitdir() the usual way in subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32362
diff changeset
822 dir = self._path
0aa4032a97e1 match: override visitdir() the usual way in subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32362
diff changeset
823 else:
0aa4032a97e1 match: override visitdir() the usual way in subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32362
diff changeset
824 dir = self._path + "/" + dir
0aa4032a97e1 match: override visitdir() the usual way in subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32362
diff changeset
825 return self._matcher.visitdir(dir)
0aa4032a97e1 match: override visitdir() the usual way in subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32362
diff changeset
826
38993
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
827 def visitchildrenset(self, dir):
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
828 if dir == '.':
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
829 dir = self._path
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
830 else:
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
831 dir = self._path + "/" + dir
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
832 return self._matcher.visitchildrenset(dir)
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
833
32494
f9445b528687 match: make subdirmatcher extend basematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32493
diff changeset
834 def always(self):
f9445b528687 match: make subdirmatcher extend basematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32493
diff changeset
835 return self._always
f9445b528687 match: make subdirmatcher extend basematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32493
diff changeset
836
33379
7ddb2aa2b7af match: express anypats(), not prefix(), in terms of the others
Martin von Zweigbergk <martinvonz@google.com>
parents: 33378
diff changeset
837 def prefix(self):
7ddb2aa2b7af match: express anypats(), not prefix(), in terms of the others
Martin von Zweigbergk <martinvonz@google.com>
parents: 33378
diff changeset
838 return self._matcher.prefix() and not self._always
32494
f9445b528687 match: make subdirmatcher extend basematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32493
diff changeset
839
36088
c4fa47f880d3 py3: make sure we return str from __repr__
Pulkit Goyal <7895pulkit@gmail.com>
parents: 35659
diff changeset
840 @encoding.strmethod
32585
e7aa11f3abcd match: add __repr__ for subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32576
diff changeset
841 def __repr__(self):
e7aa11f3abcd match: add __repr__ for subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32576
diff changeset
842 return ('<subdirmatcher path=%r, matcher=%r>' %
e7aa11f3abcd match: add __repr__ for subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32576
diff changeset
843 (self._path, self._matcher))
e7aa11f3abcd match: add __repr__ for subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32576
diff changeset
844
38612
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38582
diff changeset
845 class prefixdirmatcher(basematcher):
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38582
diff changeset
846 """Adapt a matcher to work on a parent directory.
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38582
diff changeset
847
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38582
diff changeset
848 The matcher's non-matching-attributes (root, cwd, bad, explicitdir,
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38582
diff changeset
849 traversedir) are ignored.
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38582
diff changeset
850
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38582
diff changeset
851 The prefix path should usually be the relative path from the root of
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38582
diff changeset
852 this matcher to the root of the wrapped matcher.
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38582
diff changeset
853
38750
a8bfaf592033 doctest: convert matcher root to native path
Yuya Nishihara <yuya@tcha.org>
parents: 38613
diff changeset
854 >>> m1 = match(util.localpath(b'root/d/e'), b'f', [b'../a.txt', b'b.txt'])
38612
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38582
diff changeset
855 >>> m2 = prefixdirmatcher(b'root', b'd/e/f', b'd/e', m1)
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38582
diff changeset
856 >>> bool(m2(b'a.txt'),)
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38582
diff changeset
857 False
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38582
diff changeset
858 >>> bool(m2(b'd/e/a.txt'))
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38582
diff changeset
859 True
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38582
diff changeset
860 >>> bool(m2(b'd/e/b.txt'))
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38582
diff changeset
861 False
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38582
diff changeset
862 >>> m2.files()
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38582
diff changeset
863 ['d/e/a.txt', 'd/e/f/b.txt']
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38582
diff changeset
864 >>> m2.exact(b'd/e/a.txt')
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38582
diff changeset
865 True
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38582
diff changeset
866 >>> m2.visitdir(b'd')
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38582
diff changeset
867 True
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38582
diff changeset
868 >>> m2.visitdir(b'd/e')
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38582
diff changeset
869 True
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38582
diff changeset
870 >>> m2.visitdir(b'd/e/f')
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38582
diff changeset
871 True
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38582
diff changeset
872 >>> m2.visitdir(b'd/e/g')
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38582
diff changeset
873 False
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38582
diff changeset
874 >>> m2.visitdir(b'd/ef')
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38582
diff changeset
875 False
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38582
diff changeset
876 """
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38582
diff changeset
877
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38582
diff changeset
878 def __init__(self, root, cwd, path, matcher, badfn=None):
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38582
diff changeset
879 super(prefixdirmatcher, self).__init__(root, cwd, badfn)
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38582
diff changeset
880 if not path:
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38582
diff changeset
881 raise error.ProgrammingError('prefix path must not be empty')
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38582
diff changeset
882 self._path = path
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38582
diff changeset
883 self._pathprefix = path + '/'
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38582
diff changeset
884 self._matcher = matcher
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38582
diff changeset
885
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38582
diff changeset
886 @propertycache
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38582
diff changeset
887 def _files(self):
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38582
diff changeset
888 return [self._pathprefix + f for f in self._matcher._files]
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38582
diff changeset
889
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38582
diff changeset
890 def matchfn(self, f):
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38582
diff changeset
891 if not f.startswith(self._pathprefix):
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38582
diff changeset
892 return False
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38582
diff changeset
893 return self._matcher.matchfn(f[len(self._pathprefix):])
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38582
diff changeset
894
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38582
diff changeset
895 @propertycache
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38582
diff changeset
896 def _pathdirs(self):
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38582
diff changeset
897 return set(util.finddirs(self._path)) | {'.'}
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38582
diff changeset
898
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38582
diff changeset
899 def visitdir(self, dir):
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38582
diff changeset
900 if dir == self._path:
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38582
diff changeset
901 return self._matcher.visitdir('.')
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38582
diff changeset
902 if dir.startswith(self._pathprefix):
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38582
diff changeset
903 return self._matcher.visitdir(dir[len(self._pathprefix):])
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38582
diff changeset
904 return dir in self._pathdirs
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38582
diff changeset
905
38993
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
906 def visitchildrenset(self, dir):
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
907 if dir == self._path:
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
908 return self._matcher.visitchildrenset('.')
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
909 if dir.startswith(self._pathprefix):
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
910 return self._matcher.visitchildrenset(dir[len(self._pathprefix):])
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
911 if dir in self._pathdirs:
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
912 return 'this'
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
913
38612
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38582
diff changeset
914 def isexact(self):
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38582
diff changeset
915 return self._matcher.isexact()
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38582
diff changeset
916
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38582
diff changeset
917 def prefix(self):
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38582
diff changeset
918 return self._matcher.prefix()
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38582
diff changeset
919
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38582
diff changeset
920 @encoding.strmethod
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38582
diff changeset
921 def __repr__(self):
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38582
diff changeset
922 return ('<prefixdirmatcher path=%r, matcher=%r>'
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38582
diff changeset
923 % (pycompat.bytestr(self._path), self._matcher))
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38582
diff changeset
924
33319
3c84591e7321 match: move matchers from sparse into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33306
diff changeset
925 class unionmatcher(basematcher):
33448
04be8aec44a8 match: make unionmatcher a proper matcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 33447
diff changeset
926 """A matcher that is the union of several matchers.
04be8aec44a8 match: make unionmatcher a proper matcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 33447
diff changeset
927
04be8aec44a8 match: make unionmatcher a proper matcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 33447
diff changeset
928 The non-matching-attributes (root, cwd, bad, explicitdir, traversedir) are
04be8aec44a8 match: make unionmatcher a proper matcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 33447
diff changeset
929 taken from the first matcher.
04be8aec44a8 match: make unionmatcher a proper matcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 33447
diff changeset
930 """
04be8aec44a8 match: make unionmatcher a proper matcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 33447
diff changeset
931
33319
3c84591e7321 match: move matchers from sparse into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33306
diff changeset
932 def __init__(self, matchers):
33448
04be8aec44a8 match: make unionmatcher a proper matcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 33447
diff changeset
933 m1 = matchers[0]
04be8aec44a8 match: make unionmatcher a proper matcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 33447
diff changeset
934 super(unionmatcher, self).__init__(m1._root, m1._cwd)
04be8aec44a8 match: make unionmatcher a proper matcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 33447
diff changeset
935 self.explicitdir = m1.explicitdir
04be8aec44a8 match: make unionmatcher a proper matcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 33447
diff changeset
936 self.traversedir = m1.traversedir
33319
3c84591e7321 match: move matchers from sparse into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33306
diff changeset
937 self._matchers = matchers
3c84591e7321 match: move matchers from sparse into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33306
diff changeset
938
33380
892d255ec2a1 match: override matchfn instead of __call__ for consistency
Martin von Zweigbergk <martinvonz@google.com>
parents: 33379
diff changeset
939 def matchfn(self, f):
33319
3c84591e7321 match: move matchers from sparse into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33306
diff changeset
940 for match in self._matchers:
33380
892d255ec2a1 match: override matchfn instead of __call__ for consistency
Martin von Zweigbergk <martinvonz@google.com>
parents: 33379
diff changeset
941 if match(f):
33319
3c84591e7321 match: move matchers from sparse into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33306
diff changeset
942 return True
3c84591e7321 match: move matchers from sparse into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33306
diff changeset
943 return False
3c84591e7321 match: move matchers from sparse into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33306
diff changeset
944
33448
04be8aec44a8 match: make unionmatcher a proper matcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 33447
diff changeset
945 def visitdir(self, dir):
04be8aec44a8 match: make unionmatcher a proper matcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 33447
diff changeset
946 r = False
04be8aec44a8 match: make unionmatcher a proper matcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 33447
diff changeset
947 for m in self._matchers:
04be8aec44a8 match: make unionmatcher a proper matcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 33447
diff changeset
948 v = m.visitdir(dir)
04be8aec44a8 match: make unionmatcher a proper matcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 33447
diff changeset
949 if v == 'all':
04be8aec44a8 match: make unionmatcher a proper matcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 33447
diff changeset
950 return v
04be8aec44a8 match: make unionmatcher a proper matcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 33447
diff changeset
951 r |= v
04be8aec44a8 match: make unionmatcher a proper matcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 33447
diff changeset
952 return r
04be8aec44a8 match: make unionmatcher a proper matcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 33447
diff changeset
953
38993
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
954 def visitchildrenset(self, dir):
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
955 r = set()
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
956 this = False
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
957 for m in self._matchers:
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
958 v = m.visitchildrenset(dir)
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
959 if not v:
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
960 continue
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
961 if v == 'all':
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
962 return v
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
963 if this or v == 'this':
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
964 this = True
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
965 # don't break, we might have an 'all' in here.
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
966 continue
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
967 assert isinstance(v, set)
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
968 r = r.union(v)
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
969 if this:
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
970 return 'this'
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
971 return r
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38992
diff changeset
972
36088
c4fa47f880d3 py3: make sure we return str from __repr__
Pulkit Goyal <7895pulkit@gmail.com>
parents: 35659
diff changeset
973 @encoding.strmethod
33319
3c84591e7321 match: move matchers from sparse into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33306
diff changeset
974 def __repr__(self):
3c84591e7321 match: move matchers from sparse into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33306
diff changeset
975 return ('<unionmatcher matchers=%r>' % self._matchers)
3c84591e7321 match: move matchers from sparse into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33306
diff changeset
976
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
977 def patkind(pattern, default=None):
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
978 '''If pattern is 'kind:pat' with a known kind, return kind.'''
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
979 return _patsplit(pattern, default)[0]
8570
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
980
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
981 def _patsplit(pattern, default):
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
982 """Split a string into the optional pattern kind prefix and the actual
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
983 pattern."""
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
984 if ':' in pattern:
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
985 kind, pat = pattern.split(':', 1)
33710
2be0bf186950 match: expose some data and functionality to other modules
Kostia Balytskyi <ikostia@fb.com>
parents: 33582
diff changeset
986 if kind in allpatternkinds:
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
987 return kind, pat
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
988 return default, pattern
8570
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
989
8582
a4c199e12b5a match: remove head and tail args from _globre
Matt Mackall <mpm@selenic.com>
parents: 8581
diff changeset
990 def _globre(pat):
21112
03782d2fc776 match: _globre doctests
Mads Kiilerich <madski@unity3d.com>
parents: 21111
diff changeset
991 r'''Convert an extended glob string to a regexp string.
03782d2fc776 match: _globre doctests
Mads Kiilerich <madski@unity3d.com>
parents: 21111
diff changeset
992
34152
a8994d08e4a2 doctest: use print_function and convert bytes to unicode where needed
Yuya Nishihara <yuya@tcha.org>
parents: 34146
diff changeset
993 >>> from . import pycompat
a8994d08e4a2 doctest: use print_function and convert bytes to unicode where needed
Yuya Nishihara <yuya@tcha.org>
parents: 34146
diff changeset
994 >>> def bprint(s):
a8994d08e4a2 doctest: use print_function and convert bytes to unicode where needed
Yuya Nishihara <yuya@tcha.org>
parents: 34146
diff changeset
995 ... print(pycompat.sysstr(s))
a8994d08e4a2 doctest: use print_function and convert bytes to unicode where needed
Yuya Nishihara <yuya@tcha.org>
parents: 34146
diff changeset
996 >>> bprint(_globre(br'?'))
21112
03782d2fc776 match: _globre doctests
Mads Kiilerich <madski@unity3d.com>
parents: 21111
diff changeset
997 .
34152
a8994d08e4a2 doctest: use print_function and convert bytes to unicode where needed
Yuya Nishihara <yuya@tcha.org>
parents: 34146
diff changeset
998 >>> bprint(_globre(br'*'))
21112
03782d2fc776 match: _globre doctests
Mads Kiilerich <madski@unity3d.com>
parents: 21111
diff changeset
999 [^/]*
34152
a8994d08e4a2 doctest: use print_function and convert bytes to unicode where needed
Yuya Nishihara <yuya@tcha.org>
parents: 34146
diff changeset
1000 >>> bprint(_globre(br'**'))
21112
03782d2fc776 match: _globre doctests
Mads Kiilerich <madski@unity3d.com>
parents: 21111
diff changeset
1001 .*
34152
a8994d08e4a2 doctest: use print_function and convert bytes to unicode where needed
Yuya Nishihara <yuya@tcha.org>
parents: 34146
diff changeset
1002 >>> bprint(_globre(br'**/a'))
21815
a4b67bf1f0a5 match: make glob '**/' match the empty string
Siddharth Agarwal <sid0@fb.com>
parents: 21191
diff changeset
1003 (?:.*/)?a
34152
a8994d08e4a2 doctest: use print_function and convert bytes to unicode where needed
Yuya Nishihara <yuya@tcha.org>
parents: 34146
diff changeset
1004 >>> bprint(_globre(br'a/**/b'))
38479
67dc32d4e790 cleanup: migrate from re.escape to stringutil.reescape
Augie Fackler <augie@google.com>
parents: 38061
diff changeset
1005 a/(?:.*/)?b
34152
a8994d08e4a2 doctest: use print_function and convert bytes to unicode where needed
Yuya Nishihara <yuya@tcha.org>
parents: 34146
diff changeset
1006 >>> bprint(_globre(br'[a*?!^][^b][!c]'))
21112
03782d2fc776 match: _globre doctests
Mads Kiilerich <madski@unity3d.com>
parents: 21111
diff changeset
1007 [a*?!^][\^b][^c]
34152
a8994d08e4a2 doctest: use print_function and convert bytes to unicode where needed
Yuya Nishihara <yuya@tcha.org>
parents: 34146
diff changeset
1008 >>> bprint(_globre(br'{a,b}'))
21112
03782d2fc776 match: _globre doctests
Mads Kiilerich <madski@unity3d.com>
parents: 21111
diff changeset
1009 (?:a|b)
34152
a8994d08e4a2 doctest: use print_function and convert bytes to unicode where needed
Yuya Nishihara <yuya@tcha.org>
parents: 34146
diff changeset
1010 >>> bprint(_globre(br'.\*\?'))
21112
03782d2fc776 match: _globre doctests
Mads Kiilerich <madski@unity3d.com>
parents: 21111
diff changeset
1011 \.\*\?
03782d2fc776 match: _globre doctests
Mads Kiilerich <madski@unity3d.com>
parents: 21111
diff changeset
1012 '''
8570
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
1013 i, n = 0, len(pat)
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
1014 res = ''
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
1015 group = 0
38479
67dc32d4e790 cleanup: migrate from re.escape to stringutil.reescape
Augie Fackler <augie@google.com>
parents: 38061
diff changeset
1016 escape = util.stringutil.reescape
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10263
diff changeset
1017 def peek():
31430
5c9cda37d7f6 match: slice over bytes to get the byteschr instead of ascii value
Pulkit Goyal <7895pulkit@gmail.com>
parents: 31429
diff changeset
1018 return i < n and pat[i:i + 1]
8570
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
1019 while i < n:
31430
5c9cda37d7f6 match: slice over bytes to get the byteschr instead of ascii value
Pulkit Goyal <7895pulkit@gmail.com>
parents: 31429
diff changeset
1020 c = pat[i:i + 1]
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10263
diff changeset
1021 i += 1
8583
19d1b2aec562 match: optimize escaping in _globre
Matt Mackall <mpm@selenic.com>
parents: 8582
diff changeset
1022 if c not in '*?[{},\\':
19d1b2aec562 match: optimize escaping in _globre
Matt Mackall <mpm@selenic.com>
parents: 8582
diff changeset
1023 res += escape(c)
19d1b2aec562 match: optimize escaping in _globre
Matt Mackall <mpm@selenic.com>
parents: 8582
diff changeset
1024 elif c == '*':
8570
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
1025 if peek() == '*':
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
1026 i += 1
21815
a4b67bf1f0a5 match: make glob '**/' match the empty string
Siddharth Agarwal <sid0@fb.com>
parents: 21191
diff changeset
1027 if peek() == '/':
a4b67bf1f0a5 match: make glob '**/' match the empty string
Siddharth Agarwal <sid0@fb.com>
parents: 21191
diff changeset
1028 i += 1
a4b67bf1f0a5 match: make glob '**/' match the empty string
Siddharth Agarwal <sid0@fb.com>
parents: 21191
diff changeset
1029 res += '(?:.*/)?'
a4b67bf1f0a5 match: make glob '**/' match the empty string
Siddharth Agarwal <sid0@fb.com>
parents: 21191
diff changeset
1030 else:
a4b67bf1f0a5 match: make glob '**/' match the empty string
Siddharth Agarwal <sid0@fb.com>
parents: 21191
diff changeset
1031 res += '.*'
8570
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
1032 else:
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
1033 res += '[^/]*'
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
1034 elif c == '?':
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
1035 res += '.'
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
1036 elif c == '[':
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
1037 j = i
31430
5c9cda37d7f6 match: slice over bytes to get the byteschr instead of ascii value
Pulkit Goyal <7895pulkit@gmail.com>
parents: 31429
diff changeset
1038 if j < n and pat[j:j + 1] in '!]':
8570
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
1039 j += 1
31430
5c9cda37d7f6 match: slice over bytes to get the byteschr instead of ascii value
Pulkit Goyal <7895pulkit@gmail.com>
parents: 31429
diff changeset
1040 while j < n and pat[j:j + 1] != ']':
8570
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
1041 j += 1
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
1042 if j >= n:
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
1043 res += '\\['
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
1044 else:
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
1045 stuff = pat[i:j].replace('\\','\\\\')
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
1046 i = j + 1
31430
5c9cda37d7f6 match: slice over bytes to get the byteschr instead of ascii value
Pulkit Goyal <7895pulkit@gmail.com>
parents: 31429
diff changeset
1047 if stuff[0:1] == '!':
8570
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
1048 stuff = '^' + stuff[1:]
31430
5c9cda37d7f6 match: slice over bytes to get the byteschr instead of ascii value
Pulkit Goyal <7895pulkit@gmail.com>
parents: 31429
diff changeset
1049 elif stuff[0:1] == '^':
8570
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
1050 stuff = '\\' + stuff
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
1051 res = '%s[%s]' % (res, stuff)
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
1052 elif c == '{':
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
1053 group += 1
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
1054 res += '(?:'
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
1055 elif c == '}' and group:
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
1056 res += ')'
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
1057 group -= 1
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
1058 elif c == ',' and group:
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
1059 res += '|'
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
1060 elif c == '\\':
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
1061 p = peek()
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
1062 if p:
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
1063 i += 1
8583
19d1b2aec562 match: optimize escaping in _globre
Matt Mackall <mpm@selenic.com>
parents: 8582
diff changeset
1064 res += escape(p)
8570
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
1065 else:
8583
19d1b2aec562 match: optimize escaping in _globre
Matt Mackall <mpm@selenic.com>
parents: 8582
diff changeset
1066 res += escape(c)
8570
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
1067 else:
8583
19d1b2aec562 match: optimize escaping in _globre
Matt Mackall <mpm@selenic.com>
parents: 8582
diff changeset
1068 res += escape(c)
8582
a4c199e12b5a match: remove head and tail args from _globre
Matt Mackall <mpm@selenic.com>
parents: 8581
diff changeset
1069 return res
8570
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
1070
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
1071 def _regex(kind, pat, globsuffix):
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
1072 '''Convert a (normalized) pattern of any kind into a regular expression.
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
1073 globsuffix is appended to the regexp of globs.'''
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
1074 if not pat:
8574
63a7ed2128d5 match: unnest functions in _matcher
Matt Mackall <mpm@selenic.com>
parents: 8573
diff changeset
1075 return ''
63a7ed2128d5 match: unnest functions in _matcher
Matt Mackall <mpm@selenic.com>
parents: 8573
diff changeset
1076 if kind == 're':
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
1077 return pat
33358
38b6122df5c7 match: combine regex code for path: and relpath:
Martin von Zweigbergk <martinvonz@google.com>
parents: 33357
diff changeset
1078 if kind in ('path', 'relpath'):
25636
bfe9ed85f27c match: let 'path:.' and 'path:' match everything (issue4687)
Matt Harbison <matt_harbison@yahoo.com>
parents: 25194
diff changeset
1079 if pat == '.':
bfe9ed85f27c match: let 'path:.' and 'path:' match everything (issue4687)
Matt Harbison <matt_harbison@yahoo.com>
parents: 25194
diff changeset
1080 return ''
38479
67dc32d4e790 cleanup: migrate from re.escape to stringutil.reescape
Augie Fackler <augie@google.com>
parents: 38061
diff changeset
1081 return util.stringutil.reescape(pat) + '(?:/|$)'
31032
88358446da16 match: adding support for matching files inside a directory
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 30409
diff changeset
1082 if kind == 'rootfilesin':
88358446da16 match: adding support for matching files inside a directory
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 30409
diff changeset
1083 if pat == '.':
88358446da16 match: adding support for matching files inside a directory
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 30409
diff changeset
1084 escaped = ''
88358446da16 match: adding support for matching files inside a directory
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 30409
diff changeset
1085 else:
88358446da16 match: adding support for matching files inside a directory
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 30409
diff changeset
1086 # Pattern is a directory name.
38479
67dc32d4e790 cleanup: migrate from re.escape to stringutil.reescape
Augie Fackler <augie@google.com>
parents: 38061
diff changeset
1087 escaped = util.stringutil.reescape(pat) + '/'
31032
88358446da16 match: adding support for matching files inside a directory
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 30409
diff changeset
1088 # Anything after the pattern must be a non-directory.
33357
a21819f439fe match: remove unnecessary '^' from regexes
Martin von Zweigbergk <martinvonz@google.com>
parents: 33319
diff changeset
1089 return escaped + '[^/]+$'
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
1090 if kind == 'relglob':
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
1091 return '(?:|.*/)' + _globre(pat) + globsuffix
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
1092 if kind == 'relre':
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
1093 if pat.startswith('^'):
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
1094 return pat
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
1095 return '.*' + pat
38579
2d487b9cac07 match: explode if unsupported pattern passed down to _regex() builder
Yuya Nishihara <yuya@tcha.org>
parents: 38578
diff changeset
1096 if kind == 'glob':
2d487b9cac07 match: explode if unsupported pattern passed down to _regex() builder
Yuya Nishihara <yuya@tcha.org>
parents: 38578
diff changeset
1097 return _globre(pat) + globsuffix
2d487b9cac07 match: explode if unsupported pattern passed down to _regex() builder
Yuya Nishihara <yuya@tcha.org>
parents: 38578
diff changeset
1098 raise error.ProgrammingError('not a regex pattern: %s:%s' % (kind, pat))
8574
63a7ed2128d5 match: unnest functions in _matcher
Matt Mackall <mpm@selenic.com>
parents: 8573
diff changeset
1099
38582
6467286b829c match: remove ctx argument from code path down to _buildmatch()
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
1100 def _buildmatch(kindpats, globsuffix, listsubrepos, root):
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
1101 '''Return regexp string and a matcher function for kindpats.
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
1102 globsuffix is appended to the regexp of globs.'''
25239
714f612f2afc match: allow unioning arbitrary match functions
Durham Goode <durham@fb.com>
parents: 25238
diff changeset
1103 matchfuncs = []
714f612f2afc match: allow unioning arbitrary match functions
Durham Goode <durham@fb.com>
parents: 25238
diff changeset
1104
25283
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
1105 subincludes, kindpats = _expandsubinclude(kindpats, root)
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
1106 if subincludes:
32185
6dea1701f170 match: make subinclude construction lazy
Durham Goode <durham@fb.com>
parents: 31442
diff changeset
1107 submatchers = {}
25283
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
1108 def matchsubinclude(f):
32185
6dea1701f170 match: make subinclude construction lazy
Durham Goode <durham@fb.com>
parents: 31442
diff changeset
1109 for prefix, matcherargs in subincludes:
6dea1701f170 match: make subinclude construction lazy
Durham Goode <durham@fb.com>
parents: 31442
diff changeset
1110 if f.startswith(prefix):
6dea1701f170 match: make subinclude construction lazy
Durham Goode <durham@fb.com>
parents: 31442
diff changeset
1111 mf = submatchers.get(prefix)
6dea1701f170 match: make subinclude construction lazy
Durham Goode <durham@fb.com>
parents: 31442
diff changeset
1112 if mf is None:
6dea1701f170 match: make subinclude construction lazy
Durham Goode <durham@fb.com>
parents: 31442
diff changeset
1113 mf = match(*matcherargs)
6dea1701f170 match: make subinclude construction lazy
Durham Goode <durham@fb.com>
parents: 31442
diff changeset
1114 submatchers[prefix] = mf
6dea1701f170 match: make subinclude construction lazy
Durham Goode <durham@fb.com>
parents: 31442
diff changeset
1115
6dea1701f170 match: make subinclude construction lazy
Durham Goode <durham@fb.com>
parents: 31442
diff changeset
1116 if mf(f[len(prefix):]):
6dea1701f170 match: make subinclude construction lazy
Durham Goode <durham@fb.com>
parents: 31442
diff changeset
1117 return True
25283
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
1118 return False
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
1119 matchfuncs.append(matchsubinclude)
14675
cfc89398f710 match: introduce basic fileset support
Matt Mackall <mpm@selenic.com>
parents: 14674
diff changeset
1120
25239
714f612f2afc match: allow unioning arbitrary match functions
Durham Goode <durham@fb.com>
parents: 25238
diff changeset
1121 regex = ''
714f612f2afc match: allow unioning arbitrary match functions
Durham Goode <durham@fb.com>
parents: 25238
diff changeset
1122 if kindpats:
714f612f2afc match: allow unioning arbitrary match functions
Durham Goode <durham@fb.com>
parents: 25238
diff changeset
1123 regex, mf = _buildregexmatch(kindpats, globsuffix)
714f612f2afc match: allow unioning arbitrary match functions
Durham Goode <durham@fb.com>
parents: 25238
diff changeset
1124 matchfuncs.append(mf)
714f612f2afc match: allow unioning arbitrary match functions
Durham Goode <durham@fb.com>
parents: 25238
diff changeset
1125
714f612f2afc match: allow unioning arbitrary match functions
Durham Goode <durham@fb.com>
parents: 25238
diff changeset
1126 if len(matchfuncs) == 1:
714f612f2afc match: allow unioning arbitrary match functions
Durham Goode <durham@fb.com>
parents: 25238
diff changeset
1127 return regex, matchfuncs[0]
714f612f2afc match: allow unioning arbitrary match functions
Durham Goode <durham@fb.com>
parents: 25238
diff changeset
1128 else:
714f612f2afc match: allow unioning arbitrary match functions
Durham Goode <durham@fb.com>
parents: 25238
diff changeset
1129 return regex, lambda f: any(mf(f) for mf in matchfuncs)
14675
cfc89398f710 match: introduce basic fileset support
Matt Mackall <mpm@selenic.com>
parents: 14674
diff changeset
1130
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
1131 def _buildregexmatch(kindpats, globsuffix):
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
1132 """Build a match function from a list of kinds and kindpats,
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
1133 return regexp string and a matcher function."""
8574
63a7ed2128d5 match: unnest functions in _matcher
Matt Mackall <mpm@selenic.com>
parents: 8573
diff changeset
1134 try:
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
1135 regex = '(?:%s)' % '|'.join([_regex(k, p, globsuffix)
25213
08a8e9da0ae7 match: add source to kindpats list
Durham Goode <durham@fb.com>
parents: 25195
diff changeset
1136 for (k, p, s) in kindpats])
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
1137 if len(regex) > 20000:
16687
e34106fa0dc3 cleanup: "raise SomeException()" -> "raise SomeException"
Brodie Rao <brodie@sf.io>
parents: 16645
diff changeset
1138 raise OverflowError
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
1139 return regex, _rematcher(regex)
8574
63a7ed2128d5 match: unnest functions in _matcher
Matt Mackall <mpm@selenic.com>
parents: 8573
diff changeset
1140 except OverflowError:
63a7ed2128d5 match: unnest functions in _matcher
Matt Mackall <mpm@selenic.com>
parents: 8573
diff changeset
1141 # We're using a Python with a tiny regex engine and we
63a7ed2128d5 match: unnest functions in _matcher
Matt Mackall <mpm@selenic.com>
parents: 8573
diff changeset
1142 # made it explode, so we'll divide the pattern list in two
63a7ed2128d5 match: unnest functions in _matcher
Matt Mackall <mpm@selenic.com>
parents: 8573
diff changeset
1143 # until it works
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
1144 l = len(kindpats)
8574
63a7ed2128d5 match: unnest functions in _matcher
Matt Mackall <mpm@selenic.com>
parents: 8573
diff changeset
1145 if l < 2:
63a7ed2128d5 match: unnest functions in _matcher
Matt Mackall <mpm@selenic.com>
parents: 8573
diff changeset
1146 raise
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
1147 regexa, a = _buildregexmatch(kindpats[:l//2], globsuffix)
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
1148 regexb, b = _buildregexmatch(kindpats[l//2:], globsuffix)
21191
a2f4ea82d6d3 match: fix NameError 'pat' on overflow of regex pattern length
Yuya Nishihara <yuya@tcha.org>
parents: 21113
diff changeset
1149 return regex, lambda s: a(s) or b(s)
8574
63a7ed2128d5 match: unnest functions in _matcher
Matt Mackall <mpm@selenic.com>
parents: 8573
diff changeset
1150 except re.error:
25213
08a8e9da0ae7 match: add source to kindpats list
Durham Goode <durham@fb.com>
parents: 25195
diff changeset
1151 for k, p, s in kindpats:
8574
63a7ed2128d5 match: unnest functions in _matcher
Matt Mackall <mpm@selenic.com>
parents: 8573
diff changeset
1152 try:
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
1153 _rematcher('(?:%s)' % _regex(k, p, globsuffix))
8574
63a7ed2128d5 match: unnest functions in _matcher
Matt Mackall <mpm@selenic.com>
parents: 8573
diff changeset
1154 except re.error:
25213
08a8e9da0ae7 match: add source to kindpats list
Durham Goode <durham@fb.com>
parents: 25195
diff changeset
1155 if s:
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26014
diff changeset
1156 raise error.Abort(_("%s: invalid pattern (%s): %s") %
25213
08a8e9da0ae7 match: add source to kindpats list
Durham Goode <durham@fb.com>
parents: 25195
diff changeset
1157 (s, k, p))
08a8e9da0ae7 match: add source to kindpats list
Durham Goode <durham@fb.com>
parents: 25195
diff changeset
1158 else:
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26014
diff changeset
1159 raise error.Abort(_("invalid pattern (%s): %s") % (k, p))
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26014
diff changeset
1160 raise error.Abort(_("invalid pattern"))
8574
63a7ed2128d5 match: unnest functions in _matcher
Matt Mackall <mpm@selenic.com>
parents: 8573
diff changeset
1161
31033
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
1162 def _patternrootsanddirs(kindpats):
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
1163 '''Returns roots and directories corresponding to each pattern.
21079
b02ab6486a78 match: make it more clear what _roots do and that it ends up in match()._files
Mads Kiilerich <madski@unity3d.com>
parents: 20401
diff changeset
1164
31033
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
1165 This calculates the roots and directories exactly matching the patterns and
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
1166 returns a tuple of (roots, dirs) for each. It does not return other
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
1167 directories which may also need to be considered, like the parent
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
1168 directories.
21079
b02ab6486a78 match: make it more clear what _roots do and that it ends up in match()._files
Mads Kiilerich <madski@unity3d.com>
parents: 20401
diff changeset
1169 '''
8576
ec4ed21db4b2 match: split up _normalizepats
Matt Mackall <mpm@selenic.com>
parents: 8575
diff changeset
1170 r = []
31033
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
1171 d = []
25213
08a8e9da0ae7 match: add source to kindpats list
Durham Goode <durham@fb.com>
parents: 25195
diff changeset
1172 for kind, pat, source in kindpats:
8584
0f06e72abfdc match: fold _globprefix into _roots
Matt Mackall <mpm@selenic.com>
parents: 8583
diff changeset
1173 if kind == 'glob': # find the non-glob prefix
0f06e72abfdc match: fold _globprefix into _roots
Matt Mackall <mpm@selenic.com>
parents: 8583
diff changeset
1174 root = []
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
1175 for p in pat.split('/'):
8584
0f06e72abfdc match: fold _globprefix into _roots
Matt Mackall <mpm@selenic.com>
parents: 8583
diff changeset
1176 if '[' in p or '{' in p or '*' in p or '?' in p:
0f06e72abfdc match: fold _globprefix into _roots
Matt Mackall <mpm@selenic.com>
parents: 8583
diff changeset
1177 break
0f06e72abfdc match: fold _globprefix into _roots
Matt Mackall <mpm@selenic.com>
parents: 8583
diff changeset
1178 root.append(p)
0f06e72abfdc match: fold _globprefix into _roots
Matt Mackall <mpm@selenic.com>
parents: 8583
diff changeset
1179 r.append('/'.join(root) or '.')
31033
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
1180 elif kind in ('relpath', 'path'):
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
1181 r.append(pat or '.')
31033
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
1182 elif kind in ('rootfilesin',):
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
1183 d.append(pat or '.')
19107
fcf08023c011 match: fix root calculation for combining regexps with simple paths
Mads Kiilerich <madski@unity3d.com>
parents: 18713
diff changeset
1184 else: # relglob, re, relre
8576
ec4ed21db4b2 match: split up _normalizepats
Matt Mackall <mpm@selenic.com>
parents: 8575
diff changeset
1185 r.append('.')
31033
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
1186 return r, d
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
1187
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
1188 def _roots(kindpats):
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
1189 '''Returns root directories to match recursively from the given patterns.'''
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
1190 roots, dirs = _patternrootsanddirs(kindpats)
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
1191 return roots
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
1192
38992
5a7df82de142 includematcher: separate "parents" from "dirs"
spectral <spectral@google.com>
parents: 38750
diff changeset
1193 def _rootsdirsandparents(kindpats):
31033
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
1194 '''Returns roots and exact directories from patterns.
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
1195
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
1196 roots are directories to match recursively, whereas exact directories should
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
1197 be matched non-recursively. The returned (roots, dirs) tuple will also
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
1198 include directories that need to be implicitly considered as either, such as
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
1199 parent directories.
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
1200
38992
5a7df82de142 includematcher: separate "parents" from "dirs"
spectral <spectral@google.com>
parents: 38750
diff changeset
1201 >>> _rootsdirsandparents(
34146
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33710
diff changeset
1202 ... [(b'glob', b'g/h/*', b''), (b'glob', b'g/h', b''),
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33710
diff changeset
1203 ... (b'glob', b'g*', b'')])
38992
5a7df82de142 includematcher: separate "parents" from "dirs"
spectral <spectral@google.com>
parents: 38750
diff changeset
1204 (['g/h', 'g/h', '.'], [], ['g', '.'])
5a7df82de142 includematcher: separate "parents" from "dirs"
spectral <spectral@google.com>
parents: 38750
diff changeset
1205 >>> _rootsdirsandparents(
34146
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33710
diff changeset
1206 ... [(b'rootfilesin', b'g/h', b''), (b'rootfilesin', b'', b'')])
38992
5a7df82de142 includematcher: separate "parents" from "dirs"
spectral <spectral@google.com>
parents: 38750
diff changeset
1207 ([], ['g/h', '.'], ['g', '.'])
5a7df82de142 includematcher: separate "parents" from "dirs"
spectral <spectral@google.com>
parents: 38750
diff changeset
1208 >>> _rootsdirsandparents(
34146
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33710
diff changeset
1209 ... [(b'relpath', b'r', b''), (b'path', b'p/p', b''),
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33710
diff changeset
1210 ... (b'path', b'', b'')])
38992
5a7df82de142 includematcher: separate "parents" from "dirs"
spectral <spectral@google.com>
parents: 38750
diff changeset
1211 (['r', 'p/p', '.'], [], ['p', '.'])
5a7df82de142 includematcher: separate "parents" from "dirs"
spectral <spectral@google.com>
parents: 38750
diff changeset
1212 >>> _rootsdirsandparents(
34146
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33710
diff changeset
1213 ... [(b'relglob', b'rg*', b''), (b're', b're/', b''),
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33710
diff changeset
1214 ... (b'relre', b'rr', b'')])
38992
5a7df82de142 includematcher: separate "parents" from "dirs"
spectral <spectral@google.com>
parents: 38750
diff changeset
1215 (['.', '.', '.'], [], ['.'])
31033
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
1216 '''
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
1217 r, d = _patternrootsanddirs(kindpats)
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
1218
38992
5a7df82de142 includematcher: separate "parents" from "dirs"
spectral <spectral@google.com>
parents: 38750
diff changeset
1219 p = []
31033
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
1220 # Append the parents as non-recursive/exact directories, since they must be
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
1221 # scanned to get to either the roots or the other exact directories.
38992
5a7df82de142 includematcher: separate "parents" from "dirs"
spectral <spectral@google.com>
parents: 38750
diff changeset
1222 p.extend(util.dirs(d))
5a7df82de142 includematcher: separate "parents" from "dirs"
spectral <spectral@google.com>
parents: 38750
diff changeset
1223 p.extend(util.dirs(r))
32225
cf042543afa2 match: optimize visitdir() for patterns matching only root directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 32185
diff changeset
1224 # util.dirs() does not include the root directory, so add it manually
38992
5a7df82de142 includematcher: separate "parents" from "dirs"
spectral <spectral@google.com>
parents: 38750
diff changeset
1225 p.append('.')
31033
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
1226
38992
5a7df82de142 includematcher: separate "parents" from "dirs"
spectral <spectral@google.com>
parents: 38750
diff changeset
1227 return r, d, p
8576
ec4ed21db4b2 match: split up _normalizepats
Matt Mackall <mpm@selenic.com>
parents: 8575
diff changeset
1228
31032
88358446da16 match: adding support for matching files inside a directory
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 30409
diff changeset
1229 def _explicitfiles(kindpats):
88358446da16 match: adding support for matching files inside a directory
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 30409
diff changeset
1230 '''Returns the potential explicit filenames from the patterns.
88358446da16 match: adding support for matching files inside a directory
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 30409
diff changeset
1231
34146
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33710
diff changeset
1232 >>> _explicitfiles([(b'path', b'foo/bar', b'')])
31032
88358446da16 match: adding support for matching files inside a directory
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 30409
diff changeset
1233 ['foo/bar']
34146
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33710
diff changeset
1234 >>> _explicitfiles([(b'rootfilesin', b'foo/bar', b'')])
31032
88358446da16 match: adding support for matching files inside a directory
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 30409
diff changeset
1235 []
88358446da16 match: adding support for matching files inside a directory
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 30409
diff changeset
1236 '''
88358446da16 match: adding support for matching files inside a directory
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 30409
diff changeset
1237 # Keep only the pattern kinds where one can specify filenames (vs only
88358446da16 match: adding support for matching files inside a directory
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 30409
diff changeset
1238 # directory names).
88358446da16 match: adding support for matching files inside a directory
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 30409
diff changeset
1239 filable = [kp for kp in kindpats if kp[0] not in ('rootfilesin',)]
88358446da16 match: adding support for matching files inside a directory
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 30409
diff changeset
1240 return _roots(filable)
88358446da16 match: adding support for matching files inside a directory
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 30409
diff changeset
1241
33405
6aa643762641 match: inverse _anypats(), making it _prefix()
Martin von Zweigbergk <martinvonz@google.com>
parents: 33380
diff changeset
1242 def _prefix(kindpats):
6aa643762641 match: inverse _anypats(), making it _prefix()
Martin von Zweigbergk <martinvonz@google.com>
parents: 33380
diff changeset
1243 '''Whether all the patterns match a prefix (i.e. recursively)'''
25213
08a8e9da0ae7 match: add source to kindpats list
Durham Goode <durham@fb.com>
parents: 25195
diff changeset
1244 for kind, pat, source in kindpats:
33405
6aa643762641 match: inverse _anypats(), making it _prefix()
Martin von Zweigbergk <martinvonz@google.com>
parents: 33380
diff changeset
1245 if kind not in ('path', 'relpath'):
6aa643762641 match: inverse _anypats(), making it _prefix()
Martin von Zweigbergk <martinvonz@google.com>
parents: 33380
diff changeset
1246 return False
6aa643762641 match: inverse _anypats(), making it _prefix()
Martin von Zweigbergk <martinvonz@google.com>
parents: 33380
diff changeset
1247 return True
25167
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
1248
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
1249 _commentre = None
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
1250
27595
9e2d01707e71 match: add option to return line and lineno from readpattern
Laurent Charignon <lcharignon@fb.com>
parents: 27343
diff changeset
1251 def readpatternfile(filepath, warn, sourceinfo=False):
25167
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
1252 '''parse a pattern file, returning a list of
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
1253 patterns. These patterns should be given to compile()
25216
dc562165044a ignore: use 'include:' rules instead of custom syntax
Durham Goode <durham@fb.com>
parents: 25215
diff changeset
1254 to be validated and converted into a match function.
dc562165044a ignore: use 'include:' rules instead of custom syntax
Durham Goode <durham@fb.com>
parents: 25215
diff changeset
1255
dc562165044a ignore: use 'include:' rules instead of custom syntax
Durham Goode <durham@fb.com>
parents: 25215
diff changeset
1256 trailing white space is dropped.
dc562165044a ignore: use 'include:' rules instead of custom syntax
Durham Goode <durham@fb.com>
parents: 25215
diff changeset
1257 the escape character is backslash.
dc562165044a ignore: use 'include:' rules instead of custom syntax
Durham Goode <durham@fb.com>
parents: 25215
diff changeset
1258 comments start with #.
dc562165044a ignore: use 'include:' rules instead of custom syntax
Durham Goode <durham@fb.com>
parents: 25215
diff changeset
1259 empty lines are skipped.
dc562165044a ignore: use 'include:' rules instead of custom syntax
Durham Goode <durham@fb.com>
parents: 25215
diff changeset
1260
dc562165044a ignore: use 'include:' rules instead of custom syntax
Durham Goode <durham@fb.com>
parents: 25215
diff changeset
1261 lines can be of the following formats:
dc562165044a ignore: use 'include:' rules instead of custom syntax
Durham Goode <durham@fb.com>
parents: 25215
diff changeset
1262
dc562165044a ignore: use 'include:' rules instead of custom syntax
Durham Goode <durham@fb.com>
parents: 25215
diff changeset
1263 syntax: regexp # defaults following lines to non-rooted regexps
dc562165044a ignore: use 'include:' rules instead of custom syntax
Durham Goode <durham@fb.com>
parents: 25215
diff changeset
1264 syntax: glob # defaults following lines to non-rooted globs
dc562165044a ignore: use 'include:' rules instead of custom syntax
Durham Goode <durham@fb.com>
parents: 25215
diff changeset
1265 re:pattern # non-rooted regular expression
dc562165044a ignore: use 'include:' rules instead of custom syntax
Durham Goode <durham@fb.com>
parents: 25215
diff changeset
1266 glob:pattern # non-rooted glob
27595
9e2d01707e71 match: add option to return line and lineno from readpattern
Laurent Charignon <lcharignon@fb.com>
parents: 27343
diff changeset
1267 pattern # pattern of the current default type
9e2d01707e71 match: add option to return line and lineno from readpattern
Laurent Charignon <lcharignon@fb.com>
parents: 27343
diff changeset
1268
9e2d01707e71 match: add option to return line and lineno from readpattern
Laurent Charignon <lcharignon@fb.com>
parents: 27343
diff changeset
1269 if sourceinfo is set, returns a list of tuples:
9e2d01707e71 match: add option to return line and lineno from readpattern
Laurent Charignon <lcharignon@fb.com>
parents: 27343
diff changeset
1270 (pattern, lineno, originalline). This is useful to debug ignore patterns.
9e2d01707e71 match: add option to return line and lineno from readpattern
Laurent Charignon <lcharignon@fb.com>
parents: 27343
diff changeset
1271 '''
25216
dc562165044a ignore: use 'include:' rules instead of custom syntax
Durham Goode <durham@fb.com>
parents: 25215
diff changeset
1272
25215
4040e06e9b99 match: add 'include:' syntax
Durham Goode <durham@fb.com>
parents: 25214
diff changeset
1273 syntaxes = {'re': 'relre:', 'regexp': 'relre:', 'glob': 'relglob:',
25283
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
1274 'include': 'include', 'subinclude': 'subinclude'}
25167
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
1275 syntax = 'relre:'
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
1276 patterns = []
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
1277
31412
10c17f8bfcf3 py3: open file in rb mode
Rishabh Madan <rishabhmadan96@gmail.com>
parents: 31401
diff changeset
1278 fp = open(filepath, 'rb')
30409
7f3593c29473 match: migrate to util.iterfile
Jun Wu <quark@fb.com>
parents: 29814
diff changeset
1279 for lineno, line in enumerate(util.iterfile(fp), start=1):
25167
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
1280 if "#" in line:
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
1281 global _commentre
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
1282 if not _commentre:
31429
40704098853f match: make regular expression bytes to prevent TypeError
Pulkit Goyal <7895pulkit@gmail.com>
parents: 31412
diff changeset
1283 _commentre = util.re.compile(br'((?:^|[^\\])(?:\\\\)*)#.*')
25167
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
1284 # remove comments prefixed by an even number of escapes
27327
d500341e4f55 match: use re2 in readpatternfile if possible
Bryan O'Sullivan <bos@serpentine.com>
parents: 26781
diff changeset
1285 m = _commentre.search(line)
d500341e4f55 match: use re2 in readpatternfile if possible
Bryan O'Sullivan <bos@serpentine.com>
parents: 26781
diff changeset
1286 if m:
d500341e4f55 match: use re2 in readpatternfile if possible
Bryan O'Sullivan <bos@serpentine.com>
parents: 26781
diff changeset
1287 line = line[:m.end(1)]
25167
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
1288 # fixup properly escaped comments that survived the above
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
1289 line = line.replace("\\#", "#")
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
1290 line = line.rstrip()
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
1291 if not line:
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
1292 continue
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
1293
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
1294 if line.startswith('syntax:'):
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
1295 s = line[7:].strip()
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
1296 try:
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
1297 syntax = syntaxes[s]
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
1298 except KeyError:
25214
08703b10c3ae match: add optional warn argument
Durham Goode <durham@fb.com>
parents: 25213
diff changeset
1299 if warn:
08703b10c3ae match: add optional warn argument
Durham Goode <durham@fb.com>
parents: 25213
diff changeset
1300 warn(_("%s: ignoring invalid syntax '%s'\n") %
08703b10c3ae match: add optional warn argument
Durham Goode <durham@fb.com>
parents: 25213
diff changeset
1301 (filepath, s))
25167
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
1302 continue
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
1303
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
1304 linesyntax = syntax
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
1305 for s, rels in syntaxes.iteritems():
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
1306 if line.startswith(rels):
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
1307 linesyntax = rels
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
1308 line = line[len(rels):]
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
1309 break
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
1310 elif line.startswith(s+':'):
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
1311 linesyntax = rels
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
1312 line = line[len(s) + 1:]
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
1313 break
27595
9e2d01707e71 match: add option to return line and lineno from readpattern
Laurent Charignon <lcharignon@fb.com>
parents: 27343
diff changeset
1314 if sourceinfo:
9e2d01707e71 match: add option to return line and lineno from readpattern
Laurent Charignon <lcharignon@fb.com>
parents: 27343
diff changeset
1315 patterns.append((linesyntax + line, lineno, line))
9e2d01707e71 match: add option to return line and lineno from readpattern
Laurent Charignon <lcharignon@fb.com>
parents: 27343
diff changeset
1316 else:
9e2d01707e71 match: add option to return line and lineno from readpattern
Laurent Charignon <lcharignon@fb.com>
parents: 27343
diff changeset
1317 patterns.append(linesyntax + line)
25167
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
1318 fp.close()
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
1319 return patterns