annotate mercurial/match.py @ 42080:f3db5c805a67

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