annotate mercurial/match.py @ 42864:72890d8f9860

match: simplify the regexps created for glob patterns For legibility of the resulting regexes, although it may help with performance as well. Differential Revision: https://phab.mercurial-scm.org/D6764
author Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
date Sun, 25 Aug 2019 22:53:42 -0400
parents e94c8f584ee2
children 2372284d9457
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
34137
a8994d08e4a2 doctest: use print_function and convert bytes to unicode where needed
Yuya Nishihara <yuya@tcha.org>
parents: 34131
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
38955
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
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 (
36050
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,
42452
a3a8887e4426 rust: using policy.importrust from Python callers
Georges Racinet <georges.racinet@octobus.net>
parents: 42367
diff changeset
20 policy,
36572
9adfa48792a7 match: some minimal pycompat fixes guided by test-hgignore.t
Augie Fackler <augie@google.com>
parents: 36050
diff changeset
21 pycompat,
25958
c4ccf2d394a7 match: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25875
diff changeset
22 util,
c4ccf2d394a7 match: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25875
diff changeset
23 )
37084
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36572
diff changeset
24 from .utils import (
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36572
diff changeset
25 stringutil,
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36572
diff changeset
26 )
6576
69f3e9ac7c56 walk: introduce match objects
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
27
42766
e94c8f584ee2 py3: do not convert rust module/attribute names to bytes
Yuya Nishihara <yuya@tcha.org>
parents: 42452
diff changeset
28 rustmod = policy.importrust(r'filepatterns')
42329
c7652f7440d9 rust-filepatterns: call new Rust implementations from Python
Raphaël Gomès <rgomes@octobus.net>
parents: 42195
diff changeset
29
33684
2be0bf186950 match: expose some data and functionality to other modules
Kostia Balytskyi <ikostia@fb.com>
parents: 33582
diff changeset
30 allpatternkinds = ('re', 'glob', 'path', 'relglob', 'relpath', 'relre',
41282
4fab8a7d2d72 match: support rooted globs in hgignore
Valentin Gatien-Baron <vgatien-baron@janestreet.com>
parents: 41129
diff changeset
31 'rootglob',
33684
2be0bf186950 match: expose some data and functionality to other modules
Kostia Balytskyi <ikostia@fb.com>
parents: 33582
diff changeset
32 'listfile', 'listfile0', 'set', 'include', 'subinclude',
2be0bf186950 match: expose some data and functionality to other modules
Kostia Balytskyi <ikostia@fb.com>
parents: 33582
diff changeset
33 'rootfilesin')
2be0bf186950 match: expose some data and functionality to other modules
Kostia Balytskyi <ikostia@fb.com>
parents: 33582
diff changeset
34 cwdrelativepatternkinds = ('relpath', 'glob')
2be0bf186950 match: expose some data and functionality to other modules
Kostia Balytskyi <ikostia@fb.com>
parents: 33582
diff changeset
35
24636
36872036169b treemanifest: further optimize treemanifest.matches()
Drew Gottlieb <drgott@google.com>
parents: 24452
diff changeset
36 propertycache = util.propertycache
36872036169b treemanifest: further optimize treemanifest.matches()
Drew Gottlieb <drgott@google.com>
parents: 24452
diff changeset
37
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
38 def _rematcher(regex):
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
39 '''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
40 matcher function'''
21909
335bb8b80443 match: use util.re.compile instead of util.compilere
Siddharth Agarwal <sid0@fb.com>
parents: 21815
diff changeset
41 m = util.re.compile(regex)
16943
8d08a28aa63e matcher: use re2 bindings if available
Bryan O'Sullivan <bryano@fb.com>
parents: 16791
diff changeset
42 try:
8d08a28aa63e matcher: use re2 bindings if available
Bryan O'Sullivan <bryano@fb.com>
parents: 16791
diff changeset
43 # 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
44 return m.test_match
8d08a28aa63e matcher: use re2 bindings if available
Bryan O'Sullivan <bryano@fb.com>
parents: 16791
diff changeset
45 except AttributeError:
8d08a28aa63e matcher: use re2 bindings if available
Bryan O'Sullivan <bryano@fb.com>
parents: 16791
diff changeset
46 return m.match
8d08a28aa63e matcher: use re2 bindings if available
Bryan O'Sullivan <bryano@fb.com>
parents: 16791
diff changeset
47
42086
1721b92f2b5e match: make arguments of _expandsets() optional
Denis Laxalde <denis@laxalde.org>
parents: 42085
diff changeset
48 def _expandsets(kindpats, ctx=None, listsubrepos=False, badfn=None):
38612
760cc5dc01e8 fileset: restrict getfileset() to not return a computed set (API)
Yuya Nishihara <yuya@tcha.org>
parents: 38611
diff changeset
49 '''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: 38611
diff changeset
50 matchers = []
14675
cfc89398f710 match: introduce basic fileset support
Matt Mackall <mpm@selenic.com>
parents: 14674
diff changeset
51 other = []
cfc89398f710 match: introduce basic fileset support
Matt Mackall <mpm@selenic.com>
parents: 14674
diff changeset
52
25213
08a8e9da0ae7 match: add source to kindpats list
Durham Goode <durham@fb.com>
parents: 25195
diff changeset
53 for kind, pat, source in kindpats:
14675
cfc89398f710 match: introduce basic fileset support
Matt Mackall <mpm@selenic.com>
parents: 14674
diff changeset
54 if kind == 'set':
41022
481249481392 match: fix assertion for fileset with no context (issue6046)
Yuya Nishihara <yuya@tcha.org>
parents: 40345
diff changeset
55 if ctx is None:
32444
57d6c0c74b1b match: use ProgrammingError where appropriate
Martin von Zweigbergk <martinvonz@google.com>
parents: 32415
diff changeset
56 raise error.ProgrammingError("fileset expression with no "
57d6c0c74b1b match: use ProgrammingError where appropriate
Martin von Zweigbergk <martinvonz@google.com>
parents: 32415
diff changeset
57 "context")
38612
760cc5dc01e8 fileset: restrict getfileset() to not return a computed set (API)
Yuya Nishihara <yuya@tcha.org>
parents: 38611
diff changeset
58 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
59
755d23a49170 match: resolve filesets in subrepos for commands given the '-S' argument
Matt Harbison <matt_harbison@yahoo.com>
parents: 25114
diff changeset
60 if listsubrepos:
755d23a49170 match: resolve filesets in subrepos for commands given the '-S' argument
Matt Harbison <matt_harbison@yahoo.com>
parents: 25114
diff changeset
61 for subpath in ctx.substate:
38612
760cc5dc01e8 fileset: restrict getfileset() to not return a computed set (API)
Yuya Nishihara <yuya@tcha.org>
parents: 38611
diff changeset
62 sm = ctx.sub(subpath).matchfileset(pat, badfn=badfn)
41675
ddbebce94665 match: delete unused root and cwd arguments to constructors (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 41672
diff changeset
63 pm = prefixdirmatcher(subpath, sm, badfn=badfn)
38612
760cc5dc01e8 fileset: restrict getfileset() to not return a computed set (API)
Yuya Nishihara <yuya@tcha.org>
parents: 38611
diff changeset
64 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
65
14675
cfc89398f710 match: introduce basic fileset support
Matt Mackall <mpm@selenic.com>
parents: 14674
diff changeset
66 continue
25213
08a8e9da0ae7 match: add source to kindpats list
Durham Goode <durham@fb.com>
parents: 25195
diff changeset
67 other.append((kind, pat, source))
38612
760cc5dc01e8 fileset: restrict getfileset() to not return a computed set (API)
Yuya Nishihara <yuya@tcha.org>
parents: 38611
diff changeset
68 return matchers, other
14675
cfc89398f710 match: introduce basic fileset support
Matt Mackall <mpm@selenic.com>
parents: 14674
diff changeset
69
25283
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
70 def _expandsubinclude(kindpats, root):
32132
6dea1701f170 match: make subinclude construction lazy
Durham Goode <durham@fb.com>
parents: 31433
diff changeset
71 '''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
72 subincludes in it.'''
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
73 relmatchers = []
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
74 other = []
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
75
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
76 for kind, pat, source in kindpats:
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
77 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
78 sourceroot = pathutil.dirname(util.normpath(source))
25283
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
79 pat = util.pconvert(pat)
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
80 path = pathutil.join(sourceroot, pat)
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
81
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
82 newroot = pathutil.dirname(path)
32132
6dea1701f170 match: make subinclude construction lazy
Durham Goode <durham@fb.com>
parents: 31433
diff changeset
83 matcherargs = (newroot, '', [], ['include:%s' % path])
25283
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
84
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
85 prefix = pathutil.canonpath(root, root, newroot)
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
86 if prefix:
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
87 prefix += '/'
32132
6dea1701f170 match: make subinclude construction lazy
Durham Goode <durham@fb.com>
parents: 31433
diff changeset
88 relmatchers.append((prefix, matcherargs))
25283
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
89 else:
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
90 other.append((kind, pat, source))
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
91
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
92 return relmatchers, other
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
93
24447
d44d53bc9a1e matcher: make e.g. 'relpath:.' lead to fast paths
Martin von Zweigbergk <martinvonz@google.com>
parents: 23686
diff changeset
94 def _kindpatsalwaysmatch(kindpats):
d44d53bc9a1e matcher: make e.g. 'relpath:.' lead to fast paths
Martin von Zweigbergk <martinvonz@google.com>
parents: 23686
diff changeset
95 """"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
96 'relpath:.' does.
d44d53bc9a1e matcher: make e.g. 'relpath:.' lead to fast paths
Martin von Zweigbergk <martinvonz@google.com>
parents: 23686
diff changeset
97 """
25213
08a8e9da0ae7 match: add source to kindpats list
Durham Goode <durham@fb.com>
parents: 25195
diff changeset
98 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
99 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
100 return False
d44d53bc9a1e matcher: make e.g. 'relpath:.' lead to fast paths
Martin von Zweigbergk <martinvonz@google.com>
parents: 23686
diff changeset
101 return True
d44d53bc9a1e matcher: make e.g. 'relpath:.' lead to fast paths
Martin von Zweigbergk <martinvonz@google.com>
parents: 23686
diff changeset
102
41675
ddbebce94665 match: delete unused root and cwd arguments to constructors (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 41672
diff changeset
103 def _buildkindpatsmatcher(matchercls, root, kindpats, ctx=None,
38580
9f9ffe5f687c match: compose 'set:' pattern as matcher
Yuya Nishihara <yuya@tcha.org>
parents: 38579
diff changeset
104 listsubrepos=False, badfn=None):
9f9ffe5f687c match: compose 'set:' pattern as matcher
Yuya Nishihara <yuya@tcha.org>
parents: 38579
diff changeset
105 matchers = []
41675
ddbebce94665 match: delete unused root and cwd arguments to constructors (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 41672
diff changeset
106 fms, kindpats = _expandsets(kindpats, ctx=ctx,
38612
760cc5dc01e8 fileset: restrict getfileset() to not return a computed set (API)
Yuya Nishihara <yuya@tcha.org>
parents: 38611
diff changeset
107 listsubrepos=listsubrepos, badfn=badfn)
38580
9f9ffe5f687c match: compose 'set:' pattern as matcher
Yuya Nishihara <yuya@tcha.org>
parents: 38579
diff changeset
108 if kindpats:
41675
ddbebce94665 match: delete unused root and cwd arguments to constructors (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 41672
diff changeset
109 m = matchercls(root, kindpats, badfn=badfn)
38580
9f9ffe5f687c match: compose 'set:' pattern as matcher
Yuya Nishihara <yuya@tcha.org>
parents: 38579
diff changeset
110 matchers.append(m)
38612
760cc5dc01e8 fileset: restrict getfileset() to not return a computed set (API)
Yuya Nishihara <yuya@tcha.org>
parents: 38611
diff changeset
111 if fms:
760cc5dc01e8 fileset: restrict getfileset() to not return a computed set (API)
Yuya Nishihara <yuya@tcha.org>
parents: 38611
diff changeset
112 matchers.extend(fms)
38580
9f9ffe5f687c match: compose 'set:' pattern as matcher
Yuya Nishihara <yuya@tcha.org>
parents: 38579
diff changeset
113 if not matchers:
41675
ddbebce94665 match: delete unused root and cwd arguments to constructors (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 41672
diff changeset
114 return nevermatcher(badfn=badfn)
38580
9f9ffe5f687c match: compose 'set:' pattern as matcher
Yuya Nishihara <yuya@tcha.org>
parents: 38579
diff changeset
115 if len(matchers) == 1:
9f9ffe5f687c match: compose 'set:' pattern as matcher
Yuya Nishihara <yuya@tcha.org>
parents: 38579
diff changeset
116 return matchers[0]
9f9ffe5f687c match: compose 'set:' pattern as matcher
Yuya Nishihara <yuya@tcha.org>
parents: 38579
diff changeset
117 return unionmatcher(matchers)
9f9ffe5f687c match: compose 'set:' pattern as matcher
Yuya Nishihara <yuya@tcha.org>
parents: 38579
diff changeset
118
32728
3e8eb6d84a5c match: allow pats to be None
Martin von Zweigbergk <martinvonz@google.com>
parents: 32650
diff changeset
119 def match(root, cwd, patterns=None, include=None, exclude=None, default='glob',
41622
635a12c53ea6 match: remove unused "exact" argument (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 41528
diff changeset
120 auditor=None, ctx=None, listsubrepos=False, warn=None,
32401
284b18303f61 match: replace icasefsmatch() function by flag to regular match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32400
diff changeset
121 badfn=None, icasefs=False):
42084
42537dfc7a7c match: add doctest examples in match()
Denis Laxalde <denis@laxalde.org>
parents: 42083
diff changeset
122 r"""build an object to match a set of file patterns
32395
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
123
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
124 arguments:
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
125 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: 32325
diff changeset
126 cwd - the current working directory, if relevant
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
127 patterns - patterns to find
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
128 include - patterns to include (unless they are excluded)
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
129 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: 32325
diff changeset
130 default - if a pattern in patterns has no explicit type, assume this one
42083
bee1647578b7 match: complete documentation of match() parameters
Denis Laxalde <denis@laxalde.org>
parents: 42082
diff changeset
131 auditor - optional path auditor
bee1647578b7 match: complete documentation of match() parameters
Denis Laxalde <denis@laxalde.org>
parents: 42082
diff changeset
132 ctx - optional changecontext
bee1647578b7 match: complete documentation of match() parameters
Denis Laxalde <denis@laxalde.org>
parents: 42082
diff changeset
133 listsubrepos - if True, recurse into subrepositories
32395
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
134 warn - optional function used for printing warnings
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
135 badfn - optional bad() callback for this matcher instead of the default
32401
284b18303f61 match: replace icasefsmatch() function by flag to regular match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32400
diff changeset
136 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: 32400
diff changeset
137 normalizes the given patterns to the case in the filesystem
32395
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
138
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
139 a pattern is one of:
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
140 'glob:<glob>' - a glob relative to cwd
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
141 're:<regexp>' - a regular expression
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
142 '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: 32325
diff changeset
143 recursively
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
144 '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: 32325
diff changeset
145 matched non-recursively (will not match subdirectories)
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
146 '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: 32325
diff changeset
147 'relpath:<path>' - a path relative to cwd
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
148 '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: 32325
diff changeset
149 'set:<fileset>' - a fileset expression
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
150 '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: 32325
diff changeset
151 '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: 32325
diff changeset
152 the same directory
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
153 '<something>' - a pattern of the specified default type
42084
42537dfc7a7c match: add doctest examples in match()
Denis Laxalde <denis@laxalde.org>
parents: 42083
diff changeset
154
42537dfc7a7c match: add doctest examples in match()
Denis Laxalde <denis@laxalde.org>
parents: 42083
diff changeset
155 Usually a patternmatcher is returned:
42098
5753e5949b51 py3: add b'' prefixes to new doctests in match.py
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42087
diff changeset
156 >>> match(b'foo', b'.', [b're:.*\.c$', b'path:foo/a', b'*.py'])
42084
42537dfc7a7c match: add doctest examples in match()
Denis Laxalde <denis@laxalde.org>
parents: 42083
diff changeset
157 <patternmatcher patterns='.*\\.c$|foo/a(?:/|$)|[^/]*\\.py$'>
42537dfc7a7c match: add doctest examples in match()
Denis Laxalde <denis@laxalde.org>
parents: 42083
diff changeset
158
42537dfc7a7c match: add doctest examples in match()
Denis Laxalde <denis@laxalde.org>
parents: 42083
diff changeset
159 Combining 'patterns' with 'include' (resp. 'exclude') gives an
42537dfc7a7c match: add doctest examples in match()
Denis Laxalde <denis@laxalde.org>
parents: 42083
diff changeset
160 intersectionmatcher (resp. a differencematcher):
42098
5753e5949b51 py3: add b'' prefixes to new doctests in match.py
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42087
diff changeset
161 >>> type(match(b'foo', b'.', [b're:.*\.c$'], include=[b'path:lib']))
42084
42537dfc7a7c match: add doctest examples in match()
Denis Laxalde <denis@laxalde.org>
parents: 42083
diff changeset
162 <class 'mercurial.match.intersectionmatcher'>
42098
5753e5949b51 py3: add b'' prefixes to new doctests in match.py
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42087
diff changeset
163 >>> type(match(b'foo', b'.', [b're:.*\.c$'], exclude=[b'path:build']))
42084
42537dfc7a7c match: add doctest examples in match()
Denis Laxalde <denis@laxalde.org>
parents: 42083
diff changeset
164 <class 'mercurial.match.differencematcher'>
42537dfc7a7c match: add doctest examples in match()
Denis Laxalde <denis@laxalde.org>
parents: 42083
diff changeset
165
42537dfc7a7c match: add doctest examples in match()
Denis Laxalde <denis@laxalde.org>
parents: 42083
diff changeset
166 Notice that, if 'patterns' is empty, an alwaysmatcher is returned:
42098
5753e5949b51 py3: add b'' prefixes to new doctests in match.py
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42087
diff changeset
167 >>> match(b'foo', b'.', [])
42084
42537dfc7a7c match: add doctest examples in match()
Denis Laxalde <denis@laxalde.org>
parents: 42083
diff changeset
168 <alwaysmatcher>
42537dfc7a7c match: add doctest examples in match()
Denis Laxalde <denis@laxalde.org>
parents: 42083
diff changeset
169
42537dfc7a7c match: add doctest examples in match()
Denis Laxalde <denis@laxalde.org>
parents: 42083
diff changeset
170 The 'default' argument determines which kind of pattern is assumed if a
42537dfc7a7c match: add doctest examples in match()
Denis Laxalde <denis@laxalde.org>
parents: 42083
diff changeset
171 pattern has no prefix:
42098
5753e5949b51 py3: add b'' prefixes to new doctests in match.py
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42087
diff changeset
172 >>> match(b'foo', b'.', [b'.*\.c$'], default=b're')
42084
42537dfc7a7c match: add doctest examples in match()
Denis Laxalde <denis@laxalde.org>
parents: 42083
diff changeset
173 <patternmatcher patterns='.*\\.c$'>
42098
5753e5949b51 py3: add b'' prefixes to new doctests in match.py
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42087
diff changeset
174 >>> match(b'foo', b'.', [b'main.py'], default=b'relpath')
42084
42537dfc7a7c match: add doctest examples in match()
Denis Laxalde <denis@laxalde.org>
parents: 42083
diff changeset
175 <patternmatcher patterns='main\\.py(?:/|$)'>
42098
5753e5949b51 py3: add b'' prefixes to new doctests in match.py
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42087
diff changeset
176 >>> match(b'foo', b'.', [b'main.py'], default=b're')
42084
42537dfc7a7c match: add doctest examples in match()
Denis Laxalde <denis@laxalde.org>
parents: 42083
diff changeset
177 <patternmatcher patterns='main.py'>
42537dfc7a7c match: add doctest examples in match()
Denis Laxalde <denis@laxalde.org>
parents: 42083
diff changeset
178
42537dfc7a7c match: add doctest examples in match()
Denis Laxalde <denis@laxalde.org>
parents: 42083
diff changeset
179 The primary use of matchers is to check whether a value (usually a file
42537dfc7a7c match: add doctest examples in match()
Denis Laxalde <denis@laxalde.org>
parents: 42083
diff changeset
180 name) matches againset one of the patterns given at initialization. There
42537dfc7a7c match: add doctest examples in match()
Denis Laxalde <denis@laxalde.org>
parents: 42083
diff changeset
181 are two ways of doing this check.
42537dfc7a7c match: add doctest examples in match()
Denis Laxalde <denis@laxalde.org>
parents: 42083
diff changeset
182
42098
5753e5949b51 py3: add b'' prefixes to new doctests in match.py
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42087
diff changeset
183 >>> m = match(b'foo', b'', [b're:.*\.c$', b'relpath:a'])
42084
42537dfc7a7c match: add doctest examples in match()
Denis Laxalde <denis@laxalde.org>
parents: 42083
diff changeset
184
42537dfc7a7c match: add doctest examples in match()
Denis Laxalde <denis@laxalde.org>
parents: 42083
diff changeset
185 1. Calling the matcher with a file name returns True if any pattern
42537dfc7a7c match: add doctest examples in match()
Denis Laxalde <denis@laxalde.org>
parents: 42083
diff changeset
186 matches that file name:
42098
5753e5949b51 py3: add b'' prefixes to new doctests in match.py
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42087
diff changeset
187 >>> m(b'a')
42084
42537dfc7a7c match: add doctest examples in match()
Denis Laxalde <denis@laxalde.org>
parents: 42083
diff changeset
188 True
42098
5753e5949b51 py3: add b'' prefixes to new doctests in match.py
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42087
diff changeset
189 >>> m(b'main.c')
42084
42537dfc7a7c match: add doctest examples in match()
Denis Laxalde <denis@laxalde.org>
parents: 42083
diff changeset
190 True
42098
5753e5949b51 py3: add b'' prefixes to new doctests in match.py
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42087
diff changeset
191 >>> m(b'test.py')
42084
42537dfc7a7c match: add doctest examples in match()
Denis Laxalde <denis@laxalde.org>
parents: 42083
diff changeset
192 False
42537dfc7a7c match: add doctest examples in match()
Denis Laxalde <denis@laxalde.org>
parents: 42083
diff changeset
193
42537dfc7a7c match: add doctest examples in match()
Denis Laxalde <denis@laxalde.org>
parents: 42083
diff changeset
194 2. Using the exact() method only returns True if the file name matches one
42537dfc7a7c match: add doctest examples in match()
Denis Laxalde <denis@laxalde.org>
parents: 42083
diff changeset
195 of the exact patterns (i.e. not re: or glob: patterns):
42098
5753e5949b51 py3: add b'' prefixes to new doctests in match.py
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42087
diff changeset
196 >>> m.exact(b'a')
42084
42537dfc7a7c match: add doctest examples in match()
Denis Laxalde <denis@laxalde.org>
parents: 42083
diff changeset
197 True
42098
5753e5949b51 py3: add b'' prefixes to new doctests in match.py
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42087
diff changeset
198 >>> m.exact(b'main.c')
42084
42537dfc7a7c match: add doctest examples in match()
Denis Laxalde <denis@laxalde.org>
parents: 42083
diff changeset
199 False
32395
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
200 """
32401
284b18303f61 match: replace icasefsmatch() function by flag to regular match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32400
diff changeset
201 normalize = _donormalize
284b18303f61 match: replace icasefsmatch() function by flag to regular match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32400
diff changeset
202 if icasefs:
284b18303f61 match: replace icasefsmatch() function by flag to regular match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32400
diff changeset
203 dirstate = ctx.repo().dirstate
284b18303f61 match: replace icasefsmatch() function by flag to regular match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32400
diff changeset
204 dsnormalize = dirstate.normalize
284b18303f61 match: replace icasefsmatch() function by flag to regular match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32400
diff changeset
205
284b18303f61 match: replace icasefsmatch() function by flag to regular match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32400
diff changeset
206 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: 32400
diff changeset
207 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: 32400
diff changeset
208 kindpats = []
284b18303f61 match: replace icasefsmatch() function by flag to regular match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32400
diff changeset
209 for kind, pats, source in kp:
284b18303f61 match: replace icasefsmatch() function by flag to regular match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32400
diff changeset
210 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: 32400
diff changeset
211 p = pats
284b18303f61 match: replace icasefsmatch() function by flag to regular match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32400
diff changeset
212 pats = dsnormalize(pats)
284b18303f61 match: replace icasefsmatch() function by flag to regular match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32400
diff changeset
213
284b18303f61 match: replace icasefsmatch() function by flag to regular match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32400
diff changeset
214 # 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: 32400
diff changeset
215 if p != pats and p in dirstate:
284b18303f61 match: replace icasefsmatch() function by flag to regular match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32400
diff changeset
216 kindpats.append((kind, p, source))
284b18303f61 match: replace icasefsmatch() function by flag to regular match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32400
diff changeset
217
284b18303f61 match: replace icasefsmatch() function by flag to regular match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32400
diff changeset
218 kindpats.append((kind, pats, source))
284b18303f61 match: replace icasefsmatch() function by flag to regular match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32400
diff changeset
219 return kindpats
284b18303f61 match: replace icasefsmatch() function by flag to regular match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32400
diff changeset
220
41622
635a12c53ea6 match: remove unused "exact" argument (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 41528
diff changeset
221 if patterns:
32556
5f08eca8f8d3 match: move normalize() call out of matcher constructors
Martin von Zweigbergk <martinvonz@google.com>
parents: 32555
diff changeset
222 kindpats = normalize(patterns, default, root, cwd, auditor, warn)
32557
3fdcc34c0aba match: remove special-casing of always-matching patterns in patternmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32556
diff changeset
223 if _kindpatsalwaysmatch(kindpats):
41675
ddbebce94665 match: delete unused root and cwd arguments to constructors (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 41672
diff changeset
224 m = alwaysmatcher(badfn)
32557
3fdcc34c0aba match: remove special-casing of always-matching patterns in patternmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32556
diff changeset
225 else:
41675
ddbebce94665 match: delete unused root and cwd arguments to constructors (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 41672
diff changeset
226 m = _buildkindpatsmatcher(patternmatcher, root, kindpats, ctx=ctx,
ddbebce94665 match: delete unused root and cwd arguments to constructors (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 41672
diff changeset
227 listsubrepos=listsubrepos, badfn=badfn)
32553
20c9f3ecc192 match: handle everything-matching using new alwaysmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32552
diff changeset
228 else:
20c9f3ecc192 match: handle everything-matching using new alwaysmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32552
diff changeset
229 # It's a little strange that no patterns means to match everything.
32650
783394c0c978 match: simplify nevermatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32605
diff changeset
230 # Consider changing this to match nothing (probably using nevermatcher).
41675
ddbebce94665 match: delete unused root and cwd arguments to constructors (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 41672
diff changeset
231 m = alwaysmatcher(badfn)
32553
20c9f3ecc192 match: handle everything-matching using new alwaysmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32552
diff changeset
232
32497
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32496
diff changeset
233 if include:
32556
5f08eca8f8d3 match: move normalize() call out of matcher constructors
Martin von Zweigbergk <martinvonz@google.com>
parents: 32555
diff changeset
234 kindpats = normalize(include, 'glob', root, cwd, auditor, warn)
41675
ddbebce94665 match: delete unused root and cwd arguments to constructors (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 41672
diff changeset
235 im = _buildkindpatsmatcher(includematcher, root, kindpats, ctx=ctx,
38580
9f9ffe5f687c match: compose 'set:' pattern as matcher
Yuya Nishihara <yuya@tcha.org>
parents: 38579
diff changeset
236 listsubrepos=listsubrepos, badfn=None)
32497
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32496
diff changeset
237 m = intersectmatchers(m, im)
32465
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32464
diff changeset
238 if exclude:
32556
5f08eca8f8d3 match: move normalize() call out of matcher constructors
Martin von Zweigbergk <martinvonz@google.com>
parents: 32555
diff changeset
239 kindpats = normalize(exclude, 'glob', root, cwd, auditor, warn)
41675
ddbebce94665 match: delete unused root and cwd arguments to constructors (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 41672
diff changeset
240 em = _buildkindpatsmatcher(includematcher, root, kindpats, ctx=ctx,
38580
9f9ffe5f687c match: compose 'set:' pattern as matcher
Yuya Nishihara <yuya@tcha.org>
parents: 38579
diff changeset
241 listsubrepos=listsubrepos, badfn=None)
32465
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32464
diff changeset
242 m = differencematcher(m, em)
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32464
diff changeset
243 return m
32395
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
244
41676
0531dff73d0b match: delete unused root and cwd arguments from {always,never,exact}() (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 41675
diff changeset
245 def exact(files, badfn=None):
41675
ddbebce94665 match: delete unused root and cwd arguments to constructors (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 41672
diff changeset
246 return exactmatcher(files, badfn=badfn)
32395
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
247
41676
0531dff73d0b match: delete unused root and cwd arguments from {always,never,exact}() (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 41675
diff changeset
248 def always(badfn=None):
0531dff73d0b match: delete unused root and cwd arguments from {always,never,exact}() (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 41675
diff changeset
249 return alwaysmatcher(badfn)
32395
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
250
41676
0531dff73d0b match: delete unused root and cwd arguments from {always,never,exact}() (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 41675
diff changeset
251 def never(badfn=None):
0531dff73d0b match: delete unused root and cwd arguments from {always,never,exact}() (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 41675
diff changeset
252 return nevermatcher(badfn)
32605
e6ff007e107e match: introduce nevermatcher for when no ignore files are present
Siddharth Agarwal <sid0@fb.com>
parents: 32557
diff changeset
253
32395
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
254 def badmatch(match, badfn):
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
255 """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: 32325
diff changeset
256 one.
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
257 """
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
258 m = copy.copy(match)
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
259 m.bad = badfn
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
260 return m
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
261
42085
54e6d7ef5ca5 match: make _donormalize's auditor and warn arguments optional
Denis Laxalde <denis@laxalde.org>
parents: 42084
diff changeset
262 def _donormalize(patterns, default, root, cwd, auditor=None, warn=None):
32397
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32396
diff changeset
263 '''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: 32396
diff changeset
264 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: 32396
diff changeset
265 kindpats = []
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32396
diff changeset
266 for kind, pat in [_patsplit(p, default) for p in patterns]:
33684
2be0bf186950 match: expose some data and functionality to other modules
Kostia Balytskyi <ikostia@fb.com>
parents: 33582
diff changeset
267 if kind in cwdrelativepatternkinds:
42085
54e6d7ef5ca5 match: make _donormalize's auditor and warn arguments optional
Denis Laxalde <denis@laxalde.org>
parents: 42084
diff changeset
268 pat = pathutil.canonpath(root, cwd, pat, auditor=auditor)
41282
4fab8a7d2d72 match: support rooted globs in hgignore
Valentin Gatien-Baron <vgatien-baron@janestreet.com>
parents: 41129
diff changeset
269 elif kind in ('relglob', 'path', 'rootfilesin', 'rootglob'):
32397
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32396
diff changeset
270 pat = util.normpath(pat)
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32396
diff changeset
271 elif kind in ('listfile', 'listfile0'):
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32396
diff changeset
272 try:
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32396
diff changeset
273 files = util.readfile(pat)
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32396
diff changeset
274 if kind == 'listfile0':
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32396
diff changeset
275 files = files.split('\0')
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32396
diff changeset
276 else:
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32396
diff changeset
277 files = files.splitlines()
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32396
diff changeset
278 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: 32396
diff changeset
279 except EnvironmentError:
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32396
diff changeset
280 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: 32396
diff changeset
281 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: 32396
diff changeset
282 auditor, warn):
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32396
diff changeset
283 kindpats.append((k, p, pat))
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32396
diff changeset
284 continue
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32396
diff changeset
285 elif kind == 'include':
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32396
diff changeset
286 try:
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32396
diff changeset
287 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: 32396
diff changeset
288 includepats = readpatternfile(fullpath, warn)
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32396
diff changeset
289 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: 32396
diff changeset
290 root, cwd, auditor, warn):
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32396
diff changeset
291 kindpats.append((k, p, source or pat))
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32396
diff changeset
292 except error.Abort as inst:
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32396
diff changeset
293 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: 32396
diff changeset
294 except IOError as inst:
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32396
diff changeset
295 if warn:
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32396
diff changeset
296 warn(_("skipping unreadable pattern file '%s': %s\n") %
37084
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36572
diff changeset
297 (pat, stringutil.forcebytestr(inst.strerror)))
32397
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32396
diff changeset
298 continue
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32396
diff changeset
299 # 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: 32396
diff changeset
300 kindpats.append((kind, pat, ''))
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32396
diff changeset
301 return kindpats
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32396
diff changeset
302
32458
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
303 class basematcher(object):
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
304
41675
ddbebce94665 match: delete unused root and cwd arguments to constructors (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 41672
diff changeset
305 def __init__(self, badfn=None):
32458
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
306 if badfn is not None:
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
307 self.bad = badfn
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
308
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
309 def __call__(self, fn):
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
310 return self.matchfn(fn)
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
311 # 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: 32444
diff changeset
312 # Subscribers to these events must monkeypatch the matcher object.
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
313 def bad(self, f, msg):
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
314 '''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: 32444
diff changeset
315 found/accessed, with an error message.'''
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
316
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
317 # 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: 32444
diff changeset
318 # directory is visited.
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
319 explicitdir = None
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
320
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
321 # 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: 32444
diff changeset
322 # by recursive traversal is visited.
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
323 traversedir = None
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
324
32459
9f781f43f2ce match: make basematcher._files a @propertycache
Martin von Zweigbergk <martinvonz@google.com>
parents: 32458
diff changeset
325 @propertycache
9f781f43f2ce match: make basematcher._files a @propertycache
Martin von Zweigbergk <martinvonz@google.com>
parents: 32458
diff changeset
326 def _files(self):
9f781f43f2ce match: make basematcher._files a @propertycache
Martin von Zweigbergk <martinvonz@google.com>
parents: 32458
diff changeset
327 return []
9f781f43f2ce match: make basematcher._files a @propertycache
Martin von Zweigbergk <martinvonz@google.com>
parents: 32458
diff changeset
328
32458
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
329 def files(self):
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
330 '''Explicitly listed files or patterns or roots:
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
331 if no patterns or .always(): empty list,
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
332 if exact: list exact files,
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
333 if not .anypats(): list all files and dirs,
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
334 else: optimal roots'''
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
335 return self._files
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
336
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
337 @propertycache
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
338 def _fileset(self):
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
339 return set(self._files)
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
340
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
341 def exact(self, f):
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
342 '''Returns True if f is in .files().'''
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
343 return f in self._fileset
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
344
32463
43e091847c4d match: make matchfn a method on the class
Martin von Zweigbergk <martinvonz@google.com>
parents: 32461
diff changeset
345 def matchfn(self, f):
43e091847c4d match: make matchfn a method on the class
Martin von Zweigbergk <martinvonz@google.com>
parents: 32461
diff changeset
346 return False
43e091847c4d match: make matchfn a method on the class
Martin von Zweigbergk <martinvonz@google.com>
parents: 32461
diff changeset
347
32458
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
348 def visitdir(self, dir):
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
349 '''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: 32444
diff changeset
350 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: 32444
diff changeset
351 based on the match's primary, included, and excluded patterns.
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
352
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
353 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: 32444
diff changeset
354 should be visited. Otherwise returns True or False indicating whether
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
355 the given directory should be visited.
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
356 '''
33478
cf15c3cc304c match: make base matcher return True for visitdir
Durham Goode <durham@fb.com>
parents: 33448
diff changeset
357 return True
32458
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
358
38955
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
359 def visitchildrenset(self, dir):
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
360 '''Decides whether a directory should be visited based on whether it
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
361 has potential matches in it or one of its subdirectories, and
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
362 potentially lists which subdirectories of that directory should be
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
363 visited. This is based on the match's primary, included, and excluded
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
364 patterns.
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
365
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
366 This function is very similar to 'visitdir', and the following mapping
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
367 can be applied:
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
368
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
369 visitdir | visitchildrenlist
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
370 ----------+-------------------
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
371 False | set()
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
372 'all' | 'all'
39260
27946fca8a05 match: document that visitchildrenset might return files
Kyle Lippincott <spectral@google.com>
parents: 38958
diff changeset
373 True | 'this' OR non-empty set of subdirs -or files- to visit
38955
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
374
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
375 Example:
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
376 Assume matchers ['path:foo/bar', 'rootfilesin:qux'], we would return
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
377 the following values (assuming the implementation of visitchildrenset
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
378 is capable of recognizing this; some implementations are not).
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
379
42341
27d6956d386b match: use '' instead of '.' for root directory (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 42329
diff changeset
380 '' -> {'foo', 'qux'}
38955
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
381 'baz' -> set()
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
382 'foo' -> {'bar'}
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
383 # Ideally this would be 'all', but since the prefix nature of matchers
39260
27946fca8a05 match: document that visitchildrenset might return files
Kyle Lippincott <spectral@google.com>
parents: 38958
diff changeset
384 # is applied to the entire matcher, we have to downgrade this to
27946fca8a05 match: document that visitchildrenset might return files
Kyle Lippincott <spectral@google.com>
parents: 38958
diff changeset
385 # 'this' due to the non-prefix 'rootfilesin'-kind matcher being mixed
27946fca8a05 match: document that visitchildrenset might return files
Kyle Lippincott <spectral@google.com>
parents: 38958
diff changeset
386 # in.
38955
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
387 'foo/bar' -> 'this'
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
388 'qux' -> 'this'
39260
27946fca8a05 match: document that visitchildrenset might return files
Kyle Lippincott <spectral@google.com>
parents: 38958
diff changeset
389
27946fca8a05 match: document that visitchildrenset might return files
Kyle Lippincott <spectral@google.com>
parents: 38958
diff changeset
390 Important:
27946fca8a05 match: document that visitchildrenset might return files
Kyle Lippincott <spectral@google.com>
parents: 38958
diff changeset
391 Most matchers do not know if they're representing files or
27946fca8a05 match: document that visitchildrenset might return files
Kyle Lippincott <spectral@google.com>
parents: 38958
diff changeset
392 directories. They see ['path:dir/f'] and don't know whether 'f' is a
27946fca8a05 match: document that visitchildrenset might return files
Kyle Lippincott <spectral@google.com>
parents: 38958
diff changeset
393 file or a directory, so visitchildrenset('dir') for most matchers will
27946fca8a05 match: document that visitchildrenset might return files
Kyle Lippincott <spectral@google.com>
parents: 38958
diff changeset
394 return {'f'}, but if the matcher knows it's a file (like exactmatcher
27946fca8a05 match: document that visitchildrenset might return files
Kyle Lippincott <spectral@google.com>
parents: 38958
diff changeset
395 does), it may return 'this'. Do not rely on the return being a set
27946fca8a05 match: document that visitchildrenset might return files
Kyle Lippincott <spectral@google.com>
parents: 38958
diff changeset
396 indicating that there are no files in this dir to investigate (or
27946fca8a05 match: document that visitchildrenset might return files
Kyle Lippincott <spectral@google.com>
parents: 38958
diff changeset
397 equivalently that if there are files to investigate in 'dir' that it
27946fca8a05 match: document that visitchildrenset might return files
Kyle Lippincott <spectral@google.com>
parents: 38958
diff changeset
398 will always return 'this').
38955
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
399 '''
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
400 return 'this'
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
401
32458
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
402 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
403 '''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
404 optimization might be possible.'''
32458
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
405 return False
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
406
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
407 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
408 '''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
409 optimization might be possible.'''
32458
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
410 return False
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
411
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
412 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
413 '''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
414 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
415 return False
7ddb2aa2b7af match: express anypats(), not prefix(), in terms of the others
Martin von Zweigbergk <martinvonz@google.com>
parents: 33378
diff changeset
416
7ddb2aa2b7af match: express anypats(), not prefix(), in terms of the others
Martin von Zweigbergk <martinvonz@google.com>
parents: 33378
diff changeset
417 def anypats(self):
7ddb2aa2b7af match: express anypats(), not prefix(), in terms of the others
Martin von Zweigbergk <martinvonz@google.com>
parents: 33378
diff changeset
418 '''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
419 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
420 return not self.always() and not self.isexact() and not self.prefix()
32458
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
421
32553
20c9f3ecc192 match: handle everything-matching using new alwaysmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32552
diff changeset
422 class alwaysmatcher(basematcher):
20c9f3ecc192 match: handle everything-matching using new alwaysmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32552
diff changeset
423 '''Matches everything.'''
20c9f3ecc192 match: handle everything-matching using new alwaysmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32552
diff changeset
424
41675
ddbebce94665 match: delete unused root and cwd arguments to constructors (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 41672
diff changeset
425 def __init__(self, badfn=None):
ddbebce94665 match: delete unused root and cwd arguments to constructors (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 41672
diff changeset
426 super(alwaysmatcher, self).__init__(badfn)
32553
20c9f3ecc192 match: handle everything-matching using new alwaysmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32552
diff changeset
427
20c9f3ecc192 match: handle everything-matching using new alwaysmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32552
diff changeset
428 def always(self):
20c9f3ecc192 match: handle everything-matching using new alwaysmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32552
diff changeset
429 return True
20c9f3ecc192 match: handle everything-matching using new alwaysmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32552
diff changeset
430
20c9f3ecc192 match: handle everything-matching using new alwaysmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32552
diff changeset
431 def matchfn(self, f):
20c9f3ecc192 match: handle everything-matching using new alwaysmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32552
diff changeset
432 return True
20c9f3ecc192 match: handle everything-matching using new alwaysmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32552
diff changeset
433
20c9f3ecc192 match: handle everything-matching using new alwaysmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32552
diff changeset
434 def visitdir(self, dir):
20c9f3ecc192 match: handle everything-matching using new alwaysmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32552
diff changeset
435 return 'all'
20c9f3ecc192 match: handle everything-matching using new alwaysmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32552
diff changeset
436
38955
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
437 def visitchildrenset(self, dir):
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
438 return 'all'
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
439
32553
20c9f3ecc192 match: handle everything-matching using new alwaysmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32552
diff changeset
440 def __repr__(self):
36050
c4fa47f880d3 py3: make sure we return str from __repr__
Pulkit Goyal <7895pulkit@gmail.com>
parents: 35659
diff changeset
441 return r'<alwaysmatcher>'
32553
20c9f3ecc192 match: handle everything-matching using new alwaysmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32552
diff changeset
442
32605
e6ff007e107e match: introduce nevermatcher for when no ignore files are present
Siddharth Agarwal <sid0@fb.com>
parents: 32557
diff changeset
443 class nevermatcher(basematcher):
e6ff007e107e match: introduce nevermatcher for when no ignore files are present
Siddharth Agarwal <sid0@fb.com>
parents: 32557
diff changeset
444 '''Matches nothing.'''
e6ff007e107e match: introduce nevermatcher for when no ignore files are present
Siddharth Agarwal <sid0@fb.com>
parents: 32557
diff changeset
445
41675
ddbebce94665 match: delete unused root and cwd arguments to constructors (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 41672
diff changeset
446 def __init__(self, badfn=None):
ddbebce94665 match: delete unused root and cwd arguments to constructors (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 41672
diff changeset
447 super(nevermatcher, self).__init__(badfn)
32605
e6ff007e107e match: introduce nevermatcher for when no ignore files are present
Siddharth Agarwal <sid0@fb.com>
parents: 32557
diff changeset
448
33378
adf95bfb423a match: make nevermatcher an exact matcher and a prefix matcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 33358
diff changeset
449 # 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
450 # 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
451 # 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
452 # 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
453 # 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
454 def isexact(self):
adf95bfb423a match: make nevermatcher an exact matcher and a prefix matcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 33358
diff changeset
455 return True
adf95bfb423a match: make nevermatcher an exact matcher and a prefix matcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 33358
diff changeset
456
adf95bfb423a match: make nevermatcher an exact matcher and a prefix matcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 33358
diff changeset
457 def prefix(self):
adf95bfb423a match: make nevermatcher an exact matcher and a prefix matcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 33358
diff changeset
458 return True
adf95bfb423a match: make nevermatcher an exact matcher and a prefix matcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 33358
diff changeset
459
33582
44bc181b9835 match: override visitdir() in nevermatcher to return False
Martin von Zweigbergk <martinvonz@google.com>
parents: 33497
diff changeset
460 def visitdir(self, dir):
44bc181b9835 match: override visitdir() in nevermatcher to return False
Martin von Zweigbergk <martinvonz@google.com>
parents: 33497
diff changeset
461 return False
44bc181b9835 match: override visitdir() in nevermatcher to return False
Martin von Zweigbergk <martinvonz@google.com>
parents: 33497
diff changeset
462
38955
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
463 def visitchildrenset(self, dir):
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
464 return set()
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
465
32605
e6ff007e107e match: introduce nevermatcher for when no ignore files are present
Siddharth Agarwal <sid0@fb.com>
parents: 32557
diff changeset
466 def __repr__(self):
36050
c4fa47f880d3 py3: make sure we return str from __repr__
Pulkit Goyal <7895pulkit@gmail.com>
parents: 35659
diff changeset
467 return r'<nevermatcher>'
32605
e6ff007e107e match: introduce nevermatcher for when no ignore files are present
Siddharth Agarwal <sid0@fb.com>
parents: 32557
diff changeset
468
38577
76838305b9dd match: add basic wrapper for boolean function
Yuya Nishihara <yuya@tcha.org>
parents: 38475
diff changeset
469 class predicatematcher(basematcher):
76838305b9dd match: add basic wrapper for boolean function
Yuya Nishihara <yuya@tcha.org>
parents: 38475
diff changeset
470 """A matcher adapter for a simple boolean function"""
76838305b9dd match: add basic wrapper for boolean function
Yuya Nishihara <yuya@tcha.org>
parents: 38475
diff changeset
471
41675
ddbebce94665 match: delete unused root and cwd arguments to constructors (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 41672
diff changeset
472 def __init__(self, predfn, predrepr=None, badfn=None):
ddbebce94665 match: delete unused root and cwd arguments to constructors (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 41672
diff changeset
473 super(predicatematcher, self).__init__(badfn)
38577
76838305b9dd match: add basic wrapper for boolean function
Yuya Nishihara <yuya@tcha.org>
parents: 38475
diff changeset
474 self.matchfn = predfn
76838305b9dd match: add basic wrapper for boolean function
Yuya Nishihara <yuya@tcha.org>
parents: 38475
diff changeset
475 self._predrepr = predrepr
76838305b9dd match: add basic wrapper for boolean function
Yuya Nishihara <yuya@tcha.org>
parents: 38475
diff changeset
476
76838305b9dd match: add basic wrapper for boolean function
Yuya Nishihara <yuya@tcha.org>
parents: 38475
diff changeset
477 @encoding.strmethod
76838305b9dd match: add basic wrapper for boolean function
Yuya Nishihara <yuya@tcha.org>
parents: 38475
diff changeset
478 def __repr__(self):
76838305b9dd match: add basic wrapper for boolean function
Yuya Nishihara <yuya@tcha.org>
parents: 38475
diff changeset
479 s = (stringutil.buildrepr(self._predrepr)
76838305b9dd match: add basic wrapper for boolean function
Yuya Nishihara <yuya@tcha.org>
parents: 38475
diff changeset
480 or pycompat.byterepr(self.matchfn))
76838305b9dd match: add basic wrapper for boolean function
Yuya Nishihara <yuya@tcha.org>
parents: 38475
diff changeset
481 return '<predicatenmatcher pred=%s>' % s
76838305b9dd match: add basic wrapper for boolean function
Yuya Nishihara <yuya@tcha.org>
parents: 38475
diff changeset
482
42341
27d6956d386b match: use '' instead of '.' for root directory (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 42329
diff changeset
483 def normalizerootdir(dir, funcname):
27d6956d386b match: use '' instead of '.' for root directory (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 42329
diff changeset
484 if dir == '.':
27d6956d386b match: use '' instead of '.' for root directory (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 42329
diff changeset
485 util.nouideprecwarn("match.%s() no longer accepts "
27d6956d386b match: use '' instead of '.' for root directory (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 42329
diff changeset
486 "'.', use '' instead." % funcname, '5.1')
27d6956d386b match: use '' instead of '.' for root directory (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 42329
diff changeset
487 return ''
27d6956d386b match: use '' instead of '.' for root directory (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 42329
diff changeset
488 return dir
27d6956d386b match: use '' instead of '.' for root directory (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 42329
diff changeset
489
27d6956d386b match: use '' instead of '.' for root directory (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 42329
diff changeset
490
32501
7095dbc266e3 match: split up main matcher into patternmatcher and includematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32500
diff changeset
491 class patternmatcher(basematcher):
42081
bf777c1e78dd match: add a docstring with doctest examples to patternmatcher
Denis Laxalde <denis@laxalde.org>
parents: 42080
diff changeset
492 """Matches a set of (kind, pat, source) against a 'root' directory.
bf777c1e78dd match: add a docstring with doctest examples to patternmatcher
Denis Laxalde <denis@laxalde.org>
parents: 42080
diff changeset
493
bf777c1e78dd match: add a docstring with doctest examples to patternmatcher
Denis Laxalde <denis@laxalde.org>
parents: 42080
diff changeset
494 >>> kindpats = [
42186
fd384911f51b match: use raw strings to avoid illegal baskslash escape
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42099
diff changeset
495 ... (b're', br'.*\.c$', b''),
42098
5753e5949b51 py3: add b'' prefixes to new doctests in match.py
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42087
diff changeset
496 ... (b'path', b'foo/a', b''),
5753e5949b51 py3: add b'' prefixes to new doctests in match.py
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42087
diff changeset
497 ... (b'relpath', b'b', b''),
5753e5949b51 py3: add b'' prefixes to new doctests in match.py
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42087
diff changeset
498 ... (b'glob', b'*.h', b''),
42081
bf777c1e78dd match: add a docstring with doctest examples to patternmatcher
Denis Laxalde <denis@laxalde.org>
parents: 42080
diff changeset
499 ... ]
42098
5753e5949b51 py3: add b'' prefixes to new doctests in match.py
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42087
diff changeset
500 >>> m = patternmatcher(b'foo', kindpats)
5753e5949b51 py3: add b'' prefixes to new doctests in match.py
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42087
diff changeset
501 >>> m(b'main.c') # matches re:.*\.c$
42081
bf777c1e78dd match: add a docstring with doctest examples to patternmatcher
Denis Laxalde <denis@laxalde.org>
parents: 42080
diff changeset
502 True
42098
5753e5949b51 py3: add b'' prefixes to new doctests in match.py
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42087
diff changeset
503 >>> m(b'b.txt')
42081
bf777c1e78dd match: add a docstring with doctest examples to patternmatcher
Denis Laxalde <denis@laxalde.org>
parents: 42080
diff changeset
504 False
42098
5753e5949b51 py3: add b'' prefixes to new doctests in match.py
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42087
diff changeset
505 >>> m(b'foo/a') # matches path:foo/a
42081
bf777c1e78dd match: add a docstring with doctest examples to patternmatcher
Denis Laxalde <denis@laxalde.org>
parents: 42080
diff changeset
506 True
42098
5753e5949b51 py3: add b'' prefixes to new doctests in match.py
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42087
diff changeset
507 >>> m(b'a') # does not match path:b, since 'root' is 'foo'
42081
bf777c1e78dd match: add a docstring with doctest examples to patternmatcher
Denis Laxalde <denis@laxalde.org>
parents: 42080
diff changeset
508 False
42098
5753e5949b51 py3: add b'' prefixes to new doctests in match.py
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42087
diff changeset
509 >>> m(b'b') # matches relpath:b, since 'root' is 'foo'
42081
bf777c1e78dd match: add a docstring with doctest examples to patternmatcher
Denis Laxalde <denis@laxalde.org>
parents: 42080
diff changeset
510 True
42098
5753e5949b51 py3: add b'' prefixes to new doctests in match.py
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42087
diff changeset
511 >>> m(b'lib.h') # matches glob:*.h
42081
bf777c1e78dd match: add a docstring with doctest examples to patternmatcher
Denis Laxalde <denis@laxalde.org>
parents: 42080
diff changeset
512 True
bf777c1e78dd match: add a docstring with doctest examples to patternmatcher
Denis Laxalde <denis@laxalde.org>
parents: 42080
diff changeset
513
bf777c1e78dd match: add a docstring with doctest examples to patternmatcher
Denis Laxalde <denis@laxalde.org>
parents: 42080
diff changeset
514 >>> m.files()
42341
27d6956d386b match: use '' instead of '.' for root directory (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 42329
diff changeset
515 ['', 'foo/a', 'b', '']
42098
5753e5949b51 py3: add b'' prefixes to new doctests in match.py
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42087
diff changeset
516 >>> m.exact(b'foo/a')
42081
bf777c1e78dd match: add a docstring with doctest examples to patternmatcher
Denis Laxalde <denis@laxalde.org>
parents: 42080
diff changeset
517 True
42098
5753e5949b51 py3: add b'' prefixes to new doctests in match.py
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42087
diff changeset
518 >>> m.exact(b'b')
42081
bf777c1e78dd match: add a docstring with doctest examples to patternmatcher
Denis Laxalde <denis@laxalde.org>
parents: 42080
diff changeset
519 True
42098
5753e5949b51 py3: add b'' prefixes to new doctests in match.py
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42087
diff changeset
520 >>> m.exact(b'lib.h') # exact matches are for (rel)path kinds
42081
bf777c1e78dd match: add a docstring with doctest examples to patternmatcher
Denis Laxalde <denis@laxalde.org>
parents: 42080
diff changeset
521 False
bf777c1e78dd match: add a docstring with doctest examples to patternmatcher
Denis Laxalde <denis@laxalde.org>
parents: 42080
diff changeset
522 """
32395
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
523
41675
ddbebce94665 match: delete unused root and cwd arguments to constructors (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 41672
diff changeset
524 def __init__(self, root, kindpats, badfn=None):
ddbebce94665 match: delete unused root and cwd arguments to constructors (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 41672
diff changeset
525 super(patternmatcher, self).__init__(badfn)
8581
101d305c1d0b match: fold _matcher into match.__init__
Matt Mackall <mpm@selenic.com>
parents: 8580
diff changeset
526
32557
3fdcc34c0aba match: remove special-casing of always-matching patterns in patternmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32556
diff changeset
527 self._files = _explicitfiles(kindpats)
33405
6aa643762641 match: inverse _anypats(), making it _prefix()
Martin von Zweigbergk <martinvonz@google.com>
parents: 33380
diff changeset
528 self._prefix = _prefix(kindpats)
41669
a13268524c25 match: delete unused argument "listsubrepos" from _buildmatch()
Martin von Zweigbergk <martinvonz@google.com>
parents: 41668
diff changeset
529 self._pats, self.matchfn = _buildmatch(kindpats, '$', root)
8587
8f15d54437b9 match: fold match into _match base class
Matt Mackall <mpm@selenic.com>
parents: 8586
diff changeset
530
32322
23c9a2a71c6e match: make _fileroots a @propertycache and rename it to _fileset
Martin von Zweigbergk <martinvonz@google.com>
parents: 32312
diff changeset
531 @propertycache
24636
36872036169b treemanifest: further optimize treemanifest.matches()
Drew Gottlieb <drgott@google.com>
parents: 24452
diff changeset
532 def _dirs(self):
42346
38d85ec06552 match: drop unnecessary adding of '' to set of dirs
Martin von Zweigbergk <martinvonz@google.com>
parents: 42343
diff changeset
533 return set(util.dirs(self._fileset))
24636
36872036169b treemanifest: further optimize treemanifest.matches()
Drew Gottlieb <drgott@google.com>
parents: 24452
diff changeset
534
36872036169b treemanifest: further optimize treemanifest.matches()
Drew Gottlieb <drgott@google.com>
parents: 24452
diff changeset
535 def visitdir(self, dir):
42341
27d6956d386b match: use '' instead of '.' for root directory (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 42329
diff changeset
536 dir = normalizerootdir(dir, 'visitdir')
33405
6aa643762641 match: inverse _anypats(), making it _prefix()
Martin von Zweigbergk <martinvonz@google.com>
parents: 33380
diff changeset
537 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
538 return 'all'
42343
d8e55c0c642c util: make util.dirs() and util.finddirs() include root directory (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 42341
diff changeset
539 return (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
540 dir in self._dirs or
32322
23c9a2a71c6e match: make _fileroots a @propertycache and rename it to _fileset
Martin von Zweigbergk <martinvonz@google.com>
parents: 32312
diff changeset
541 any(parentdir in self._fileset
25577
a410479c7ee7 match: drop optimization (?) of 'parentdirs' calculation
Martin von Zweigbergk <martinvonz@google.com>
parents: 25576
diff changeset
542 for parentdir in util.finddirs(dir)))
24636
36872036169b treemanifest: further optimize treemanifest.matches()
Drew Gottlieb <drgott@google.com>
parents: 24452
diff changeset
543
38955
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
544 def visitchildrenset(self, dir):
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
545 ret = self.visitdir(dir)
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
546 if ret is True:
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
547 return 'this'
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
548 elif not ret:
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
549 return set()
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
550 assert ret == 'all'
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
551 return 'all'
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
552
33379
7ddb2aa2b7af match: express anypats(), not prefix(), in terms of the others
Martin von Zweigbergk <martinvonz@google.com>
parents: 33378
diff changeset
553 def prefix(self):
33405
6aa643762641 match: inverse _anypats(), making it _prefix()
Martin von Zweigbergk <martinvonz@google.com>
parents: 33380
diff changeset
554 return self._prefix
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
555
36050
c4fa47f880d3 py3: make sure we return str from __repr__
Pulkit Goyal <7895pulkit@gmail.com>
parents: 35659
diff changeset
556 @encoding.strmethod
32406
952017471f93 match: implement __repr__() and update users (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32401
diff changeset
557 def __repr__(self):
38019
2f406142d7b4 py3: use pycompat.bytestr() on bytes before %r-ing it
Pulkit Goyal <7895pulkit@gmail.com>
parents: 37084
diff changeset
558 return ('<patternmatcher patterns=%r>' % pycompat.bytestr(self._pats))
32501
7095dbc266e3 match: split up main matcher into patternmatcher and includematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32500
diff changeset
559
39460
35ecaa999a12 match: improve includematcher.visitchildrenset to be much faster and cached
Kyle Lippincott <spectral@google.com>
parents: 39261
diff changeset
560 # This is basically a reimplementation of util.dirs that stores the children
35ecaa999a12 match: improve includematcher.visitchildrenset to be much faster and cached
Kyle Lippincott <spectral@google.com>
parents: 39261
diff changeset
561 # instead of just a count of them, plus a small optional optimization to avoid
35ecaa999a12 match: improve includematcher.visitchildrenset to be much faster and cached
Kyle Lippincott <spectral@google.com>
parents: 39261
diff changeset
562 # some directories we don't need.
35ecaa999a12 match: improve includematcher.visitchildrenset to be much faster and cached
Kyle Lippincott <spectral@google.com>
parents: 39261
diff changeset
563 class _dirchildren(object):
35ecaa999a12 match: improve includematcher.visitchildrenset to be much faster and cached
Kyle Lippincott <spectral@google.com>
parents: 39261
diff changeset
564 def __init__(self, paths, onlyinclude=None):
35ecaa999a12 match: improve includematcher.visitchildrenset to be much faster and cached
Kyle Lippincott <spectral@google.com>
parents: 39261
diff changeset
565 self._dirs = {}
35ecaa999a12 match: improve includematcher.visitchildrenset to be much faster and cached
Kyle Lippincott <spectral@google.com>
parents: 39261
diff changeset
566 self._onlyinclude = onlyinclude or []
35ecaa999a12 match: improve includematcher.visitchildrenset to be much faster and cached
Kyle Lippincott <spectral@google.com>
parents: 39261
diff changeset
567 addpath = self.addpath
35ecaa999a12 match: improve includematcher.visitchildrenset to be much faster and cached
Kyle Lippincott <spectral@google.com>
parents: 39261
diff changeset
568 for f in paths:
35ecaa999a12 match: improve includematcher.visitchildrenset to be much faster and cached
Kyle Lippincott <spectral@google.com>
parents: 39261
diff changeset
569 addpath(f)
35ecaa999a12 match: improve includematcher.visitchildrenset to be much faster and cached
Kyle Lippincott <spectral@google.com>
parents: 39261
diff changeset
570
35ecaa999a12 match: improve includematcher.visitchildrenset to be much faster and cached
Kyle Lippincott <spectral@google.com>
parents: 39261
diff changeset
571 def addpath(self, path):
42341
27d6956d386b match: use '' instead of '.' for root directory (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 42329
diff changeset
572 if path == '':
39460
35ecaa999a12 match: improve includematcher.visitchildrenset to be much faster and cached
Kyle Lippincott <spectral@google.com>
parents: 39261
diff changeset
573 return
35ecaa999a12 match: improve includematcher.visitchildrenset to be much faster and cached
Kyle Lippincott <spectral@google.com>
parents: 39261
diff changeset
574 dirs = self._dirs
35ecaa999a12 match: improve includematcher.visitchildrenset to be much faster and cached
Kyle Lippincott <spectral@google.com>
parents: 39261
diff changeset
575 findsplitdirs = _dirchildren._findsplitdirs
35ecaa999a12 match: improve includematcher.visitchildrenset to be much faster and cached
Kyle Lippincott <spectral@google.com>
parents: 39261
diff changeset
576 for d, b in findsplitdirs(path):
35ecaa999a12 match: improve includematcher.visitchildrenset to be much faster and cached
Kyle Lippincott <spectral@google.com>
parents: 39261
diff changeset
577 if d not in self._onlyinclude:
35ecaa999a12 match: improve includematcher.visitchildrenset to be much faster and cached
Kyle Lippincott <spectral@google.com>
parents: 39261
diff changeset
578 continue
35ecaa999a12 match: improve includematcher.visitchildrenset to be much faster and cached
Kyle Lippincott <spectral@google.com>
parents: 39261
diff changeset
579 dirs.setdefault(d, set()).add(b)
35ecaa999a12 match: improve includematcher.visitchildrenset to be much faster and cached
Kyle Lippincott <spectral@google.com>
parents: 39261
diff changeset
580
35ecaa999a12 match: improve includematcher.visitchildrenset to be much faster and cached
Kyle Lippincott <spectral@google.com>
parents: 39261
diff changeset
581 @staticmethod
35ecaa999a12 match: improve includematcher.visitchildrenset to be much faster and cached
Kyle Lippincott <spectral@google.com>
parents: 39261
diff changeset
582 def _findsplitdirs(path):
35ecaa999a12 match: improve includematcher.visitchildrenset to be much faster and cached
Kyle Lippincott <spectral@google.com>
parents: 39261
diff changeset
583 # yields (dirname, basename) tuples, walking back to the root. This is
35ecaa999a12 match: improve includematcher.visitchildrenset to be much faster and cached
Kyle Lippincott <spectral@google.com>
parents: 39261
diff changeset
584 # very similar to util.finddirs, except:
35ecaa999a12 match: improve includematcher.visitchildrenset to be much faster and cached
Kyle Lippincott <spectral@google.com>
parents: 39261
diff changeset
585 # - produces a (dirname, basename) tuple, not just 'dirname'
35ecaa999a12 match: improve includematcher.visitchildrenset to be much faster and cached
Kyle Lippincott <spectral@google.com>
parents: 39261
diff changeset
586 # Unlike manifest._splittopdir, this does not suffix `dirname` with a
42341
27d6956d386b match: use '' instead of '.' for root directory (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 42329
diff changeset
587 # slash.
39460
35ecaa999a12 match: improve includematcher.visitchildrenset to be much faster and cached
Kyle Lippincott <spectral@google.com>
parents: 39261
diff changeset
588 oldpos = len(path)
35ecaa999a12 match: improve includematcher.visitchildrenset to be much faster and cached
Kyle Lippincott <spectral@google.com>
parents: 39261
diff changeset
589 pos = path.rfind('/')
35ecaa999a12 match: improve includematcher.visitchildrenset to be much faster and cached
Kyle Lippincott <spectral@google.com>
parents: 39261
diff changeset
590 while pos != -1:
35ecaa999a12 match: improve includematcher.visitchildrenset to be much faster and cached
Kyle Lippincott <spectral@google.com>
parents: 39261
diff changeset
591 yield path[:pos], path[pos + 1:oldpos]
35ecaa999a12 match: improve includematcher.visitchildrenset to be much faster and cached
Kyle Lippincott <spectral@google.com>
parents: 39261
diff changeset
592 oldpos = pos
35ecaa999a12 match: improve includematcher.visitchildrenset to be much faster and cached
Kyle Lippincott <spectral@google.com>
parents: 39261
diff changeset
593 pos = path.rfind('/', 0, pos)
42341
27d6956d386b match: use '' instead of '.' for root directory (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 42329
diff changeset
594 yield '', path[:oldpos]
39460
35ecaa999a12 match: improve includematcher.visitchildrenset to be much faster and cached
Kyle Lippincott <spectral@google.com>
parents: 39261
diff changeset
595
35ecaa999a12 match: improve includematcher.visitchildrenset to be much faster and cached
Kyle Lippincott <spectral@google.com>
parents: 39261
diff changeset
596 def get(self, path):
35ecaa999a12 match: improve includematcher.visitchildrenset to be much faster and cached
Kyle Lippincott <spectral@google.com>
parents: 39261
diff changeset
597 return self._dirs.get(path, set())
35ecaa999a12 match: improve includematcher.visitchildrenset to be much faster and cached
Kyle Lippincott <spectral@google.com>
parents: 39261
diff changeset
598
32501
7095dbc266e3 match: split up main matcher into patternmatcher and includematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32500
diff changeset
599 class includematcher(basematcher):
7095dbc266e3 match: split up main matcher into patternmatcher and includematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32500
diff changeset
600
41675
ddbebce94665 match: delete unused root and cwd arguments to constructors (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 41672
diff changeset
601 def __init__(self, root, kindpats, badfn=None):
ddbebce94665 match: delete unused root and cwd arguments to constructors (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 41672
diff changeset
602 super(includematcher, self).__init__(badfn)
32501
7095dbc266e3 match: split up main matcher into patternmatcher and includematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32500
diff changeset
603
41669
a13268524c25 match: delete unused argument "listsubrepos" from _buildmatch()
Martin von Zweigbergk <martinvonz@google.com>
parents: 41668
diff changeset
604 self._pats, self.matchfn = _buildmatch(kindpats, '(?:/|$)', root)
33405
6aa643762641 match: inverse _anypats(), making it _prefix()
Martin von Zweigbergk <martinvonz@google.com>
parents: 33380
diff changeset
605 self._prefix = _prefix(kindpats)
38954
5a7df82de142 includematcher: separate "parents" from "dirs"
spectral <spectral@google.com>
parents: 38750
diff changeset
606 roots, dirs, parents = _rootsdirsandparents(kindpats)
32502
3026f19b4b01 match: remove support for non-include patterns from includematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32501
diff changeset
607 # roots are directories which are recursively included.
32503
361808a2b0b8 match: simplify includematcher a bit
Martin von Zweigbergk <martinvonz@google.com>
parents: 32502
diff changeset
608 self._roots = set(roots)
32502
3026f19b4b01 match: remove support for non-include patterns from includematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32501
diff changeset
609 # dirs are directories which are non-recursively included.
32503
361808a2b0b8 match: simplify includematcher a bit
Martin von Zweigbergk <martinvonz@google.com>
parents: 32502
diff changeset
610 self._dirs = set(dirs)
38954
5a7df82de142 includematcher: separate "parents" from "dirs"
spectral <spectral@google.com>
parents: 38750
diff changeset
611 # parents are directories which are non-recursively included because
5a7df82de142 includematcher: separate "parents" from "dirs"
spectral <spectral@google.com>
parents: 38750
diff changeset
612 # they are needed to get to items in _dirs or _roots.
42361
c4b8f8637d7a match: de-flake test-doctest.py by not depending on util.dirs() order
Martin von Zweigbergk <martinvonz@google.com>
parents: 42346
diff changeset
613 self._parents = parents
32501
7095dbc266e3 match: split up main matcher into patternmatcher and includematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32500
diff changeset
614
7095dbc266e3 match: split up main matcher into patternmatcher and includematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32500
diff changeset
615 def visitdir(self, dir):
42341
27d6956d386b match: use '' instead of '.' for root directory (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 42329
diff changeset
616 dir = normalizerootdir(dir, 'visitdir')
33405
6aa643762641 match: inverse _anypats(), making it _prefix()
Martin von Zweigbergk <martinvonz@google.com>
parents: 33380
diff changeset
617 if self._prefix and dir in self._roots:
32501
7095dbc266e3 match: split up main matcher into patternmatcher and includematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32500
diff changeset
618 return 'all'
42343
d8e55c0c642c util: make util.dirs() and util.finddirs() include root directory (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 42341
diff changeset
619 return (dir in self._roots or
32503
361808a2b0b8 match: simplify includematcher a bit
Martin von Zweigbergk <martinvonz@google.com>
parents: 32502
diff changeset
620 dir in self._dirs or
38954
5a7df82de142 includematcher: separate "parents" from "dirs"
spectral <spectral@google.com>
parents: 38750
diff changeset
621 dir in self._parents or
32503
361808a2b0b8 match: simplify includematcher a bit
Martin von Zweigbergk <martinvonz@google.com>
parents: 32502
diff changeset
622 any(parentdir in self._roots
361808a2b0b8 match: simplify includematcher a bit
Martin von Zweigbergk <martinvonz@google.com>
parents: 32502
diff changeset
623 for parentdir in util.finddirs(dir)))
32501
7095dbc266e3 match: split up main matcher into patternmatcher and includematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32500
diff changeset
624
39460
35ecaa999a12 match: improve includematcher.visitchildrenset to be much faster and cached
Kyle Lippincott <spectral@google.com>
parents: 39261
diff changeset
625 @propertycache
35ecaa999a12 match: improve includematcher.visitchildrenset to be much faster and cached
Kyle Lippincott <spectral@google.com>
parents: 39261
diff changeset
626 def _allparentschildren(self):
35ecaa999a12 match: improve includematcher.visitchildrenset to be much faster and cached
Kyle Lippincott <spectral@google.com>
parents: 39261
diff changeset
627 # It may seem odd that we add dirs, roots, and parents, and then
35ecaa999a12 match: improve includematcher.visitchildrenset to be much faster and cached
Kyle Lippincott <spectral@google.com>
parents: 39261
diff changeset
628 # restrict to only parents. This is to catch the case of:
35ecaa999a12 match: improve includematcher.visitchildrenset to be much faster and cached
Kyle Lippincott <spectral@google.com>
parents: 39261
diff changeset
629 # dirs = ['foo/bar']
35ecaa999a12 match: improve includematcher.visitchildrenset to be much faster and cached
Kyle Lippincott <spectral@google.com>
parents: 39261
diff changeset
630 # parents = ['foo']
35ecaa999a12 match: improve includematcher.visitchildrenset to be much faster and cached
Kyle Lippincott <spectral@google.com>
parents: 39261
diff changeset
631 # if we asked for the children of 'foo', but had only added
35ecaa999a12 match: improve includematcher.visitchildrenset to be much faster and cached
Kyle Lippincott <spectral@google.com>
parents: 39261
diff changeset
632 # self._parents, we wouldn't be able to respond ['bar'].
35ecaa999a12 match: improve includematcher.visitchildrenset to be much faster and cached
Kyle Lippincott <spectral@google.com>
parents: 39261
diff changeset
633 return _dirchildren(
35ecaa999a12 match: improve includematcher.visitchildrenset to be much faster and cached
Kyle Lippincott <spectral@google.com>
parents: 39261
diff changeset
634 itertools.chain(self._dirs, self._roots, self._parents),
35ecaa999a12 match: improve includematcher.visitchildrenset to be much faster and cached
Kyle Lippincott <spectral@google.com>
parents: 39261
diff changeset
635 onlyinclude=self._parents)
35ecaa999a12 match: improve includematcher.visitchildrenset to be much faster and cached
Kyle Lippincott <spectral@google.com>
parents: 39261
diff changeset
636
38955
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
637 def visitchildrenset(self, dir):
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
638 if self._prefix and dir in self._roots:
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
639 return 'all'
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
640 # Note: this does *not* include the 'dir in self._parents' case from
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
641 # visitdir, that's handled below.
42341
27d6956d386b match: use '' instead of '.' for root directory (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 42329
diff changeset
642 if ('' in self._roots or
38955
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
643 dir in self._roots or
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
644 dir in self._dirs or
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
645 any(parentdir in self._roots
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
646 for parentdir in util.finddirs(dir))):
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
647 return 'this'
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
648
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
649 if dir in self._parents:
39460
35ecaa999a12 match: improve includematcher.visitchildrenset to be much faster and cached
Kyle Lippincott <spectral@google.com>
parents: 39261
diff changeset
650 return self._allparentschildren.get(dir) or set()
35ecaa999a12 match: improve includematcher.visitchildrenset to be much faster and cached
Kyle Lippincott <spectral@google.com>
parents: 39261
diff changeset
651 return set()
38955
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
652
36050
c4fa47f880d3 py3: make sure we return str from __repr__
Pulkit Goyal <7895pulkit@gmail.com>
parents: 35659
diff changeset
653 @encoding.strmethod
32501
7095dbc266e3 match: split up main matcher into patternmatcher and includematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32500
diff changeset
654 def __repr__(self):
36572
9adfa48792a7 match: some minimal pycompat fixes guided by test-hgignore.t
Augie Fackler <augie@google.com>
parents: 36050
diff changeset
655 return ('<includematcher includes=%r>' % pycompat.bytestr(self._pats))
32406
952017471f93 match: implement __repr__() and update users (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32401
diff changeset
656
32499
a3583852861a match: handle exact matching using new exactmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32497
diff changeset
657 class exactmatcher(basematcher):
42080
f3db5c805a67 match: add doctest examples for exactmatcher
Denis Laxalde <denis@laxalde.org>
parents: 41676
diff changeset
658 r'''Matches the input files exactly. They are interpreted as paths, not
32499
a3583852861a match: handle exact matching using new exactmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32497
diff changeset
659 patterns (so no kind-prefixes).
42080
f3db5c805a67 match: add doctest examples for exactmatcher
Denis Laxalde <denis@laxalde.org>
parents: 41676
diff changeset
660
42186
fd384911f51b match: use raw strings to avoid illegal baskslash escape
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42099
diff changeset
661 >>> m = exactmatcher([b'a.txt', br're:.*\.c$'])
42098
5753e5949b51 py3: add b'' prefixes to new doctests in match.py
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42087
diff changeset
662 >>> m(b'a.txt')
42080
f3db5c805a67 match: add doctest examples for exactmatcher
Denis Laxalde <denis@laxalde.org>
parents: 41676
diff changeset
663 True
42098
5753e5949b51 py3: add b'' prefixes to new doctests in match.py
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42087
diff changeset
664 >>> m(b'b.txt')
42080
f3db5c805a67 match: add doctest examples for exactmatcher
Denis Laxalde <denis@laxalde.org>
parents: 41676
diff changeset
665 False
f3db5c805a67 match: add doctest examples for exactmatcher
Denis Laxalde <denis@laxalde.org>
parents: 41676
diff changeset
666
f3db5c805a67 match: add doctest examples for exactmatcher
Denis Laxalde <denis@laxalde.org>
parents: 41676
diff changeset
667 Input files that would be matched are exactly those returned by .files()
f3db5c805a67 match: add doctest examples for exactmatcher
Denis Laxalde <denis@laxalde.org>
parents: 41676
diff changeset
668 >>> m.files()
f3db5c805a67 match: add doctest examples for exactmatcher
Denis Laxalde <denis@laxalde.org>
parents: 41676
diff changeset
669 ['a.txt', 're:.*\\.c$']
f3db5c805a67 match: add doctest examples for exactmatcher
Denis Laxalde <denis@laxalde.org>
parents: 41676
diff changeset
670
f3db5c805a67 match: add doctest examples for exactmatcher
Denis Laxalde <denis@laxalde.org>
parents: 41676
diff changeset
671 So pattern 're:.*\.c$' is not considered as a regex, but as a file name
42098
5753e5949b51 py3: add b'' prefixes to new doctests in match.py
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42087
diff changeset
672 >>> m(b'main.c')
42080
f3db5c805a67 match: add doctest examples for exactmatcher
Denis Laxalde <denis@laxalde.org>
parents: 41676
diff changeset
673 False
42186
fd384911f51b match: use raw strings to avoid illegal baskslash escape
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42099
diff changeset
674 >>> m(br're:.*\.c$')
42080
f3db5c805a67 match: add doctest examples for exactmatcher
Denis Laxalde <denis@laxalde.org>
parents: 41676
diff changeset
675 True
32499
a3583852861a match: handle exact matching using new exactmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32497
diff changeset
676 '''
a3583852861a match: handle exact matching using new exactmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32497
diff changeset
677
41675
ddbebce94665 match: delete unused root and cwd arguments to constructors (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 41672
diff changeset
678 def __init__(self, files, badfn=None):
ddbebce94665 match: delete unused root and cwd arguments to constructors (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 41672
diff changeset
679 super(exactmatcher, self).__init__(badfn)
32499
a3583852861a match: handle exact matching using new exactmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32497
diff changeset
680
a3583852861a match: handle exact matching using new exactmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32497
diff changeset
681 if isinstance(files, list):
a3583852861a match: handle exact matching using new exactmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32497
diff changeset
682 self._files = files
a3583852861a match: handle exact matching using new exactmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32497
diff changeset
683 else:
a3583852861a match: handle exact matching using new exactmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32497
diff changeset
684 self._files = list(files)
32543
cf7c88986e9f match: define exactmatcher.matchfn statically
Yuya Nishihara <yuya@tcha.org>
parents: 32542
diff changeset
685
cf7c88986e9f match: define exactmatcher.matchfn statically
Yuya Nishihara <yuya@tcha.org>
parents: 32542
diff changeset
686 matchfn = basematcher.exact
32499
a3583852861a match: handle exact matching using new exactmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32497
diff changeset
687
a3583852861a match: handle exact matching using new exactmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32497
diff changeset
688 @propertycache
a3583852861a match: handle exact matching using new exactmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32497
diff changeset
689 def _dirs(self):
42346
38d85ec06552 match: drop unnecessary adding of '' to set of dirs
Martin von Zweigbergk <martinvonz@google.com>
parents: 42343
diff changeset
690 return set(util.dirs(self._fileset))
32499
a3583852861a match: handle exact matching using new exactmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32497
diff changeset
691
a3583852861a match: handle exact matching using new exactmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32497
diff changeset
692 def visitdir(self, dir):
42341
27d6956d386b match: use '' instead of '.' for root directory (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 42329
diff changeset
693 dir = normalizerootdir(dir, 'visitdir')
32499
a3583852861a match: handle exact matching using new exactmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32497
diff changeset
694 return dir in self._dirs
a3583852861a match: handle exact matching using new exactmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32497
diff changeset
695
38955
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
696 def visitchildrenset(self, dir):
42341
27d6956d386b match: use '' instead of '.' for root directory (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 42329
diff changeset
697 dir = normalizerootdir(dir, 'visitchildrenset')
27d6956d386b match: use '' instead of '.' for root directory (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 42329
diff changeset
698
39261
c9a3f7f5c023 match: make exactmatcher.visitchildrenset return file children as well
Kyle Lippincott <spectral@google.com>
parents: 39260
diff changeset
699 if not self._fileset or dir not in self._dirs:
c9a3f7f5c023 match: make exactmatcher.visitchildrenset return file children as well
Kyle Lippincott <spectral@google.com>
parents: 39260
diff changeset
700 return set()
c9a3f7f5c023 match: make exactmatcher.visitchildrenset return file children as well
Kyle Lippincott <spectral@google.com>
parents: 39260
diff changeset
701
42341
27d6956d386b match: use '' instead of '.' for root directory (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 42329
diff changeset
702 candidates = self._fileset | self._dirs - {''}
27d6956d386b match: use '' instead of '.' for root directory (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 42329
diff changeset
703 if dir != '':
39261
c9a3f7f5c023 match: make exactmatcher.visitchildrenset return file children as well
Kyle Lippincott <spectral@google.com>
parents: 39260
diff changeset
704 d = dir + '/'
c9a3f7f5c023 match: make exactmatcher.visitchildrenset return file children as well
Kyle Lippincott <spectral@google.com>
parents: 39260
diff changeset
705 candidates = set(c[len(d):] for c in candidates if
c9a3f7f5c023 match: make exactmatcher.visitchildrenset return file children as well
Kyle Lippincott <spectral@google.com>
parents: 39260
diff changeset
706 c.startswith(d))
c9a3f7f5c023 match: make exactmatcher.visitchildrenset return file children as well
Kyle Lippincott <spectral@google.com>
parents: 39260
diff changeset
707 # self._dirs includes all of the directories, recursively, so if
42341
27d6956d386b match: use '' instead of '.' for root directory (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 42329
diff changeset
708 # we're attempting to match foo/bar/baz.txt, it'll have '', 'foo',
39261
c9a3f7f5c023 match: make exactmatcher.visitchildrenset return file children as well
Kyle Lippincott <spectral@google.com>
parents: 39260
diff changeset
709 # 'foo/bar' in it. Thus we can safely ignore a candidate that has a
c9a3f7f5c023 match: make exactmatcher.visitchildrenset return file children as well
Kyle Lippincott <spectral@google.com>
parents: 39260
diff changeset
710 # '/' in it, indicating a it's for a subdir-of-a-subdir; the
c9a3f7f5c023 match: make exactmatcher.visitchildrenset return file children as well
Kyle Lippincott <spectral@google.com>
parents: 39260
diff changeset
711 # immediate subdir will be in there without a slash.
c9a3f7f5c023 match: make exactmatcher.visitchildrenset return file children as well
Kyle Lippincott <spectral@google.com>
parents: 39260
diff changeset
712 ret = {c for c in candidates if '/' not in c}
c9a3f7f5c023 match: make exactmatcher.visitchildrenset return file children as well
Kyle Lippincott <spectral@google.com>
parents: 39260
diff changeset
713 # We really do not expect ret to be empty, since that would imply that
c9a3f7f5c023 match: make exactmatcher.visitchildrenset return file children as well
Kyle Lippincott <spectral@google.com>
parents: 39260
diff changeset
714 # there's something in _dirs that didn't have a file in _fileset.
c9a3f7f5c023 match: make exactmatcher.visitchildrenset return file children as well
Kyle Lippincott <spectral@google.com>
parents: 39260
diff changeset
715 assert ret
c9a3f7f5c023 match: make exactmatcher.visitchildrenset return file children as well
Kyle Lippincott <spectral@google.com>
parents: 39260
diff changeset
716 return ret
38955
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
717
32499
a3583852861a match: handle exact matching using new exactmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32497
diff changeset
718 def isexact(self):
a3583852861a match: handle exact matching using new exactmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32497
diff changeset
719 return True
a3583852861a match: handle exact matching using new exactmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32497
diff changeset
720
36050
c4fa47f880d3 py3: make sure we return str from __repr__
Pulkit Goyal <7895pulkit@gmail.com>
parents: 35659
diff changeset
721 @encoding.strmethod
32499
a3583852861a match: handle exact matching using new exactmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32497
diff changeset
722 def __repr__(self):
a3583852861a match: handle exact matching using new exactmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32497
diff changeset
723 return ('<exactmatcher files=%r>' % self._files)
a3583852861a match: handle exact matching using new exactmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32497
diff changeset
724
32465
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32464
diff changeset
725 class differencematcher(basematcher):
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32464
diff changeset
726 '''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: 35164
diff changeset
727 does not.
32465
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32464
diff changeset
728
41675
ddbebce94665 match: delete unused root and cwd arguments to constructors (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 41672
diff changeset
729 The second matcher's non-matching-attributes (bad, explicitdir,
32465
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32464
diff changeset
730 traversedir) are ignored.
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32464
diff changeset
731 '''
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32464
diff changeset
732 def __init__(self, m1, m2):
41675
ddbebce94665 match: delete unused root and cwd arguments to constructors (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 41672
diff changeset
733 super(differencematcher, self).__init__()
32465
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32464
diff changeset
734 self._m1 = m1
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32464
diff changeset
735 self._m2 = m2
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32464
diff changeset
736 self.bad = m1.bad
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32464
diff changeset
737 self.explicitdir = m1.explicitdir
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32464
diff changeset
738 self.traversedir = m1.traversedir
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32464
diff changeset
739
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32464
diff changeset
740 def matchfn(self, f):
35659
821d8a5ab4ff match: do not weirdly include explicit files excluded by -X option
Yuya Nishihara <yuya@tcha.org>
parents: 35164
diff changeset
741 return self._m1(f) and not self._m2(f)
32465
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32464
diff changeset
742
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32464
diff changeset
743 @propertycache
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32464
diff changeset
744 def _files(self):
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32464
diff changeset
745 if self.isexact():
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32464
diff changeset
746 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: 32464
diff changeset
747 # 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: 32464
diff changeset
748 # 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: 32464
diff changeset
749 # 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: 32464
diff changeset
750 # 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: 32464
diff changeset
751 # because the "dir" in m1 may not be a file.
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32464
diff changeset
752 return self._m1.files()
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32464
diff changeset
753
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32464
diff changeset
754 def visitdir(self, dir):
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32464
diff changeset
755 if self._m2.visitdir(dir) == 'all':
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32464
diff changeset
756 return False
41528
b7a0efb3c370 match: teach diffmatcher.visitdir() to return 'all' if possible
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41282
diff changeset
757 elif not self._m2.visitdir(dir):
b7a0efb3c370 match: teach diffmatcher.visitdir() to return 'all' if possible
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41282
diff changeset
758 # m2 does not match dir, we can return 'all' here if possible
b7a0efb3c370 match: teach diffmatcher.visitdir() to return 'all' if possible
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41282
diff changeset
759 return self._m1.visitdir(dir)
32465
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32464
diff changeset
760 return bool(self._m1.visitdir(dir))
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32464
diff changeset
761
38955
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
762 def visitchildrenset(self, dir):
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
763 m2_set = self._m2.visitchildrenset(dir)
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
764 if m2_set == 'all':
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
765 return set()
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
766 m1_set = self._m1.visitchildrenset(dir)
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
767 # Possible values for m1: 'all', 'this', set(...), set()
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
768 # Possible values for m2: 'this', set(...), set()
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
769 # 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: 38954
diff changeset
770 # 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: 38954
diff changeset
771 # return True, not 'all', for some reason.
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
772 if not m2_set:
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
773 return m1_set
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
774 if m1_set in ['all', 'this']:
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
775 # 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: 38954
diff changeset
776 # 'this' or set(foo)), since m2 might return set() for a
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
777 # subdirectory.
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
778 return 'this'
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
779 # Possible values for m1: set(...), set()
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
780 # Possible values for m2: 'this', set(...)
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
781 # We ignore m2's set results. They're possibly incorrect:
42341
27d6956d386b match: use '' instead of '.' for root directory (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 42329
diff changeset
782 # m1 = path:dir/subdir, m2=rootfilesin:dir, visitchildrenset(''):
38955
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
783 # m1 returns {'dir'}, m2 returns {'dir'}, if we subtracted we'd
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
784 # return set(), which is *not* correct, we still need to visit 'dir'!
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
785 return m1_set
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
786
32465
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32464
diff changeset
787 def isexact(self):
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32464
diff changeset
788 return self._m1.isexact()
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32464
diff changeset
789
36050
c4fa47f880d3 py3: make sure we return str from __repr__
Pulkit Goyal <7895pulkit@gmail.com>
parents: 35659
diff changeset
790 @encoding.strmethod
32465
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32464
diff changeset
791 def __repr__(self):
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32464
diff changeset
792 return ('<differencematcher m1=%r, m2=%r>' % (self._m1, self._m2))
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32464
diff changeset
793
32497
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32496
diff changeset
794 def intersectmatchers(m1, m2):
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32496
diff changeset
795 '''Composes two matchers by matching if both of them match.
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32496
diff changeset
796
41675
ddbebce94665 match: delete unused root and cwd arguments to constructors (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 41672
diff changeset
797 The second matcher's non-matching-attributes (bad, explicitdir,
32497
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32496
diff changeset
798 traversedir) are ignored.
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32496
diff changeset
799 '''
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32496
diff changeset
800 if m1 is None or m2 is None:
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32496
diff changeset
801 return m1 or m2
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32496
diff changeset
802 if m1.always():
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32496
diff changeset
803 m = copy.copy(m2)
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32496
diff changeset
804 # 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: 32496
diff changeset
805 # one thing to copy from m1.
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32496
diff changeset
806 m.bad = m1.bad
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32496
diff changeset
807 m.explicitdir = m1.explicitdir
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32496
diff changeset
808 m.traversedir = m1.traversedir
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32496
diff changeset
809 return m
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32496
diff changeset
810 if m2.always():
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32496
diff changeset
811 m = copy.copy(m1)
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32496
diff changeset
812 return m
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32496
diff changeset
813 return intersectionmatcher(m1, m2)
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32496
diff changeset
814
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32496
diff changeset
815 class intersectionmatcher(basematcher):
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32496
diff changeset
816 def __init__(self, m1, m2):
41675
ddbebce94665 match: delete unused root and cwd arguments to constructors (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 41672
diff changeset
817 super(intersectionmatcher, self).__init__()
32497
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32496
diff changeset
818 self._m1 = m1
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32496
diff changeset
819 self._m2 = m2
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32496
diff changeset
820 self.bad = m1.bad
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32496
diff changeset
821 self.explicitdir = m1.explicitdir
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32496
diff changeset
822 self.traversedir = m1.traversedir
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32496
diff changeset
823
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32496
diff changeset
824 @propertycache
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32496
diff changeset
825 def _files(self):
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32496
diff changeset
826 if self.isexact():
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32496
diff changeset
827 m1, m2 = self._m1, self._m2
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32496
diff changeset
828 if not m1.isexact():
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32496
diff changeset
829 m1, m2 = m2, m1
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32496
diff changeset
830 return [f for f in m1.files() if m2(f)]
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32496
diff changeset
831 # 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: 32496
diff changeset
832 # 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: 32496
diff changeset
833 # 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: 32496
diff changeset
834 # "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: 32496
diff changeset
835 return self._m1.files() + self._m2.files()
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32496
diff changeset
836
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32496
diff changeset
837 def matchfn(self, f):
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32496
diff changeset
838 return self._m1(f) and self._m2(f)
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32496
diff changeset
839
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32496
diff changeset
840 def visitdir(self, dir):
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32496
diff changeset
841 visit1 = self._m1.visitdir(dir)
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32496
diff changeset
842 if visit1 == 'all':
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32496
diff changeset
843 return self._m2.visitdir(dir)
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32496
diff changeset
844 # bool() because visit1=True + visit2='all' should not be 'all'
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32496
diff changeset
845 return bool(visit1 and self._m2.visitdir(dir))
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32496
diff changeset
846
38955
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
847 def visitchildrenset(self, dir):
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
848 m1_set = self._m1.visitchildrenset(dir)
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
849 if not m1_set:
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
850 return set()
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
851 m2_set = self._m2.visitchildrenset(dir)
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
852 if not m2_set:
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
853 return set()
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
854
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
855 if m1_set == 'all':
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
856 return m2_set
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
857 elif m2_set == 'all':
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
858 return m1_set
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
859
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
860 if m1_set == 'this' or m2_set == 'this':
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
861 return 'this'
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
862
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
863 assert isinstance(m1_set, set) and isinstance(m2_set, set)
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
864 return m1_set.intersection(m2_set)
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
865
32497
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32496
diff changeset
866 def always(self):
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32496
diff changeset
867 return self._m1.always() and self._m2.always()
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32496
diff changeset
868
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32496
diff changeset
869 def isexact(self):
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32496
diff changeset
870 return self._m1.isexact() or self._m2.isexact()
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32496
diff changeset
871
36050
c4fa47f880d3 py3: make sure we return str from __repr__
Pulkit Goyal <7895pulkit@gmail.com>
parents: 35659
diff changeset
872 @encoding.strmethod
32497
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32496
diff changeset
873 def __repr__(self):
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32496
diff changeset
874 return ('<intersectionmatcher m1=%r, m2=%r>' % (self._m1, self._m2))
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32496
diff changeset
875
32460
f9445b528687 match: make subdirmatcher extend basematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32459
diff changeset
876 class subdirmatcher(basematcher):
12165
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
877 """Adapt a matcher to work on a subdirectory only.
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
878
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
879 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
880
34137
a8994d08e4a2 doctest: use print_function and convert bytes to unicode where needed
Yuya Nishihara <yuya@tcha.org>
parents: 34131
diff changeset
881 >>> from . import pycompat
34131
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33684
diff changeset
882 >>> 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: 33684
diff changeset
883 >>> m2 = subdirmatcher(b'sub', m1)
42087
2e2699af5649 match: let regex match function return a boolean
Denis Laxalde <denis@laxalde.org>
parents: 42086
diff changeset
884 >>> m2(b'a.txt')
12165
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
885 False
42087
2e2699af5649 match: let regex match function return a boolean
Denis Laxalde <denis@laxalde.org>
parents: 42086
diff changeset
886 >>> m2(b'b.txt')
12165
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
887 True
42087
2e2699af5649 match: let regex match function return a boolean
Denis Laxalde <denis@laxalde.org>
parents: 42086
diff changeset
888 >>> m2.matchfn(b'a.txt')
12165
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
889 False
42087
2e2699af5649 match: let regex match function return a boolean
Denis Laxalde <denis@laxalde.org>
parents: 42086
diff changeset
890 >>> m2.matchfn(b'b.txt')
12165
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
891 True
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
892 >>> m2.files()
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
893 ['b.txt']
34131
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33684
diff changeset
894 >>> m2.exact(b'b.txt')
12165
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
895 True
12268
83aaeba32b88 narrowmatcher: propagate bad method
Martin Geisler <mg@lazybytes.net>
parents: 12267
diff changeset
896 >>> def bad(f, msg):
34137
a8994d08e4a2 doctest: use print_function and convert bytes to unicode where needed
Yuya Nishihara <yuya@tcha.org>
parents: 34131
diff changeset
897 ... print(pycompat.sysstr(b"%s: %s" % (f, msg)))
12268
83aaeba32b88 narrowmatcher: propagate bad method
Martin Geisler <mg@lazybytes.net>
parents: 12267
diff changeset
898 >>> m1.bad = bad
34131
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33684
diff changeset
899 >>> m2.bad(b'x.txt', b'No such file')
12268
83aaeba32b88 narrowmatcher: propagate bad method
Martin Geisler <mg@lazybytes.net>
parents: 12267
diff changeset
900 sub/x.txt: No such file
12165
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
901 """
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
902
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
903 def __init__(self, path, matcher):
41675
ddbebce94665 match: delete unused root and cwd arguments to constructors (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 41672
diff changeset
904 super(subdirmatcher, self).__init__()
12165
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
905 self._path = path
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
906 self._matcher = matcher
32460
f9445b528687 match: make subdirmatcher extend basematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32459
diff changeset
907 self._always = matcher.always()
12165
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
908
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
909 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
910 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
911
32325
763d72925691 match: use match.prefix() in subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32324
diff changeset
912 # 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: 32324
diff changeset
913 # a prefix matcher, this submatcher always matches.
763d72925691 match: use match.prefix() in subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32324
diff changeset
914 if matcher.prefix():
25195
472a685a4961 merge with stable
Matt Mackall <mpm@selenic.com>
parents: 25189 25194
diff changeset
915 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
916
32324
77dac8fd30ee match: avoid accessing match._pathrestricted from subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32323
diff changeset
917 def bad(self, f, msg):
77dac8fd30ee match: avoid accessing match._pathrestricted from subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32323
diff changeset
918 self._matcher.bad(self._path + "/" + f, msg)
77dac8fd30ee match: avoid accessing match._pathrestricted from subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32323
diff changeset
919
32464
2e80a691e575 match: override matchfn() the usual way in subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32463
diff changeset
920 def matchfn(self, f):
2e80a691e575 match: override matchfn() the usual way in subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32463
diff changeset
921 # 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: 32463
diff changeset
922 # 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: 32463
diff changeset
923 # 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: 32463
diff changeset
924 # 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: 32463
diff changeset
925 return self._matcher.matchfn(self._path + "/" + f)
2e80a691e575 match: override matchfn() the usual way in subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32463
diff changeset
926
32323
0aa4032a97e1 match: override visitdir() the usual way in subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32322
diff changeset
927 def visitdir(self, dir):
42341
27d6956d386b match: use '' instead of '.' for root directory (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 42329
diff changeset
928 dir = normalizerootdir(dir, 'visitdir')
27d6956d386b match: use '' instead of '.' for root directory (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 42329
diff changeset
929 if dir == '':
32323
0aa4032a97e1 match: override visitdir() the usual way in subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32322
diff changeset
930 dir = self._path
0aa4032a97e1 match: override visitdir() the usual way in subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32322
diff changeset
931 else:
0aa4032a97e1 match: override visitdir() the usual way in subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32322
diff changeset
932 dir = self._path + "/" + dir
0aa4032a97e1 match: override visitdir() the usual way in subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32322
diff changeset
933 return self._matcher.visitdir(dir)
0aa4032a97e1 match: override visitdir() the usual way in subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32322
diff changeset
934
38955
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
935 def visitchildrenset(self, dir):
42341
27d6956d386b match: use '' instead of '.' for root directory (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 42329
diff changeset
936 dir = normalizerootdir(dir, 'visitchildrenset')
27d6956d386b match: use '' instead of '.' for root directory (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 42329
diff changeset
937 if dir == '':
38955
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
938 dir = self._path
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
939 else:
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
940 dir = self._path + "/" + dir
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
941 return self._matcher.visitchildrenset(dir)
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
942
32460
f9445b528687 match: make subdirmatcher extend basematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32459
diff changeset
943 def always(self):
f9445b528687 match: make subdirmatcher extend basematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32459
diff changeset
944 return self._always
f9445b528687 match: make subdirmatcher extend basematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32459
diff changeset
945
33379
7ddb2aa2b7af match: express anypats(), not prefix(), in terms of the others
Martin von Zweigbergk <martinvonz@google.com>
parents: 33378
diff changeset
946 def prefix(self):
7ddb2aa2b7af match: express anypats(), not prefix(), in terms of the others
Martin von Zweigbergk <martinvonz@google.com>
parents: 33378
diff changeset
947 return self._matcher.prefix() and not self._always
32460
f9445b528687 match: make subdirmatcher extend basematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32459
diff changeset
948
36050
c4fa47f880d3 py3: make sure we return str from __repr__
Pulkit Goyal <7895pulkit@gmail.com>
parents: 35659
diff changeset
949 @encoding.strmethod
32552
e7aa11f3abcd match: add __repr__ for subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32543
diff changeset
950 def __repr__(self):
e7aa11f3abcd match: add __repr__ for subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32543
diff changeset
951 return ('<subdirmatcher path=%r, matcher=%r>' %
e7aa11f3abcd match: add __repr__ for subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32543
diff changeset
952 (self._path, self._matcher))
e7aa11f3abcd match: add __repr__ for subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32543
diff changeset
953
38611
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
954 class prefixdirmatcher(basematcher):
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
955 """Adapt a matcher to work on a parent directory.
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
956
41675
ddbebce94665 match: delete unused root and cwd arguments to constructors (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 41672
diff changeset
957 The matcher's non-matching-attributes (bad, explicitdir, traversedir) are
ddbebce94665 match: delete unused root and cwd arguments to constructors (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 41672
diff changeset
958 ignored.
38611
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
959
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
960 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: 38581
diff changeset
961 this matcher to the root of the wrapped matcher.
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
962
38750
a8bfaf592033 doctest: convert matcher root to native path
Yuya Nishihara <yuya@tcha.org>
parents: 38612
diff changeset
963 >>> m1 = match(util.localpath(b'root/d/e'), b'f', [b'../a.txt', b'b.txt'])
41675
ddbebce94665 match: delete unused root and cwd arguments to constructors (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 41672
diff changeset
964 >>> m2 = prefixdirmatcher(b'd/e', m1)
42087
2e2699af5649 match: let regex match function return a boolean
Denis Laxalde <denis@laxalde.org>
parents: 42086
diff changeset
965 >>> m2(b'a.txt')
38611
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
966 False
42087
2e2699af5649 match: let regex match function return a boolean
Denis Laxalde <denis@laxalde.org>
parents: 42086
diff changeset
967 >>> m2(b'd/e/a.txt')
38611
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
968 True
42087
2e2699af5649 match: let regex match function return a boolean
Denis Laxalde <denis@laxalde.org>
parents: 42086
diff changeset
969 >>> m2(b'd/e/b.txt')
38611
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
970 False
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
971 >>> m2.files()
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
972 ['d/e/a.txt', 'd/e/f/b.txt']
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
973 >>> m2.exact(b'd/e/a.txt')
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
974 True
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
975 >>> m2.visitdir(b'd')
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
976 True
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
977 >>> m2.visitdir(b'd/e')
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
978 True
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
979 >>> m2.visitdir(b'd/e/f')
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
980 True
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
981 >>> m2.visitdir(b'd/e/g')
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
982 False
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
983 >>> m2.visitdir(b'd/ef')
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
984 False
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
985 """
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
986
41675
ddbebce94665 match: delete unused root and cwd arguments to constructors (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 41672
diff changeset
987 def __init__(self, path, matcher, badfn=None):
ddbebce94665 match: delete unused root and cwd arguments to constructors (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 41672
diff changeset
988 super(prefixdirmatcher, self).__init__(badfn)
38611
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
989 if not path:
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
990 raise error.ProgrammingError('prefix path must not be empty')
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
991 self._path = path
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
992 self._pathprefix = path + '/'
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
993 self._matcher = matcher
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
994
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
995 @propertycache
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
996 def _files(self):
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
997 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: 38581
diff changeset
998
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
999 def matchfn(self, f):
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
1000 if not f.startswith(self._pathprefix):
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
1001 return False
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
1002 return self._matcher.matchfn(f[len(self._pathprefix):])
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
1003
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
1004 @propertycache
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
1005 def _pathdirs(self):
42346
38d85ec06552 match: drop unnecessary adding of '' to set of dirs
Martin von Zweigbergk <martinvonz@google.com>
parents: 42343
diff changeset
1006 return set(util.finddirs(self._path))
38611
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
1007
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
1008 def visitdir(self, dir):
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
1009 if dir == self._path:
42341
27d6956d386b match: use '' instead of '.' for root directory (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 42329
diff changeset
1010 return self._matcher.visitdir('')
38611
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
1011 if dir.startswith(self._pathprefix):
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
1012 return self._matcher.visitdir(dir[len(self._pathprefix):])
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
1013 return dir in self._pathdirs
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
1014
38955
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
1015 def visitchildrenset(self, dir):
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
1016 if dir == self._path:
42341
27d6956d386b match: use '' instead of '.' for root directory (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 42329
diff changeset
1017 return self._matcher.visitchildrenset('')
38955
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
1018 if dir.startswith(self._pathprefix):
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
1019 return self._matcher.visitchildrenset(dir[len(self._pathprefix):])
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
1020 if dir in self._pathdirs:
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
1021 return 'this'
38958
b9f94d67ea73 match: add missing "return set()", add FIXME to test to doc a bug
Kyle Lippincott <spectral@google.com>
parents: 38957
diff changeset
1022 return set()
38955
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
1023
38611
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
1024 def isexact(self):
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
1025 return self._matcher.isexact()
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
1026
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
1027 def prefix(self):
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
1028 return self._matcher.prefix()
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
1029
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
1030 @encoding.strmethod
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
1031 def __repr__(self):
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
1032 return ('<prefixdirmatcher path=%r, matcher=%r>'
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
1033 % (pycompat.bytestr(self._path), self._matcher))
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
1034
33319
3c84591e7321 match: move matchers from sparse into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33306
diff changeset
1035 class unionmatcher(basematcher):
33448
04be8aec44a8 match: make unionmatcher a proper matcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 33447
diff changeset
1036 """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
1037
41675
ddbebce94665 match: delete unused root and cwd arguments to constructors (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 41672
diff changeset
1038 The non-matching-attributes (bad, explicitdir, traversedir) are taken from
ddbebce94665 match: delete unused root and cwd arguments to constructors (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 41672
diff changeset
1039 the first matcher.
33448
04be8aec44a8 match: make unionmatcher a proper matcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 33447
diff changeset
1040 """
04be8aec44a8 match: make unionmatcher a proper matcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 33447
diff changeset
1041
33319
3c84591e7321 match: move matchers from sparse into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33306
diff changeset
1042 def __init__(self, matchers):
33448
04be8aec44a8 match: make unionmatcher a proper matcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 33447
diff changeset
1043 m1 = matchers[0]
41675
ddbebce94665 match: delete unused root and cwd arguments to constructors (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 41672
diff changeset
1044 super(unionmatcher, self).__init__()
33448
04be8aec44a8 match: make unionmatcher a proper matcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 33447
diff changeset
1045 self.explicitdir = m1.explicitdir
04be8aec44a8 match: make unionmatcher a proper matcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 33447
diff changeset
1046 self.traversedir = m1.traversedir
33319
3c84591e7321 match: move matchers from sparse into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33306
diff changeset
1047 self._matchers = matchers
3c84591e7321 match: move matchers from sparse into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33306
diff changeset
1048
33380
892d255ec2a1 match: override matchfn instead of __call__ for consistency
Martin von Zweigbergk <martinvonz@google.com>
parents: 33379
diff changeset
1049 def matchfn(self, f):
33319
3c84591e7321 match: move matchers from sparse into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33306
diff changeset
1050 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
1051 if match(f):
33319
3c84591e7321 match: move matchers from sparse into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33306
diff changeset
1052 return True
3c84591e7321 match: move matchers from sparse into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33306
diff changeset
1053 return False
3c84591e7321 match: move matchers from sparse into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33306
diff changeset
1054
33448
04be8aec44a8 match: make unionmatcher a proper matcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 33447
diff changeset
1055 def visitdir(self, dir):
04be8aec44a8 match: make unionmatcher a proper matcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 33447
diff changeset
1056 r = False
04be8aec44a8 match: make unionmatcher a proper matcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 33447
diff changeset
1057 for m in self._matchers:
04be8aec44a8 match: make unionmatcher a proper matcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 33447
diff changeset
1058 v = m.visitdir(dir)
04be8aec44a8 match: make unionmatcher a proper matcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 33447
diff changeset
1059 if v == 'all':
04be8aec44a8 match: make unionmatcher a proper matcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 33447
diff changeset
1060 return v
04be8aec44a8 match: make unionmatcher a proper matcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 33447
diff changeset
1061 r |= v
04be8aec44a8 match: make unionmatcher a proper matcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 33447
diff changeset
1062 return r
04be8aec44a8 match: make unionmatcher a proper matcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 33447
diff changeset
1063
38955
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
1064 def visitchildrenset(self, dir):
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
1065 r = set()
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
1066 this = False
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
1067 for m in self._matchers:
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
1068 v = m.visitchildrenset(dir)
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
1069 if not v:
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
1070 continue
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
1071 if v == 'all':
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
1072 return v
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
1073 if this or v == 'this':
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
1074 this = True
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
1075 # don't break, we might have an 'all' in here.
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
1076 continue
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
1077 assert isinstance(v, set)
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
1078 r = r.union(v)
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
1079 if this:
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
1080 return 'this'
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
1081 return r
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
1082
36050
c4fa47f880d3 py3: make sure we return str from __repr__
Pulkit Goyal <7895pulkit@gmail.com>
parents: 35659
diff changeset
1083 @encoding.strmethod
33319
3c84591e7321 match: move matchers from sparse into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33306
diff changeset
1084 def __repr__(self):
3c84591e7321 match: move matchers from sparse into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33306
diff changeset
1085 return ('<unionmatcher matchers=%r>' % self._matchers)
3c84591e7321 match: move matchers from sparse into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33306
diff changeset
1086
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
1087 def patkind(pattern, default=None):
42082
413a75da98ce match: add doctest examples for patkind()
Denis Laxalde <denis@laxalde.org>
parents: 42081
diff changeset
1088 '''If pattern is 'kind:pat' with a known kind, return kind.
413a75da98ce match: add doctest examples for patkind()
Denis Laxalde <denis@laxalde.org>
parents: 42081
diff changeset
1089
42186
fd384911f51b match: use raw strings to avoid illegal baskslash escape
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42099
diff changeset
1090 >>> patkind(br're:.*\.c$')
42082
413a75da98ce match: add doctest examples for patkind()
Denis Laxalde <denis@laxalde.org>
parents: 42081
diff changeset
1091 're'
42098
5753e5949b51 py3: add b'' prefixes to new doctests in match.py
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42087
diff changeset
1092 >>> patkind(b'glob:*.c')
42082
413a75da98ce match: add doctest examples for patkind()
Denis Laxalde <denis@laxalde.org>
parents: 42081
diff changeset
1093 'glob'
42098
5753e5949b51 py3: add b'' prefixes to new doctests in match.py
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42087
diff changeset
1094 >>> patkind(b'relpath:test.py')
42082
413a75da98ce match: add doctest examples for patkind()
Denis Laxalde <denis@laxalde.org>
parents: 42081
diff changeset
1095 'relpath'
42098
5753e5949b51 py3: add b'' prefixes to new doctests in match.py
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42087
diff changeset
1096 >>> patkind(b'main.py')
5753e5949b51 py3: add b'' prefixes to new doctests in match.py
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42087
diff changeset
1097 >>> patkind(b'main.py', default=b're')
42082
413a75da98ce match: add doctest examples for patkind()
Denis Laxalde <denis@laxalde.org>
parents: 42081
diff changeset
1098 're'
413a75da98ce match: add doctest examples for patkind()
Denis Laxalde <denis@laxalde.org>
parents: 42081
diff changeset
1099 '''
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
1100 return _patsplit(pattern, default)[0]
8570
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
1101
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
1102 def _patsplit(pattern, default):
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
1103 """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
1104 pattern."""
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
1105 if ':' in pattern:
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
1106 kind, pat = pattern.split(':', 1)
33684
2be0bf186950 match: expose some data and functionality to other modules
Kostia Balytskyi <ikostia@fb.com>
parents: 33582
diff changeset
1107 if kind in allpatternkinds:
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
1108 return kind, pat
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
1109 return default, pattern
8570
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
1110
8582
a4c199e12b5a match: remove head and tail args from _globre
Matt Mackall <mpm@selenic.com>
parents: 8581
diff changeset
1111 def _globre(pat):
21112
03782d2fc776 match: _globre doctests
Mads Kiilerich <madski@unity3d.com>
parents: 21111
diff changeset
1112 r'''Convert an extended glob string to a regexp string.
03782d2fc776 match: _globre doctests
Mads Kiilerich <madski@unity3d.com>
parents: 21111
diff changeset
1113
34137
a8994d08e4a2 doctest: use print_function and convert bytes to unicode where needed
Yuya Nishihara <yuya@tcha.org>
parents: 34131
diff changeset
1114 >>> from . import pycompat
a8994d08e4a2 doctest: use print_function and convert bytes to unicode where needed
Yuya Nishihara <yuya@tcha.org>
parents: 34131
diff changeset
1115 >>> def bprint(s):
a8994d08e4a2 doctest: use print_function and convert bytes to unicode where needed
Yuya Nishihara <yuya@tcha.org>
parents: 34131
diff changeset
1116 ... print(pycompat.sysstr(s))
a8994d08e4a2 doctest: use print_function and convert bytes to unicode where needed
Yuya Nishihara <yuya@tcha.org>
parents: 34131
diff changeset
1117 >>> bprint(_globre(br'?'))
21112
03782d2fc776 match: _globre doctests
Mads Kiilerich <madski@unity3d.com>
parents: 21111
diff changeset
1118 .
34137
a8994d08e4a2 doctest: use print_function and convert bytes to unicode where needed
Yuya Nishihara <yuya@tcha.org>
parents: 34131
diff changeset
1119 >>> bprint(_globre(br'*'))
21112
03782d2fc776 match: _globre doctests
Mads Kiilerich <madski@unity3d.com>
parents: 21111
diff changeset
1120 [^/]*
34137
a8994d08e4a2 doctest: use print_function and convert bytes to unicode where needed
Yuya Nishihara <yuya@tcha.org>
parents: 34131
diff changeset
1121 >>> bprint(_globre(br'**'))
21112
03782d2fc776 match: _globre doctests
Mads Kiilerich <madski@unity3d.com>
parents: 21111
diff changeset
1122 .*
34137
a8994d08e4a2 doctest: use print_function and convert bytes to unicode where needed
Yuya Nishihara <yuya@tcha.org>
parents: 34131
diff changeset
1123 >>> bprint(_globre(br'**/a'))
21815
a4b67bf1f0a5 match: make glob '**/' match the empty string
Siddharth Agarwal <sid0@fb.com>
parents: 21191
diff changeset
1124 (?:.*/)?a
34137
a8994d08e4a2 doctest: use print_function and convert bytes to unicode where needed
Yuya Nishihara <yuya@tcha.org>
parents: 34131
diff changeset
1125 >>> bprint(_globre(br'a/**/b'))
38475
67dc32d4e790 cleanup: migrate from re.escape to stringutil.reescape
Augie Fackler <augie@google.com>
parents: 38019
diff changeset
1126 a/(?:.*/)?b
34137
a8994d08e4a2 doctest: use print_function and convert bytes to unicode where needed
Yuya Nishihara <yuya@tcha.org>
parents: 34131
diff changeset
1127 >>> bprint(_globre(br'[a*?!^][^b][!c]'))
21112
03782d2fc776 match: _globre doctests
Mads Kiilerich <madski@unity3d.com>
parents: 21111
diff changeset
1128 [a*?!^][\^b][^c]
34137
a8994d08e4a2 doctest: use print_function and convert bytes to unicode where needed
Yuya Nishihara <yuya@tcha.org>
parents: 34131
diff changeset
1129 >>> bprint(_globre(br'{a,b}'))
21112
03782d2fc776 match: _globre doctests
Mads Kiilerich <madski@unity3d.com>
parents: 21111
diff changeset
1130 (?:a|b)
34137
a8994d08e4a2 doctest: use print_function and convert bytes to unicode where needed
Yuya Nishihara <yuya@tcha.org>
parents: 34131
diff changeset
1131 >>> bprint(_globre(br'.\*\?'))
21112
03782d2fc776 match: _globre doctests
Mads Kiilerich <madski@unity3d.com>
parents: 21111
diff changeset
1132 \.\*\?
03782d2fc776 match: _globre doctests
Mads Kiilerich <madski@unity3d.com>
parents: 21111
diff changeset
1133 '''
8570
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
1134 i, n = 0, len(pat)
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
1135 res = ''
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
1136 group = 0
40684
e6c9ef5e11a0 match: provide and use a quick way to escape a single byte
Boris Feld <boris.feld@octobus.net>
parents: 40345
diff changeset
1137 escape = util.stringutil.regexbytesescapemap.get
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10263
diff changeset
1138 def peek():
31421
5c9cda37d7f6 match: slice over bytes to get the byteschr instead of ascii value
Pulkit Goyal <7895pulkit@gmail.com>
parents: 31420
diff changeset
1139 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
1140 while i < n:
31421
5c9cda37d7f6 match: slice over bytes to get the byteschr instead of ascii value
Pulkit Goyal <7895pulkit@gmail.com>
parents: 31420
diff changeset
1141 c = pat[i:i + 1]
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10263
diff changeset
1142 i += 1
8583
19d1b2aec562 match: optimize escaping in _globre
Matt Mackall <mpm@selenic.com>
parents: 8582
diff changeset
1143 if c not in '*?[{},\\':
40684
e6c9ef5e11a0 match: provide and use a quick way to escape a single byte
Boris Feld <boris.feld@octobus.net>
parents: 40345
diff changeset
1144 res += escape(c, c)
8583
19d1b2aec562 match: optimize escaping in _globre
Matt Mackall <mpm@selenic.com>
parents: 8582
diff changeset
1145 elif c == '*':
8570
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
1146 if peek() == '*':
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
1147 i += 1
21815
a4b67bf1f0a5 match: make glob '**/' match the empty string
Siddharth Agarwal <sid0@fb.com>
parents: 21191
diff changeset
1148 if peek() == '/':
a4b67bf1f0a5 match: make glob '**/' match the empty string
Siddharth Agarwal <sid0@fb.com>
parents: 21191
diff changeset
1149 i += 1
a4b67bf1f0a5 match: make glob '**/' match the empty string
Siddharth Agarwal <sid0@fb.com>
parents: 21191
diff changeset
1150 res += '(?:.*/)?'
a4b67bf1f0a5 match: make glob '**/' match the empty string
Siddharth Agarwal <sid0@fb.com>
parents: 21191
diff changeset
1151 else:
a4b67bf1f0a5 match: make glob '**/' match the empty string
Siddharth Agarwal <sid0@fb.com>
parents: 21191
diff changeset
1152 res += '.*'
8570
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
1153 else:
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
1154 res += '[^/]*'
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
1155 elif c == '?':
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
1156 res += '.'
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
1157 elif c == '[':
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
1158 j = i
31421
5c9cda37d7f6 match: slice over bytes to get the byteschr instead of ascii value
Pulkit Goyal <7895pulkit@gmail.com>
parents: 31420
diff changeset
1159 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
1160 j += 1
31421
5c9cda37d7f6 match: slice over bytes to get the byteschr instead of ascii value
Pulkit Goyal <7895pulkit@gmail.com>
parents: 31420
diff changeset
1161 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
1162 j += 1
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
1163 if j >= n:
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
1164 res += '\\['
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
1165 else:
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
1166 stuff = pat[i:j].replace('\\','\\\\')
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
1167 i = j + 1
31421
5c9cda37d7f6 match: slice over bytes to get the byteschr instead of ascii value
Pulkit Goyal <7895pulkit@gmail.com>
parents: 31420
diff changeset
1168 if stuff[0:1] == '!':
8570
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
1169 stuff = '^' + stuff[1:]
31421
5c9cda37d7f6 match: slice over bytes to get the byteschr instead of ascii value
Pulkit Goyal <7895pulkit@gmail.com>
parents: 31420
diff changeset
1170 elif stuff[0:1] == '^':
8570
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
1171 stuff = '\\' + stuff
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
1172 res = '%s[%s]' % (res, stuff)
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
1173 elif c == '{':
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
1174 group += 1
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
1175 res += '(?:'
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
1176 elif c == '}' and group:
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
1177 res += ')'
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
1178 group -= 1
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
1179 elif c == ',' and group:
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
1180 res += '|'
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
1181 elif c == '\\':
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
1182 p = peek()
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
1183 if p:
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
1184 i += 1
40684
e6c9ef5e11a0 match: provide and use a quick way to escape a single byte
Boris Feld <boris.feld@octobus.net>
parents: 40345
diff changeset
1185 res += escape(p, p)
8570
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
1186 else:
40684
e6c9ef5e11a0 match: provide and use a quick way to escape a single byte
Boris Feld <boris.feld@octobus.net>
parents: 40345
diff changeset
1187 res += escape(c, c)
8570
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
1188 else:
40684
e6c9ef5e11a0 match: provide and use a quick way to escape a single byte
Boris Feld <boris.feld@octobus.net>
parents: 40345
diff changeset
1189 res += escape(c, c)
8582
a4c199e12b5a match: remove head and tail args from _globre
Matt Mackall <mpm@selenic.com>
parents: 8581
diff changeset
1190 return res
8570
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
1191
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
1192 def _regex(kind, pat, globsuffix):
42329
c7652f7440d9 rust-filepatterns: call new Rust implementations from Python
Raphaël Gomès <rgomes@octobus.net>
parents: 42195
diff changeset
1193 '''Convert a (normalized) pattern of any kind into a
c7652f7440d9 rust-filepatterns: call new Rust implementations from Python
Raphaël Gomès <rgomes@octobus.net>
parents: 42195
diff changeset
1194 regular expression.
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
1195 globsuffix is appended to the regexp of globs.'''
42329
c7652f7440d9 rust-filepatterns: call new Rust implementations from Python
Raphaël Gomès <rgomes@octobus.net>
parents: 42195
diff changeset
1196
42452
a3a8887e4426 rust: using policy.importrust from Python callers
Georges Racinet <georges.racinet@octobus.net>
parents: 42367
diff changeset
1197 if rustmod is not None:
42329
c7652f7440d9 rust-filepatterns: call new Rust implementations from Python
Raphaël Gomès <rgomes@octobus.net>
parents: 42195
diff changeset
1198 try:
42452
a3a8887e4426 rust: using policy.importrust from Python callers
Georges Racinet <georges.racinet@octobus.net>
parents: 42367
diff changeset
1199 return rustmod.build_single_regex(
42329
c7652f7440d9 rust-filepatterns: call new Rust implementations from Python
Raphaël Gomès <rgomes@octobus.net>
parents: 42195
diff changeset
1200 kind,
c7652f7440d9 rust-filepatterns: call new Rust implementations from Python
Raphaël Gomès <rgomes@octobus.net>
parents: 42195
diff changeset
1201 pat,
c7652f7440d9 rust-filepatterns: call new Rust implementations from Python
Raphaël Gomès <rgomes@octobus.net>
parents: 42195
diff changeset
1202 globsuffix
c7652f7440d9 rust-filepatterns: call new Rust implementations from Python
Raphaël Gomès <rgomes@octobus.net>
parents: 42195
diff changeset
1203 )
42452
a3a8887e4426 rust: using policy.importrust from Python callers
Georges Racinet <georges.racinet@octobus.net>
parents: 42367
diff changeset
1204 except rustmod.PatternError:
42329
c7652f7440d9 rust-filepatterns: call new Rust implementations from Python
Raphaël Gomès <rgomes@octobus.net>
parents: 42195
diff changeset
1205 raise error.ProgrammingError(
c7652f7440d9 rust-filepatterns: call new Rust implementations from Python
Raphaël Gomès <rgomes@octobus.net>
parents: 42195
diff changeset
1206 'not a regex pattern: %s:%s' % (kind, pat)
c7652f7440d9 rust-filepatterns: call new Rust implementations from Python
Raphaël Gomès <rgomes@octobus.net>
parents: 42195
diff changeset
1207 )
c7652f7440d9 rust-filepatterns: call new Rust implementations from Python
Raphaël Gomès <rgomes@octobus.net>
parents: 42195
diff changeset
1208
42341
27d6956d386b match: use '' instead of '.' for root directory (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 42329
diff changeset
1209 if not pat and kind in ('glob', 'relpath'):
8574
63a7ed2128d5 match: unnest functions in _matcher
Matt Mackall <mpm@selenic.com>
parents: 8573
diff changeset
1210 return ''
63a7ed2128d5 match: unnest functions in _matcher
Matt Mackall <mpm@selenic.com>
parents: 8573
diff changeset
1211 if kind == 're':
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
1212 return pat
33358
38b6122df5c7 match: combine regex code for path: and relpath:
Martin von Zweigbergk <martinvonz@google.com>
parents: 33357
diff changeset
1213 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
1214 if pat == '.':
bfe9ed85f27c match: let 'path:.' and 'path:' match everything (issue4687)
Matt Harbison <matt_harbison@yahoo.com>
parents: 25194
diff changeset
1215 return ''
38475
67dc32d4e790 cleanup: migrate from re.escape to stringutil.reescape
Augie Fackler <augie@google.com>
parents: 38019
diff changeset
1216 return util.stringutil.reescape(pat) + '(?:/|$)'
31012
88358446da16 match: adding support for matching files inside a directory
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 30399
diff changeset
1217 if kind == 'rootfilesin':
88358446da16 match: adding support for matching files inside a directory
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 30399
diff changeset
1218 if pat == '.':
88358446da16 match: adding support for matching files inside a directory
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 30399
diff changeset
1219 escaped = ''
88358446da16 match: adding support for matching files inside a directory
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 30399
diff changeset
1220 else:
88358446da16 match: adding support for matching files inside a directory
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 30399
diff changeset
1221 # Pattern is a directory name.
38475
67dc32d4e790 cleanup: migrate from re.escape to stringutil.reescape
Augie Fackler <augie@google.com>
parents: 38019
diff changeset
1222 escaped = util.stringutil.reescape(pat) + '/'
31012
88358446da16 match: adding support for matching files inside a directory
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 30399
diff changeset
1223 # 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
1224 return escaped + '[^/]+$'
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
1225 if kind == 'relglob':
42864
72890d8f9860 match: simplify the regexps created for glob patterns
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 42766
diff changeset
1226 globre = _globre(pat)
72890d8f9860 match: simplify the regexps created for glob patterns
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 42766
diff changeset
1227 if globre.startswith('[^/]*'):
72890d8f9860 match: simplify the regexps created for glob patterns
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 42766
diff changeset
1228 # When pat has the form *XYZ (common), make the returned regex more
72890d8f9860 match: simplify the regexps created for glob patterns
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 42766
diff changeset
1229 # legible by returning the regex for **XYZ instead of **/*XYZ.
72890d8f9860 match: simplify the regexps created for glob patterns
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 42766
diff changeset
1230 return '.*' + globre[len('[^/]*'):] + globsuffix
72890d8f9860 match: simplify the regexps created for glob patterns
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 42766
diff changeset
1231 return '(?:|.*/)' + globre + globsuffix
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
1232 if kind == 'relre':
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
1233 if pat.startswith('^'):
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
1234 return pat
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
1235 return '.*' + pat
41282
4fab8a7d2d72 match: support rooted globs in hgignore
Valentin Gatien-Baron <vgatien-baron@janestreet.com>
parents: 41129
diff changeset
1236 if kind in ('glob', 'rootglob'):
38578
2d487b9cac07 match: explode if unsupported pattern passed down to _regex() builder
Yuya Nishihara <yuya@tcha.org>
parents: 38577
diff changeset
1237 return _globre(pat) + globsuffix
2d487b9cac07 match: explode if unsupported pattern passed down to _regex() builder
Yuya Nishihara <yuya@tcha.org>
parents: 38577
diff changeset
1238 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
1239
41669
a13268524c25 match: delete unused argument "listsubrepos" from _buildmatch()
Martin von Zweigbergk <martinvonz@google.com>
parents: 41668
diff changeset
1240 def _buildmatch(kindpats, globsuffix, root):
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
1241 '''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
1242 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
1243 matchfuncs = []
714f612f2afc match: allow unioning arbitrary match functions
Durham Goode <durham@fb.com>
parents: 25238
diff changeset
1244
25283
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
1245 subincludes, kindpats = _expandsubinclude(kindpats, root)
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
1246 if subincludes:
32132
6dea1701f170 match: make subinclude construction lazy
Durham Goode <durham@fb.com>
parents: 31433
diff changeset
1247 submatchers = {}
25283
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
1248 def matchsubinclude(f):
32132
6dea1701f170 match: make subinclude construction lazy
Durham Goode <durham@fb.com>
parents: 31433
diff changeset
1249 for prefix, matcherargs in subincludes:
6dea1701f170 match: make subinclude construction lazy
Durham Goode <durham@fb.com>
parents: 31433
diff changeset
1250 if f.startswith(prefix):
6dea1701f170 match: make subinclude construction lazy
Durham Goode <durham@fb.com>
parents: 31433
diff changeset
1251 mf = submatchers.get(prefix)
6dea1701f170 match: make subinclude construction lazy
Durham Goode <durham@fb.com>
parents: 31433
diff changeset
1252 if mf is None:
6dea1701f170 match: make subinclude construction lazy
Durham Goode <durham@fb.com>
parents: 31433
diff changeset
1253 mf = match(*matcherargs)
6dea1701f170 match: make subinclude construction lazy
Durham Goode <durham@fb.com>
parents: 31433
diff changeset
1254 submatchers[prefix] = mf
6dea1701f170 match: make subinclude construction lazy
Durham Goode <durham@fb.com>
parents: 31433
diff changeset
1255
6dea1701f170 match: make subinclude construction lazy
Durham Goode <durham@fb.com>
parents: 31433
diff changeset
1256 if mf(f[len(prefix):]):
6dea1701f170 match: make subinclude construction lazy
Durham Goode <durham@fb.com>
parents: 31433
diff changeset
1257 return True
25283
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
1258 return False
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
1259 matchfuncs.append(matchsubinclude)
14675
cfc89398f710 match: introduce basic fileset support
Matt Mackall <mpm@selenic.com>
parents: 14674
diff changeset
1260
25239
714f612f2afc match: allow unioning arbitrary match functions
Durham Goode <durham@fb.com>
parents: 25238
diff changeset
1261 regex = ''
714f612f2afc match: allow unioning arbitrary match functions
Durham Goode <durham@fb.com>
parents: 25238
diff changeset
1262 if kindpats:
40242
19ed212de2d1 match: optimize matcher when all patterns are of rootfilesin kind
Martin von Zweigbergk <martinvonz@google.com>
parents: 39460
diff changeset
1263 if all(k == 'rootfilesin' for k, p, s in kindpats):
19ed212de2d1 match: optimize matcher when all patterns are of rootfilesin kind
Martin von Zweigbergk <martinvonz@google.com>
parents: 39460
diff changeset
1264 dirs = {p for k, p, s in kindpats}
19ed212de2d1 match: optimize matcher when all patterns are of rootfilesin kind
Martin von Zweigbergk <martinvonz@google.com>
parents: 39460
diff changeset
1265 def mf(f):
19ed212de2d1 match: optimize matcher when all patterns are of rootfilesin kind
Martin von Zweigbergk <martinvonz@google.com>
parents: 39460
diff changeset
1266 i = f.rfind('/')
19ed212de2d1 match: optimize matcher when all patterns are of rootfilesin kind
Martin von Zweigbergk <martinvonz@google.com>
parents: 39460
diff changeset
1267 if i >= 0:
19ed212de2d1 match: optimize matcher when all patterns are of rootfilesin kind
Martin von Zweigbergk <martinvonz@google.com>
parents: 39460
diff changeset
1268 dir = f[:i]
19ed212de2d1 match: optimize matcher when all patterns are of rootfilesin kind
Martin von Zweigbergk <martinvonz@google.com>
parents: 39460
diff changeset
1269 else:
19ed212de2d1 match: optimize matcher when all patterns are of rootfilesin kind
Martin von Zweigbergk <martinvonz@google.com>
parents: 39460
diff changeset
1270 dir = '.'
19ed212de2d1 match: optimize matcher when all patterns are of rootfilesin kind
Martin von Zweigbergk <martinvonz@google.com>
parents: 39460
diff changeset
1271 return dir in dirs
40345
d30a19d10441 match: fix up a repr to not crash on Python 3
Augie Fackler <augie@google.com>
parents: 40242
diff changeset
1272 regex = b'rootfilesin: %s' % stringutil.pprint(list(sorted(dirs)))
40242
19ed212de2d1 match: optimize matcher when all patterns are of rootfilesin kind
Martin von Zweigbergk <martinvonz@google.com>
parents: 39460
diff changeset
1273 matchfuncs.append(mf)
19ed212de2d1 match: optimize matcher when all patterns are of rootfilesin kind
Martin von Zweigbergk <martinvonz@google.com>
parents: 39460
diff changeset
1274 else:
19ed212de2d1 match: optimize matcher when all patterns are of rootfilesin kind
Martin von Zweigbergk <martinvonz@google.com>
parents: 39460
diff changeset
1275 regex, mf = _buildregexmatch(kindpats, globsuffix)
19ed212de2d1 match: optimize matcher when all patterns are of rootfilesin kind
Martin von Zweigbergk <martinvonz@google.com>
parents: 39460
diff changeset
1276 matchfuncs.append(mf)
25239
714f612f2afc match: allow unioning arbitrary match functions
Durham Goode <durham@fb.com>
parents: 25238
diff changeset
1277
714f612f2afc match: allow unioning arbitrary match functions
Durham Goode <durham@fb.com>
parents: 25238
diff changeset
1278 if len(matchfuncs) == 1:
714f612f2afc match: allow unioning arbitrary match functions
Durham Goode <durham@fb.com>
parents: 25238
diff changeset
1279 return regex, matchfuncs[0]
714f612f2afc match: allow unioning arbitrary match functions
Durham Goode <durham@fb.com>
parents: 25238
diff changeset
1280 else:
714f612f2afc match: allow unioning arbitrary match functions
Durham Goode <durham@fb.com>
parents: 25238
diff changeset
1281 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
1282
40774
8306dac48061 match: extract a literal constant into a symbolic one
Boris Feld <boris.feld@octobus.net>
parents: 40757
diff changeset
1283 MAX_RE_SIZE = 20000
8306dac48061 match: extract a literal constant into a symbolic one
Boris Feld <boris.feld@octobus.net>
parents: 40757
diff changeset
1284
40776
ce401300f981 match: extract function that group regexps
Boris Feld <boris.feld@octobus.net>
parents: 40775
diff changeset
1285 def _joinregexes(regexps):
ce401300f981 match: extract function that group regexps
Boris Feld <boris.feld@octobus.net>
parents: 40775
diff changeset
1286 """gather multiple regular expressions into a single one"""
40782
3984409e144b match: drop unnecessary wrapping of regex in group
Martin von Zweigbergk <martinvonz@google.com>
parents: 40781
diff changeset
1287 return '|'.join(regexps)
40776
ce401300f981 match: extract function that group regexps
Boris Feld <boris.feld@octobus.net>
parents: 40775
diff changeset
1288
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
1289 def _buildregexmatch(kindpats, globsuffix):
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
1290 """Build a match function from a list of kinds and kindpats,
40775
4e02f25f31c6 match: test for overflow error in pattern
Boris Feld <boris.feld@octobus.net>
parents: 40774
diff changeset
1291 return regexp string and a matcher function.
4e02f25f31c6 match: test for overflow error in pattern
Boris Feld <boris.feld@octobus.net>
parents: 40774
diff changeset
1292
4e02f25f31c6 match: test for overflow error in pattern
Boris Feld <boris.feld@octobus.net>
parents: 40774
diff changeset
1293 Test too large input
4e02f25f31c6 match: test for overflow error in pattern
Boris Feld <boris.feld@octobus.net>
parents: 40774
diff changeset
1294 >>> _buildregexmatch([
40947
9e462fb88f79 match: fix doctest to use bytes instead of str
Augie Fackler <augie@google.com>
parents: 40782
diff changeset
1295 ... (b'relglob', b'?' * MAX_RE_SIZE, b'')
9e462fb88f79 match: fix doctest to use bytes instead of str
Augie Fackler <augie@google.com>
parents: 40782
diff changeset
1296 ... ], b'$')
40775
4e02f25f31c6 match: test for overflow error in pattern
Boris Feld <boris.feld@octobus.net>
parents: 40774
diff changeset
1297 Traceback (most recent call last):
4e02f25f31c6 match: test for overflow error in pattern
Boris Feld <boris.feld@octobus.net>
parents: 40774
diff changeset
1298 ...
40778
69bd3176da7c match: raise an Abort error instead of OverflowError
Boris Feld <boris.feld@octobus.net>
parents: 40777
diff changeset
1299 Abort: matcher pattern is too long (20009 bytes)
40775
4e02f25f31c6 match: test for overflow error in pattern
Boris Feld <boris.feld@octobus.net>
parents: 40774
diff changeset
1300 """
8574
63a7ed2128d5 match: unnest functions in _matcher
Matt Mackall <mpm@selenic.com>
parents: 8573
diff changeset
1301 try:
40777
3c842749debc match: avoid translating glob to matcher multiple times for large sets
Boris Feld <boris.feld@octobus.net>
parents: 40776
diff changeset
1302 allgroups = []
3c842749debc match: avoid translating glob to matcher multiple times for large sets
Boris Feld <boris.feld@octobus.net>
parents: 40776
diff changeset
1303 regexps = [_regex(k, p, globsuffix) for (k, p, s) in kindpats]
3c842749debc match: avoid translating glob to matcher multiple times for large sets
Boris Feld <boris.feld@octobus.net>
parents: 40776
diff changeset
1304 fullregexp = _joinregexes(regexps)
3c842749debc match: avoid translating glob to matcher multiple times for large sets
Boris Feld <boris.feld@octobus.net>
parents: 40776
diff changeset
1305
3c842749debc match: avoid translating glob to matcher multiple times for large sets
Boris Feld <boris.feld@octobus.net>
parents: 40776
diff changeset
1306 startidx = 0
40782
3984409e144b match: drop unnecessary wrapping of regex in group
Martin von Zweigbergk <martinvonz@google.com>
parents: 40781
diff changeset
1307 groupsize = 0
40777
3c842749debc match: avoid translating glob to matcher multiple times for large sets
Boris Feld <boris.feld@octobus.net>
parents: 40776
diff changeset
1308 for idx, r in enumerate(regexps):
3c842749debc match: avoid translating glob to matcher multiple times for large sets
Boris Feld <boris.feld@octobus.net>
parents: 40776
diff changeset
1309 piecesize = len(r)
40782
3984409e144b match: drop unnecessary wrapping of regex in group
Martin von Zweigbergk <martinvonz@google.com>
parents: 40781
diff changeset
1310 if piecesize > MAX_RE_SIZE:
40778
69bd3176da7c match: raise an Abort error instead of OverflowError
Boris Feld <boris.feld@octobus.net>
parents: 40777
diff changeset
1311 msg = _("matcher pattern is too long (%d bytes)") % piecesize
69bd3176da7c match: raise an Abort error instead of OverflowError
Boris Feld <boris.feld@octobus.net>
parents: 40777
diff changeset
1312 raise error.Abort(msg)
40780
1e019f45fa88 match: make "groupsize" include the trailing "|"
Martin von Zweigbergk <martinvonz@google.com>
parents: 40779
diff changeset
1313 elif (groupsize + piecesize) > MAX_RE_SIZE:
40777
3c842749debc match: avoid translating glob to matcher multiple times for large sets
Boris Feld <boris.feld@octobus.net>
parents: 40776
diff changeset
1314 group = regexps[startidx:idx]
3c842749debc match: avoid translating glob to matcher multiple times for large sets
Boris Feld <boris.feld@octobus.net>
parents: 40776
diff changeset
1315 allgroups.append(_joinregexes(group))
3c842749debc match: avoid translating glob to matcher multiple times for large sets
Boris Feld <boris.feld@octobus.net>
parents: 40776
diff changeset
1316 startidx = idx
40782
3984409e144b match: drop unnecessary wrapping of regex in group
Martin von Zweigbergk <martinvonz@google.com>
parents: 40781
diff changeset
1317 groupsize = 0
40777
3c842749debc match: avoid translating glob to matcher multiple times for large sets
Boris Feld <boris.feld@octobus.net>
parents: 40776
diff changeset
1318 groupsize += piecesize + 1
3c842749debc match: avoid translating glob to matcher multiple times for large sets
Boris Feld <boris.feld@octobus.net>
parents: 40776
diff changeset
1319
3c842749debc match: avoid translating glob to matcher multiple times for large sets
Boris Feld <boris.feld@octobus.net>
parents: 40776
diff changeset
1320 if startidx == 0:
42087
2e2699af5649 match: let regex match function return a boolean
Denis Laxalde <denis@laxalde.org>
parents: 42086
diff changeset
1321 matcher = _rematcher(fullregexp)
42099
bccb322f1496 match: fix re2 compability broken in 2e2699af5649
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 42098
diff changeset
1322 func = lambda s: bool(matcher(s))
40777
3c842749debc match: avoid translating glob to matcher multiple times for large sets
Boris Feld <boris.feld@octobus.net>
parents: 40776
diff changeset
1323 else:
3c842749debc match: avoid translating glob to matcher multiple times for large sets
Boris Feld <boris.feld@octobus.net>
parents: 40776
diff changeset
1324 group = regexps[startidx:]
3c842749debc match: avoid translating glob to matcher multiple times for large sets
Boris Feld <boris.feld@octobus.net>
parents: 40776
diff changeset
1325 allgroups.append(_joinregexes(group))
3c842749debc match: avoid translating glob to matcher multiple times for large sets
Boris Feld <boris.feld@octobus.net>
parents: 40776
diff changeset
1326 allmatchers = [_rematcher(g) for g in allgroups]
3c842749debc match: avoid translating glob to matcher multiple times for large sets
Boris Feld <boris.feld@octobus.net>
parents: 40776
diff changeset
1327 func = lambda s: any(m(s) for m in allmatchers)
3c842749debc match: avoid translating glob to matcher multiple times for large sets
Boris Feld <boris.feld@octobus.net>
parents: 40776
diff changeset
1328 return fullregexp, func
8574
63a7ed2128d5 match: unnest functions in _matcher
Matt Mackall <mpm@selenic.com>
parents: 8573
diff changeset
1329 except re.error:
25213
08a8e9da0ae7 match: add source to kindpats list
Durham Goode <durham@fb.com>
parents: 25195
diff changeset
1330 for k, p, s in kindpats:
8574
63a7ed2128d5 match: unnest functions in _matcher
Matt Mackall <mpm@selenic.com>
parents: 8573
diff changeset
1331 try:
40782
3984409e144b match: drop unnecessary wrapping of regex in group
Martin von Zweigbergk <martinvonz@google.com>
parents: 40781
diff changeset
1332 _rematcher(_regex(k, p, globsuffix))
8574
63a7ed2128d5 match: unnest functions in _matcher
Matt Mackall <mpm@selenic.com>
parents: 8573
diff changeset
1333 except re.error:
25213
08a8e9da0ae7 match: add source to kindpats list
Durham Goode <durham@fb.com>
parents: 25195
diff changeset
1334 if s:
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26014
diff changeset
1335 raise error.Abort(_("%s: invalid pattern (%s): %s") %
40779
e8c992d56465 match: fix an unaligned (but harmless) indent
Martin von Zweigbergk <martinvonz@google.com>
parents: 40778
diff changeset
1336 (s, k, p))
25213
08a8e9da0ae7 match: add source to kindpats list
Durham Goode <durham@fb.com>
parents: 25195
diff changeset
1337 else:
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26014
diff changeset
1338 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
1339 raise error.Abort(_("invalid pattern"))
8574
63a7ed2128d5 match: unnest functions in _matcher
Matt Mackall <mpm@selenic.com>
parents: 8573
diff changeset
1340
31013
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31012
diff changeset
1341 def _patternrootsanddirs(kindpats):
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31012
diff changeset
1342 '''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
1343
31013
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31012
diff changeset
1344 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: 31012
diff changeset
1345 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: 31012
diff changeset
1346 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: 31012
diff changeset
1347 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
1348 '''
8576
ec4ed21db4b2 match: split up _normalizepats
Matt Mackall <mpm@selenic.com>
parents: 8575
diff changeset
1349 r = []
31013
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31012
diff changeset
1350 d = []
25213
08a8e9da0ae7 match: add source to kindpats list
Durham Goode <durham@fb.com>
parents: 25195
diff changeset
1351 for kind, pat, source in kindpats:
41282
4fab8a7d2d72 match: support rooted globs in hgignore
Valentin Gatien-Baron <vgatien-baron@janestreet.com>
parents: 41129
diff changeset
1352 if kind in ('glob', 'rootglob'): # find the non-glob prefix
8584
0f06e72abfdc match: fold _globprefix into _roots
Matt Mackall <mpm@selenic.com>
parents: 8583
diff changeset
1353 root = []
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
1354 for p in pat.split('/'):
8584
0f06e72abfdc match: fold _globprefix into _roots
Matt Mackall <mpm@selenic.com>
parents: 8583
diff changeset
1355 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
1356 break
0f06e72abfdc match: fold _globprefix into _roots
Matt Mackall <mpm@selenic.com>
parents: 8583
diff changeset
1357 root.append(p)
42341
27d6956d386b match: use '' instead of '.' for root directory (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 42329
diff changeset
1358 r.append('/'.join(root))
31013
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31012
diff changeset
1359 elif kind in ('relpath', 'path'):
42341
27d6956d386b match: use '' instead of '.' for root directory (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 42329
diff changeset
1360 if pat == '.':
27d6956d386b match: use '' instead of '.' for root directory (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 42329
diff changeset
1361 pat = ''
27d6956d386b match: use '' instead of '.' for root directory (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 42329
diff changeset
1362 r.append(pat)
31013
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31012
diff changeset
1363 elif kind in ('rootfilesin',):
42341
27d6956d386b match: use '' instead of '.' for root directory (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 42329
diff changeset
1364 if pat == '.':
27d6956d386b match: use '' instead of '.' for root directory (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 42329
diff changeset
1365 pat = ''
27d6956d386b match: use '' instead of '.' for root directory (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 42329
diff changeset
1366 d.append(pat)
19107
fcf08023c011 match: fix root calculation for combining regexps with simple paths
Mads Kiilerich <madski@unity3d.com>
parents: 18713
diff changeset
1367 else: # relglob, re, relre
42341
27d6956d386b match: use '' instead of '.' for root directory (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 42329
diff changeset
1368 r.append('')
31013
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31012
diff changeset
1369 return r, d
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31012
diff changeset
1370
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31012
diff changeset
1371 def _roots(kindpats):
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31012
diff changeset
1372 '''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: 31012
diff changeset
1373 roots, dirs = _patternrootsanddirs(kindpats)
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31012
diff changeset
1374 return roots
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31012
diff changeset
1375
38954
5a7df82de142 includematcher: separate "parents" from "dirs"
spectral <spectral@google.com>
parents: 38750
diff changeset
1376 def _rootsdirsandparents(kindpats):
31013
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31012
diff changeset
1377 '''Returns roots and exact directories from patterns.
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31012
diff changeset
1378
38957
f356be1a7ba3 match: correct doc for _rootsdirsandparents after 5a7df82de142
Kyle Lippincott <spectral@google.com>
parents: 38955
diff changeset
1379 `roots` are directories to match recursively, `dirs` should
f356be1a7ba3 match: correct doc for _rootsdirsandparents after 5a7df82de142
Kyle Lippincott <spectral@google.com>
parents: 38955
diff changeset
1380 be matched non-recursively, and `parents` are the implicitly required
f356be1a7ba3 match: correct doc for _rootsdirsandparents after 5a7df82de142
Kyle Lippincott <spectral@google.com>
parents: 38955
diff changeset
1381 directories to walk to items in either roots or dirs.
f356be1a7ba3 match: correct doc for _rootsdirsandparents after 5a7df82de142
Kyle Lippincott <spectral@google.com>
parents: 38955
diff changeset
1382
f356be1a7ba3 match: correct doc for _rootsdirsandparents after 5a7df82de142
Kyle Lippincott <spectral@google.com>
parents: 38955
diff changeset
1383 Returns a tuple of (roots, dirs, parents).
31013
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31012
diff changeset
1384
42367
96fc696a9cb2 match: stabilize _rootsdirsandparents doctest
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 42362
diff changeset
1385 >>> r = _rootsdirsandparents(
34131
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33684
diff changeset
1386 ... [(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: 33684
diff changeset
1387 ... (b'glob', b'g*', b'')])
42367
96fc696a9cb2 match: stabilize _rootsdirsandparents doctest
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 42362
diff changeset
1388 >>> print(r[0:2], sorted(r[2])) # the set has an unstable output
96fc696a9cb2 match: stabilize _rootsdirsandparents doctest
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 42362
diff changeset
1389 (['g/h', 'g/h', ''], []) ['', 'g']
96fc696a9cb2 match: stabilize _rootsdirsandparents doctest
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 42362
diff changeset
1390 >>> r = _rootsdirsandparents(
34131
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33684
diff changeset
1391 ... [(b'rootfilesin', b'g/h', b''), (b'rootfilesin', b'', b'')])
42367
96fc696a9cb2 match: stabilize _rootsdirsandparents doctest
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 42362
diff changeset
1392 >>> print(r[0:2], sorted(r[2])) # the set has an unstable output
96fc696a9cb2 match: stabilize _rootsdirsandparents doctest
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 42362
diff changeset
1393 ([], ['g/h', '']) ['', 'g']
96fc696a9cb2 match: stabilize _rootsdirsandparents doctest
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 42362
diff changeset
1394 >>> r = _rootsdirsandparents(
34131
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33684
diff changeset
1395 ... [(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: 33684
diff changeset
1396 ... (b'path', b'', b'')])
42367
96fc696a9cb2 match: stabilize _rootsdirsandparents doctest
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 42362
diff changeset
1397 >>> print(r[0:2], sorted(r[2])) # the set has an unstable output
96fc696a9cb2 match: stabilize _rootsdirsandparents doctest
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 42362
diff changeset
1398 (['r', 'p/p', ''], []) ['', 'p']
96fc696a9cb2 match: stabilize _rootsdirsandparents doctest
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 42362
diff changeset
1399 >>> r = _rootsdirsandparents(
34131
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33684
diff changeset
1400 ... [(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: 33684
diff changeset
1401 ... (b'relre', b'rr', b'')])
42367
96fc696a9cb2 match: stabilize _rootsdirsandparents doctest
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 42362
diff changeset
1402 >>> print(r[0:2], sorted(r[2])) # the set has an unstable output
96fc696a9cb2 match: stabilize _rootsdirsandparents doctest
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 42362
diff changeset
1403 (['', '', ''], []) ['']
31013
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31012
diff changeset
1404 '''
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31012
diff changeset
1405 r, d = _patternrootsanddirs(kindpats)
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31012
diff changeset
1406
42361
c4b8f8637d7a match: de-flake test-doctest.py by not depending on util.dirs() order
Martin von Zweigbergk <martinvonz@google.com>
parents: 42346
diff changeset
1407 p = set()
c4b8f8637d7a match: de-flake test-doctest.py by not depending on util.dirs() order
Martin von Zweigbergk <martinvonz@google.com>
parents: 42346
diff changeset
1408 # Add the parents as non-recursive/exact directories, since they must be
31013
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31012
diff changeset
1409 # scanned to get to either the roots or the other exact directories.
42361
c4b8f8637d7a match: de-flake test-doctest.py by not depending on util.dirs() order
Martin von Zweigbergk <martinvonz@google.com>
parents: 42346
diff changeset
1410 p.update(util.dirs(d))
c4b8f8637d7a match: de-flake test-doctest.py by not depending on util.dirs() order
Martin von Zweigbergk <martinvonz@google.com>
parents: 42346
diff changeset
1411 p.update(util.dirs(r))
31013
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31012
diff changeset
1412
39460
35ecaa999a12 match: improve includematcher.visitchildrenset to be much faster and cached
Kyle Lippincott <spectral@google.com>
parents: 39261
diff changeset
1413 # FIXME: all uses of this function convert these to sets, do so before
35ecaa999a12 match: improve includematcher.visitchildrenset to be much faster and cached
Kyle Lippincott <spectral@google.com>
parents: 39261
diff changeset
1414 # returning.
35ecaa999a12 match: improve includematcher.visitchildrenset to be much faster and cached
Kyle Lippincott <spectral@google.com>
parents: 39261
diff changeset
1415 # FIXME: all uses of this function do not need anything in 'roots' and
35ecaa999a12 match: improve includematcher.visitchildrenset to be much faster and cached
Kyle Lippincott <spectral@google.com>
parents: 39261
diff changeset
1416 # 'dirs' to also be in 'parents', consider removing them before returning.
38954
5a7df82de142 includematcher: separate "parents" from "dirs"
spectral <spectral@google.com>
parents: 38750
diff changeset
1417 return r, d, p
8576
ec4ed21db4b2 match: split up _normalizepats
Matt Mackall <mpm@selenic.com>
parents: 8575
diff changeset
1418
31012
88358446da16 match: adding support for matching files inside a directory
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 30399
diff changeset
1419 def _explicitfiles(kindpats):
88358446da16 match: adding support for matching files inside a directory
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 30399
diff changeset
1420 '''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: 30399
diff changeset
1421
34131
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33684
diff changeset
1422 >>> _explicitfiles([(b'path', b'foo/bar', b'')])
31012
88358446da16 match: adding support for matching files inside a directory
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 30399
diff changeset
1423 ['foo/bar']
34131
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33684
diff changeset
1424 >>> _explicitfiles([(b'rootfilesin', b'foo/bar', b'')])
31012
88358446da16 match: adding support for matching files inside a directory
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 30399
diff changeset
1425 []
88358446da16 match: adding support for matching files inside a directory
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 30399
diff changeset
1426 '''
88358446da16 match: adding support for matching files inside a directory
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 30399
diff changeset
1427 # 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: 30399
diff changeset
1428 # directory names).
88358446da16 match: adding support for matching files inside a directory
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 30399
diff changeset
1429 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: 30399
diff changeset
1430 return _roots(filable)
88358446da16 match: adding support for matching files inside a directory
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 30399
diff changeset
1431
33405
6aa643762641 match: inverse _anypats(), making it _prefix()
Martin von Zweigbergk <martinvonz@google.com>
parents: 33380
diff changeset
1432 def _prefix(kindpats):
6aa643762641 match: inverse _anypats(), making it _prefix()
Martin von Zweigbergk <martinvonz@google.com>
parents: 33380
diff changeset
1433 '''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
1434 for kind, pat, source in kindpats:
33405
6aa643762641 match: inverse _anypats(), making it _prefix()
Martin von Zweigbergk <martinvonz@google.com>
parents: 33380
diff changeset
1435 if kind not in ('path', 'relpath'):
6aa643762641 match: inverse _anypats(), making it _prefix()
Martin von Zweigbergk <martinvonz@google.com>
parents: 33380
diff changeset
1436 return False
6aa643762641 match: inverse _anypats(), making it _prefix()
Martin von Zweigbergk <martinvonz@google.com>
parents: 33380
diff changeset
1437 return True
25167
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
1438
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
1439 _commentre = None
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
1440
27595
9e2d01707e71 match: add option to return line and lineno from readpattern
Laurent Charignon <lcharignon@fb.com>
parents: 27343
diff changeset
1441 def readpatternfile(filepath, warn, sourceinfo=False):
25167
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
1442 '''parse a pattern file, returning a list of
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
1443 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
1444 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
1445
dc562165044a ignore: use 'include:' rules instead of custom syntax
Durham Goode <durham@fb.com>
parents: 25215
diff changeset
1446 trailing white space is dropped.
dc562165044a ignore: use 'include:' rules instead of custom syntax
Durham Goode <durham@fb.com>
parents: 25215
diff changeset
1447 the escape character is backslash.
dc562165044a ignore: use 'include:' rules instead of custom syntax
Durham Goode <durham@fb.com>
parents: 25215
diff changeset
1448 comments start with #.
dc562165044a ignore: use 'include:' rules instead of custom syntax
Durham Goode <durham@fb.com>
parents: 25215
diff changeset
1449 empty lines are skipped.
dc562165044a ignore: use 'include:' rules instead of custom syntax
Durham Goode <durham@fb.com>
parents: 25215
diff changeset
1450
dc562165044a ignore: use 'include:' rules instead of custom syntax
Durham Goode <durham@fb.com>
parents: 25215
diff changeset
1451 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
1452
dc562165044a ignore: use 'include:' rules instead of custom syntax
Durham Goode <durham@fb.com>
parents: 25215
diff changeset
1453 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
1454 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
1455 re:pattern # non-rooted regular expression
dc562165044a ignore: use 'include:' rules instead of custom syntax
Durham Goode <durham@fb.com>
parents: 25215
diff changeset
1456 glob:pattern # non-rooted glob
41282
4fab8a7d2d72 match: support rooted globs in hgignore
Valentin Gatien-Baron <vgatien-baron@janestreet.com>
parents: 41129
diff changeset
1457 rootglob:pat # rooted glob (same root as ^ in regexps)
27595
9e2d01707e71 match: add option to return line and lineno from readpattern
Laurent Charignon <lcharignon@fb.com>
parents: 27343
diff changeset
1458 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
1459
9e2d01707e71 match: add option to return line and lineno from readpattern
Laurent Charignon <lcharignon@fb.com>
parents: 27343
diff changeset
1460 if sourceinfo is set, returns a list of tuples:
42329
c7652f7440d9 rust-filepatterns: call new Rust implementations from Python
Raphaël Gomès <rgomes@octobus.net>
parents: 42195
diff changeset
1461 (pattern, lineno, originalline).
c7652f7440d9 rust-filepatterns: call new Rust implementations from Python
Raphaël Gomès <rgomes@octobus.net>
parents: 42195
diff changeset
1462 This is useful to debug ignore patterns.
27595
9e2d01707e71 match: add option to return line and lineno from readpattern
Laurent Charignon <lcharignon@fb.com>
parents: 27343
diff changeset
1463 '''
25216
dc562165044a ignore: use 'include:' rules instead of custom syntax
Durham Goode <durham@fb.com>
parents: 25215
diff changeset
1464
42452
a3a8887e4426 rust: using policy.importrust from Python callers
Georges Racinet <georges.racinet@octobus.net>
parents: 42367
diff changeset
1465 if rustmod is not None:
a3a8887e4426 rust: using policy.importrust from Python callers
Georges Racinet <georges.racinet@octobus.net>
parents: 42367
diff changeset
1466 result, warnings = rustmod.read_pattern_file(
42329
c7652f7440d9 rust-filepatterns: call new Rust implementations from Python
Raphaël Gomès <rgomes@octobus.net>
parents: 42195
diff changeset
1467 filepath,
c7652f7440d9 rust-filepatterns: call new Rust implementations from Python
Raphaël Gomès <rgomes@octobus.net>
parents: 42195
diff changeset
1468 bool(warn),
c7652f7440d9 rust-filepatterns: call new Rust implementations from Python
Raphaël Gomès <rgomes@octobus.net>
parents: 42195
diff changeset
1469 sourceinfo,
c7652f7440d9 rust-filepatterns: call new Rust implementations from Python
Raphaël Gomès <rgomes@octobus.net>
parents: 42195
diff changeset
1470 )
c7652f7440d9 rust-filepatterns: call new Rust implementations from Python
Raphaël Gomès <rgomes@octobus.net>
parents: 42195
diff changeset
1471
c7652f7440d9 rust-filepatterns: call new Rust implementations from Python
Raphaël Gomès <rgomes@octobus.net>
parents: 42195
diff changeset
1472 for warning_params in warnings:
c7652f7440d9 rust-filepatterns: call new Rust implementations from Python
Raphaël Gomès <rgomes@octobus.net>
parents: 42195
diff changeset
1473 # Can't be easily emitted from Rust, because it would require
c7652f7440d9 rust-filepatterns: call new Rust implementations from Python
Raphaël Gomès <rgomes@octobus.net>
parents: 42195
diff changeset
1474 # a mechanism for both gettext and calling the `warn` function.
c7652f7440d9 rust-filepatterns: call new Rust implementations from Python
Raphaël Gomès <rgomes@octobus.net>
parents: 42195
diff changeset
1475 warn(_("%s: ignoring invalid syntax '%s'\n") % warning_params)
c7652f7440d9 rust-filepatterns: call new Rust implementations from Python
Raphaël Gomès <rgomes@octobus.net>
parents: 42195
diff changeset
1476
c7652f7440d9 rust-filepatterns: call new Rust implementations from Python
Raphaël Gomès <rgomes@octobus.net>
parents: 42195
diff changeset
1477 return result
c7652f7440d9 rust-filepatterns: call new Rust implementations from Python
Raphaël Gomès <rgomes@octobus.net>
parents: 42195
diff changeset
1478
40685
e41f6c2e69c4 match: reformat `syntaxes` dictionary for better maintainability
Boris Feld <boris.feld@octobus.net>
parents: 40684
diff changeset
1479 syntaxes = {
e41f6c2e69c4 match: reformat `syntaxes` dictionary for better maintainability
Boris Feld <boris.feld@octobus.net>
parents: 40684
diff changeset
1480 're': 'relre:',
e41f6c2e69c4 match: reformat `syntaxes` dictionary for better maintainability
Boris Feld <boris.feld@octobus.net>
parents: 40684
diff changeset
1481 'regexp': 'relre:',
e41f6c2e69c4 match: reformat `syntaxes` dictionary for better maintainability
Boris Feld <boris.feld@octobus.net>
parents: 40684
diff changeset
1482 'glob': 'relglob:',
41282
4fab8a7d2d72 match: support rooted globs in hgignore
Valentin Gatien-Baron <vgatien-baron@janestreet.com>
parents: 41129
diff changeset
1483 'rootglob': 'rootglob:',
40685
e41f6c2e69c4 match: reformat `syntaxes` dictionary for better maintainability
Boris Feld <boris.feld@octobus.net>
parents: 40684
diff changeset
1484 'include': 'include',
e41f6c2e69c4 match: reformat `syntaxes` dictionary for better maintainability
Boris Feld <boris.feld@octobus.net>
parents: 40684
diff changeset
1485 'subinclude': 'subinclude',
e41f6c2e69c4 match: reformat `syntaxes` dictionary for better maintainability
Boris Feld <boris.feld@octobus.net>
parents: 40684
diff changeset
1486 }
25167
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
1487 syntax = 'relre:'
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
1488 patterns = []
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
1489
31403
10c17f8bfcf3 py3: open file in rb mode
Rishabh Madan <rishabhmadan96@gmail.com>
parents: 31392
diff changeset
1490 fp = open(filepath, 'rb')
30399
7f3593c29473 match: migrate to util.iterfile
Jun Wu <quark@fb.com>
parents: 29803
diff changeset
1491 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
1492 if "#" in line:
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
1493 global _commentre
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
1494 if not _commentre:
31420
40704098853f match: make regular expression bytes to prevent TypeError
Pulkit Goyal <7895pulkit@gmail.com>
parents: 31403
diff changeset
1495 _commentre = util.re.compile(br'((?:^|[^\\])(?:\\\\)*)#.*')
25167
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
1496 # 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
1497 m = _commentre.search(line)
d500341e4f55 match: use re2 in readpatternfile if possible
Bryan O'Sullivan <bos@serpentine.com>
parents: 26781
diff changeset
1498 if m:
d500341e4f55 match: use re2 in readpatternfile if possible
Bryan O'Sullivan <bos@serpentine.com>
parents: 26781
diff changeset
1499 line = line[:m.end(1)]
25167
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
1500 # fixup properly escaped comments that survived the above
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
1501 line = line.replace("\\#", "#")
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
1502 line = line.rstrip()
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
1503 if not line:
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
1504 continue
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
1505
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
1506 if line.startswith('syntax:'):
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
1507 s = line[7:].strip()
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
1508 try:
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
1509 syntax = syntaxes[s]
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
1510 except KeyError:
25214
08703b10c3ae match: add optional warn argument
Durham Goode <durham@fb.com>
parents: 25213
diff changeset
1511 if warn:
08703b10c3ae match: add optional warn argument
Durham Goode <durham@fb.com>
parents: 25213
diff changeset
1512 warn(_("%s: ignoring invalid syntax '%s'\n") %
08703b10c3ae match: add optional warn argument
Durham Goode <durham@fb.com>
parents: 25213
diff changeset
1513 (filepath, s))
25167
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
1514 continue
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
1515
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
1516 linesyntax = syntax
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
1517 for s, rels in syntaxes.iteritems():
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
1518 if line.startswith(rels):
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
1519 linesyntax = rels
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
1520 line = line[len(rels):]
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
1521 break
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
1522 elif line.startswith(s+':'):
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
1523 linesyntax = rels
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
1524 line = line[len(s) + 1:]
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
1525 break
27595
9e2d01707e71 match: add option to return line and lineno from readpattern
Laurent Charignon <lcharignon@fb.com>
parents: 27343
diff changeset
1526 if sourceinfo:
9e2d01707e71 match: add option to return line and lineno from readpattern
Laurent Charignon <lcharignon@fb.com>
parents: 27343
diff changeset
1527 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
1528 else:
9e2d01707e71 match: add option to return line and lineno from readpattern
Laurent Charignon <lcharignon@fb.com>
parents: 27343
diff changeset
1529 patterns.append(linesyntax + line)
25167
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
1530 fp.close()
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
1531 return patterns