annotate mercurial/match.py @ 32458:a04bc55201c3

match: extract base class for matchers We will soon start splitting up the current matcher class into more specialized classes, so we'll want a base class for all the things that don't vary much between different matchers.
author Martin von Zweigbergk <martinvonz@google.com>
date Wed, 17 May 2017 23:45:13 -0700
parents 57d6c0c74b1b
children 9f781f43f2ce
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
25958
c4ccf2d394a7 match: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25875
diff changeset
8 from __future__ import absolute_import
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
c4ccf2d394a7 match: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25875
diff changeset
11 import os
c4ccf2d394a7 match: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25875
diff changeset
12 import re
c4ccf2d394a7 match: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25875
diff changeset
13
c4ccf2d394a7 match: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25875
diff changeset
14 from .i18n import _
c4ccf2d394a7 match: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25875
diff changeset
15 from . import (
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26014
diff changeset
16 error,
25958
c4ccf2d394a7 match: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25875
diff changeset
17 pathutil,
c4ccf2d394a7 match: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25875
diff changeset
18 util,
c4ccf2d394a7 match: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25875
diff changeset
19 )
6576
69f3e9ac7c56 walk: introduce match objects
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
20
24636
36872036169b treemanifest: further optimize treemanifest.matches()
Drew Gottlieb <drgott@google.com>
parents: 24452
diff changeset
21 propertycache = util.propertycache
36872036169b treemanifest: further optimize treemanifest.matches()
Drew Gottlieb <drgott@google.com>
parents: 24452
diff changeset
22
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
23 def _rematcher(regex):
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
24 '''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
25 matcher function'''
21909
335bb8b80443 match: use util.re.compile instead of util.compilere
Siddharth Agarwal <sid0@fb.com>
parents: 21815
diff changeset
26 m = util.re.compile(regex)
16943
8d08a28aa63e matcher: use re2 bindings if available
Bryan O'Sullivan <bryano@fb.com>
parents: 16791
diff changeset
27 try:
8d08a28aa63e matcher: use re2 bindings if available
Bryan O'Sullivan <bryano@fb.com>
parents: 16791
diff changeset
28 # 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
29 return m.test_match
8d08a28aa63e matcher: use re2 bindings if available
Bryan O'Sullivan <bryano@fb.com>
parents: 16791
diff changeset
30 except AttributeError:
8d08a28aa63e matcher: use re2 bindings if available
Bryan O'Sullivan <bryano@fb.com>
parents: 16791
diff changeset
31 return m.match
8d08a28aa63e matcher: use re2 bindings if available
Bryan O'Sullivan <bryano@fb.com>
parents: 16791
diff changeset
32
25122
755d23a49170 match: resolve filesets in subrepos for commands given the '-S' argument
Matt Harbison <matt_harbison@yahoo.com>
parents: 25114
diff changeset
33 def _expandsets(kindpats, ctx, listsubrepos):
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
34 '''Returns the kindpats list with the 'set' patterns expanded.'''
14675
cfc89398f710 match: introduce basic fileset support
Matt Mackall <mpm@selenic.com>
parents: 14674
diff changeset
35 fset = set()
cfc89398f710 match: introduce basic fileset support
Matt Mackall <mpm@selenic.com>
parents: 14674
diff changeset
36 other = []
cfc89398f710 match: introduce basic fileset support
Matt Mackall <mpm@selenic.com>
parents: 14674
diff changeset
37
25213
08a8e9da0ae7 match: add source to kindpats list
Durham Goode <durham@fb.com>
parents: 25195
diff changeset
38 for kind, pat, source in kindpats:
14675
cfc89398f710 match: introduce basic fileset support
Matt Mackall <mpm@selenic.com>
parents: 14674
diff changeset
39 if kind == 'set':
cfc89398f710 match: introduce basic fileset support
Matt Mackall <mpm@selenic.com>
parents: 14674
diff changeset
40 if not ctx:
32444
57d6c0c74b1b match: use ProgrammingError where appropriate
Martin von Zweigbergk <martinvonz@google.com>
parents: 32415
diff changeset
41 raise error.ProgrammingError("fileset expression with no "
57d6c0c74b1b match: use ProgrammingError where appropriate
Martin von Zweigbergk <martinvonz@google.com>
parents: 32415
diff changeset
42 "context")
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
43 s = ctx.getfileset(pat)
14675
cfc89398f710 match: introduce basic fileset support
Matt Mackall <mpm@selenic.com>
parents: 14674
diff changeset
44 fset.update(s)
25122
755d23a49170 match: resolve filesets in subrepos for commands given the '-S' argument
Matt Harbison <matt_harbison@yahoo.com>
parents: 25114
diff changeset
45
755d23a49170 match: resolve filesets in subrepos for commands given the '-S' argument
Matt Harbison <matt_harbison@yahoo.com>
parents: 25114
diff changeset
46 if listsubrepos:
755d23a49170 match: resolve filesets in subrepos for commands given the '-S' argument
Matt Harbison <matt_harbison@yahoo.com>
parents: 25114
diff changeset
47 for subpath in ctx.substate:
755d23a49170 match: resolve filesets in subrepos for commands given the '-S' argument
Matt Harbison <matt_harbison@yahoo.com>
parents: 25114
diff changeset
48 s = ctx.sub(subpath).getfileset(pat)
755d23a49170 match: resolve filesets in subrepos for commands given the '-S' argument
Matt Harbison <matt_harbison@yahoo.com>
parents: 25114
diff changeset
49 fset.update(subpath + '/' + f for f in s)
755d23a49170 match: resolve filesets in subrepos for commands given the '-S' argument
Matt Harbison <matt_harbison@yahoo.com>
parents: 25114
diff changeset
50
14675
cfc89398f710 match: introduce basic fileset support
Matt Mackall <mpm@selenic.com>
parents: 14674
diff changeset
51 continue
25213
08a8e9da0ae7 match: add source to kindpats list
Durham Goode <durham@fb.com>
parents: 25195
diff changeset
52 other.append((kind, pat, source))
14675
cfc89398f710 match: introduce basic fileset support
Matt Mackall <mpm@selenic.com>
parents: 14674
diff changeset
53 return fset, other
cfc89398f710 match: introduce basic fileset support
Matt Mackall <mpm@selenic.com>
parents: 14674
diff changeset
54
25283
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
55 def _expandsubinclude(kindpats, root):
32132
6dea1701f170 match: make subinclude construction lazy
Durham Goode <durham@fb.com>
parents: 31433
diff changeset
56 '''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
57 subincludes in it.'''
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
58 relmatchers = []
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
59 other = []
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
60
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
61 for kind, pat, source in kindpats:
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
62 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
63 sourceroot = pathutil.dirname(util.normpath(source))
25283
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
64 pat = util.pconvert(pat)
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
65 path = pathutil.join(sourceroot, pat)
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
66
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
67 newroot = pathutil.dirname(path)
32132
6dea1701f170 match: make subinclude construction lazy
Durham Goode <durham@fb.com>
parents: 31433
diff changeset
68 matcherargs = (newroot, '', [], ['include:%s' % path])
25283
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
69
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
70 prefix = pathutil.canonpath(root, root, newroot)
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
71 if prefix:
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
72 prefix += '/'
32132
6dea1701f170 match: make subinclude construction lazy
Durham Goode <durham@fb.com>
parents: 31433
diff changeset
73 relmatchers.append((prefix, matcherargs))
25283
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
74 else:
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
75 other.append((kind, pat, source))
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
76
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
77 return relmatchers, other
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
78
24447
d44d53bc9a1e matcher: make e.g. 'relpath:.' lead to fast paths
Martin von Zweigbergk <martinvonz@google.com>
parents: 23686
diff changeset
79 def _kindpatsalwaysmatch(kindpats):
d44d53bc9a1e matcher: make e.g. 'relpath:.' lead to fast paths
Martin von Zweigbergk <martinvonz@google.com>
parents: 23686
diff changeset
80 """"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
81 'relpath:.' does.
d44d53bc9a1e matcher: make e.g. 'relpath:.' lead to fast paths
Martin von Zweigbergk <martinvonz@google.com>
parents: 23686
diff changeset
82 """
25213
08a8e9da0ae7 match: add source to kindpats list
Durham Goode <durham@fb.com>
parents: 25195
diff changeset
83 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
84 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
85 return False
d44d53bc9a1e matcher: make e.g. 'relpath:.' lead to fast paths
Martin von Zweigbergk <martinvonz@google.com>
parents: 23686
diff changeset
86 return True
d44d53bc9a1e matcher: make e.g. 'relpath:.' lead to fast paths
Martin von Zweigbergk <martinvonz@google.com>
parents: 23686
diff changeset
87
32395
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
88 def match(root, cwd, patterns, include=None, exclude=None, default='glob',
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
89 exact=False, auditor=None, ctx=None, listsubrepos=False, warn=None,
32401
284b18303f61 match: replace icasefsmatch() function by flag to regular match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32400
diff changeset
90 badfn=None, icasefs=False):
32395
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
91 """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: 32325
diff changeset
92
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
93 arguments:
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
94 root - the canonical root of the tree you're matching against
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
95 cwd - the current working directory, if relevant
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
96 patterns - patterns to find
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
97 include - patterns to include (unless they are excluded)
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
98 exclude - patterns to exclude (even if they are included)
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
99 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: 32325
diff changeset
100 exact - patterns are actually filenames (include/exclude still apply)
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
101 warn - optional function used for printing warnings
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
102 badfn - optional bad() callback for this matcher instead of the default
32401
284b18303f61 match: replace icasefsmatch() function by flag to regular match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32400
diff changeset
103 icasefs - make a matcher for wdir on case insensitive filesystems, which
284b18303f61 match: replace icasefsmatch() function by flag to regular match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32400
diff changeset
104 normalizes the given patterns to the case in the filesystem
32395
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
105
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
106 a pattern is one of:
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
107 'glob:<glob>' - a glob relative to cwd
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
108 're:<regexp>' - a regular expression
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
109 'path:<path>' - a path relative to repository root, which is matched
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
110 recursively
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
111 'rootfilesin:<path>' - a path relative to repository root, which is
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
112 matched non-recursively (will not match subdirectories)
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
113 'relglob:<glob>' - an unrooted glob (*.c matches C files in all dirs)
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
114 'relpath:<path>' - a path relative to cwd
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
115 'relre:<regexp>' - a regexp that needn't match the start of a name
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
116 'set:<fileset>' - a fileset expression
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
117 'include:<path>' - a file of patterns to read and include
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
118 'subinclude:<path>' - a file of patterns to match against files under
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
119 the same directory
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
120 '<something>' - a pattern of the specified default type
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
121 """
32401
284b18303f61 match: replace icasefsmatch() function by flag to regular match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32400
diff changeset
122 normalize = _donormalize
284b18303f61 match: replace icasefsmatch() function by flag to regular match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32400
diff changeset
123 if icasefs:
32415
9695aca1a3a0 match: catch attempts to create case-insenstive exact matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32406
diff changeset
124 if exact:
32444
57d6c0c74b1b match: use ProgrammingError where appropriate
Martin von Zweigbergk <martinvonz@google.com>
parents: 32415
diff changeset
125 raise error.ProgrammingError("a case-insensitive exact matcher "
57d6c0c74b1b match: use ProgrammingError where appropriate
Martin von Zweigbergk <martinvonz@google.com>
parents: 32415
diff changeset
126 "doesn't make sense")
32401
284b18303f61 match: replace icasefsmatch() function by flag to regular match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32400
diff changeset
127 dirstate = ctx.repo().dirstate
284b18303f61 match: replace icasefsmatch() function by flag to regular match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32400
diff changeset
128 dsnormalize = dirstate.normalize
284b18303f61 match: replace icasefsmatch() function by flag to regular match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32400
diff changeset
129
284b18303f61 match: replace icasefsmatch() function by flag to regular match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32400
diff changeset
130 def normalize(patterns, default, root, cwd, auditor, warn):
284b18303f61 match: replace icasefsmatch() function by flag to regular match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32400
diff changeset
131 kp = _donormalize(patterns, default, root, cwd, auditor, warn)
284b18303f61 match: replace icasefsmatch() function by flag to regular match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32400
diff changeset
132 kindpats = []
284b18303f61 match: replace icasefsmatch() function by flag to regular match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32400
diff changeset
133 for kind, pats, source in kp:
284b18303f61 match: replace icasefsmatch() function by flag to regular match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32400
diff changeset
134 if kind not in ('re', 'relre'): # regex can't be normalized
284b18303f61 match: replace icasefsmatch() function by flag to regular match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32400
diff changeset
135 p = pats
284b18303f61 match: replace icasefsmatch() function by flag to regular match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32400
diff changeset
136 pats = dsnormalize(pats)
284b18303f61 match: replace icasefsmatch() function by flag to regular match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32400
diff changeset
137
284b18303f61 match: replace icasefsmatch() function by flag to regular match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32400
diff changeset
138 # Preserve the original to handle a case only rename.
284b18303f61 match: replace icasefsmatch() function by flag to regular match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32400
diff changeset
139 if p != pats and p in dirstate:
284b18303f61 match: replace icasefsmatch() function by flag to regular match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32400
diff changeset
140 kindpats.append((kind, p, source))
284b18303f61 match: replace icasefsmatch() function by flag to regular match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32400
diff changeset
141
284b18303f61 match: replace icasefsmatch() function by flag to regular match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32400
diff changeset
142 kindpats.append((kind, pats, source))
284b18303f61 match: replace icasefsmatch() function by flag to regular match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32400
diff changeset
143 return kindpats
284b18303f61 match: replace icasefsmatch() function by flag to regular match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32400
diff changeset
144
284b18303f61 match: replace icasefsmatch() function by flag to regular match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32400
diff changeset
145 return matcher(root, cwd, normalize, patterns, include=include,
32399
1c1f7c946666 match: pass in normalize() function to matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32398
diff changeset
146 exclude=exclude, default=default, exact=exact,
1c1f7c946666 match: pass in normalize() function to matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32398
diff changeset
147 auditor=auditor, ctx=ctx, listsubrepos=listsubrepos,
1c1f7c946666 match: pass in normalize() function to matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32398
diff changeset
148 warn=warn, badfn=badfn)
32395
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
149
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
150 def exact(root, cwd, files, badfn=None):
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
151 return match(root, cwd, files, exact=True, badfn=badfn)
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
152
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
153 def always(root, cwd):
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
154 return match(root, cwd, [])
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
155
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
156 def badmatch(match, badfn):
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
157 """Make a copy of the given matcher, replacing its bad method with the given
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
158 one.
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
159 """
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
160 m = copy.copy(match)
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
161 m.bad = badfn
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
162 return m
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
163
32397
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32396
diff changeset
164 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: 32396
diff changeset
165 '''Convert 'kind:pat' from the patterns list to tuples with kind and
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32396
diff changeset
166 normalized and rooted patterns and with listfiles expanded.'''
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32396
diff changeset
167 kindpats = []
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32396
diff changeset
168 for kind, pat in [_patsplit(p, default) for p in patterns]:
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32396
diff changeset
169 if kind in ('glob', 'relpath'):
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32396
diff changeset
170 pat = pathutil.canonpath(root, cwd, pat, auditor)
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32396
diff changeset
171 elif kind in ('relglob', 'path', 'rootfilesin'):
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32396
diff changeset
172 pat = util.normpath(pat)
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32396
diff changeset
173 elif kind in ('listfile', 'listfile0'):
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32396
diff changeset
174 try:
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32396
diff changeset
175 files = util.readfile(pat)
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32396
diff changeset
176 if kind == 'listfile0':
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32396
diff changeset
177 files = files.split('\0')
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32396
diff changeset
178 else:
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32396
diff changeset
179 files = files.splitlines()
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32396
diff changeset
180 files = [f for f in files if f]
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32396
diff changeset
181 except EnvironmentError:
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32396
diff changeset
182 raise error.Abort(_("unable to read file list (%s)") % pat)
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32396
diff changeset
183 for k, p, source in _donormalize(files, default, root, cwd,
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32396
diff changeset
184 auditor, warn):
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32396
diff changeset
185 kindpats.append((k, p, pat))
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32396
diff changeset
186 continue
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32396
diff changeset
187 elif kind == 'include':
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32396
diff changeset
188 try:
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32396
diff changeset
189 fullpath = os.path.join(root, util.localpath(pat))
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32396
diff changeset
190 includepats = readpatternfile(fullpath, warn)
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32396
diff changeset
191 for k, p, source in _donormalize(includepats, default,
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32396
diff changeset
192 root, cwd, auditor, warn):
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32396
diff changeset
193 kindpats.append((k, p, source or pat))
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32396
diff changeset
194 except error.Abort as inst:
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32396
diff changeset
195 raise error.Abort('%s: %s' % (pat, inst[0]))
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32396
diff changeset
196 except IOError as inst:
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32396
diff changeset
197 if warn:
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32396
diff changeset
198 warn(_("skipping unreadable pattern file '%s': %s\n") %
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32396
diff changeset
199 (pat, inst.strerror))
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32396
diff changeset
200 continue
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32396
diff changeset
201 # else: re or relre - which cannot be normalized
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32396
diff changeset
202 kindpats.append((kind, pat, ''))
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32396
diff changeset
203 return kindpats
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32396
diff changeset
204
32458
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
205 class basematcher(object):
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
206
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
207 def __init__(self, root, cwd, badfn=None):
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
208 self._root = root
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
209 self._cwd = cwd
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
210 if badfn is not None:
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
211 self.bad = badfn
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
212 self._files = [] # exact files and roots of patterns
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
213 self.matchfn = lambda f: False
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
214
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
215 def __call__(self, fn):
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
216 return self.matchfn(fn)
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
217 def __iter__(self):
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
218 for f in self._files:
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
219 yield f
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
220 # Callbacks related to how the matcher is used by dirstate.walk.
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
221 # Subscribers to these events must monkeypatch the matcher object.
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
222 def bad(self, f, msg):
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
223 '''Callback from dirstate.walk for each explicit file that can't be
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
224 found/accessed, with an error message.'''
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
225 pass
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
226
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
227 # If an explicitdir is set, it will be called when an explicitly listed
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
228 # directory is visited.
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
229 explicitdir = None
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
230
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
231 # If an traversedir is set, it will be called when a directory discovered
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
232 # by recursive traversal is visited.
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
233 traversedir = None
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
234
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
235 def abs(self, f):
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
236 '''Convert a repo path back to path that is relative to the root of the
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
237 matcher.'''
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
238 return f
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
239
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
240 def rel(self, f):
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
241 '''Convert repo path back to path that is relative to cwd of matcher.'''
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
242 return util.pathto(self._root, self._cwd, f)
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
243
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
244 def uipath(self, f):
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
245 '''Convert repo path to a display path. If patterns or -I/-X were used
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
246 to create this matcher, the display path will be relative to cwd.
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
247 Otherwise it is relative to the root of the repo.'''
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
248 return self.rel(f)
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
249
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
250 def files(self):
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
251 '''Explicitly listed files or patterns or roots:
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
252 if no patterns or .always(): empty list,
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
253 if exact: list exact files,
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
254 if not .anypats(): list all files and dirs,
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
255 else: optimal roots'''
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
256 return self._files
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
257
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
258 @propertycache
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
259 def _fileset(self):
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
260 return set(self._files)
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
261
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
262 def exact(self, f):
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
263 '''Returns True if f is in .files().'''
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
264 return f in self._fileset
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
265
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
266 def visitdir(self, dir):
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
267 '''Decides whether a directory should be visited based on whether it
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
268 has potential matches in it or one of its subdirectories. This is
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
269 based on the match's primary, included, and excluded patterns.
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
270
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
271 Returns the string 'all' if the given directory and all subdirectories
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
272 should be visited. Otherwise returns True or False indicating whether
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
273 the given directory should be visited.
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
274
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
275 This function's behavior is undefined if it has returned False for
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
276 one of the dir's parent directories.
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
277 '''
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
278 return False
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
279
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
280 def anypats(self):
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
281 '''Matcher uses patterns or include/exclude.'''
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
282 return False
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
283
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
284 def always(self):
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
285 '''Matcher will match everything and .files() will be empty
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
286 - optimization might be possible and necessary.'''
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
287 return False
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
288
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
289 def isexact(self):
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
290 return False
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
291
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
292 def prefix(self):
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
293 return not self.always() and not self.isexact() and not self.anypats()
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
294
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
295 class matcher(basematcher):
32395
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
296
32399
1c1f7c946666 match: pass in normalize() function to matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32398
diff changeset
297 def __init__(self, root, cwd, normalize, patterns, include=None,
1c1f7c946666 match: pass in normalize() function to matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32398
diff changeset
298 exclude=None, default='glob', exact=False, auditor=None,
1c1f7c946666 match: pass in normalize() function to matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32398
diff changeset
299 ctx=None, listsubrepos=False, warn=None, badfn=None):
32458
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
300 super(matcher, self).__init__(root, cwd, badfn)
31433
7aac35ada1cb match: explicitly tests for None
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31421
diff changeset
301 if include is None:
7aac35ada1cb match: explicitly tests for None
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31421
diff changeset
302 include = []
7aac35ada1cb match: explicitly tests for None
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31421
diff changeset
303 if exclude is None:
7aac35ada1cb match: explicitly tests for None
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31421
diff changeset
304 exclude = []
8581
101d305c1d0b match: fold _matcher into match.__init__
Matt Mackall <mpm@selenic.com>
parents: 8580
diff changeset
305
8587
8f15d54437b9 match: fold match into _match base class
Matt Mackall <mpm@selenic.com>
parents: 8586
diff changeset
306 self._anypats = bool(include or exclude)
18713
8728579f6bdc match: more accurately report when we're always going to match
Bryan O'Sullivan <bryano@fb.com>
parents: 17425
diff changeset
307 self._always = False
23480
88d2d77eb981 match: introduce uipath() to properly style a file path
Matt Harbison <matt_harbison@yahoo.com>
parents: 22777
diff changeset
308 self._pathrestricted = bool(include or exclude or patterns)
32406
952017471f93 match: implement __repr__() and update users (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32401
diff changeset
309 self.patternspat = None
952017471f93 match: implement __repr__() and update users (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32401
diff changeset
310 self.includepat = None
952017471f93 match: implement __repr__() and update users (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32401
diff changeset
311 self.excludepat = None
31013
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31012
diff changeset
312
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31012
diff changeset
313 # roots are directories which are recursively included/excluded.
25231
8545bd381504 match: have visitdir() consider includes and excludes
Drew Gottlieb <drgott@google.com>
parents: 25216
diff changeset
314 self._includeroots = set()
31013
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31012
diff changeset
315 self._excluderoots = set()
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31012
diff changeset
316 # dirs are directories which are non-recursively included.
32176
cf042543afa2 match: optimize visitdir() for patterns matching only root directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 32132
diff changeset
317 self._includedirs = set()
8581
101d305c1d0b match: fold _matcher into match.__init__
Matt Mackall <mpm@selenic.com>
parents: 8580
diff changeset
318
22513
ca709785caf2 match: simplify brittle predicate construction
Martin von Zweigbergk <martinvonz@gmail.com>
parents: 21915
diff changeset
319 matchfns = []
8586
347fe1ac4f21 match: add exact flag to match() to unify all match forms
Matt Mackall <mpm@selenic.com>
parents: 8585
diff changeset
320 if include:
32399
1c1f7c946666 match: pass in normalize() function to matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32398
diff changeset
321 kindpats = normalize(include, 'glob', root, cwd, auditor, warn)
25122
755d23a49170 match: resolve filesets in subrepos for commands given the '-S' argument
Matt Harbison <matt_harbison@yahoo.com>
parents: 25114
diff changeset
322 self.includepat, im = _buildmatch(ctx, kindpats, '(?:/|$)',
25238
5a55ad6e8e24 match: add root to _buildmatch
Durham Goode <durham@fb.com>
parents: 25233
diff changeset
323 listsubrepos, root)
31013
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31012
diff changeset
324 roots, dirs = _rootsanddirs(kindpats)
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31012
diff changeset
325 self._includeroots.update(roots)
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31012
diff changeset
326 self._includedirs.update(dirs)
22513
ca709785caf2 match: simplify brittle predicate construction
Martin von Zweigbergk <martinvonz@gmail.com>
parents: 21915
diff changeset
327 matchfns.append(im)
8586
347fe1ac4f21 match: add exact flag to match() to unify all match forms
Matt Mackall <mpm@selenic.com>
parents: 8585
diff changeset
328 if exclude:
32399
1c1f7c946666 match: pass in normalize() function to matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32398
diff changeset
329 kindpats = normalize(exclude, 'glob', root, cwd, auditor, warn)
25122
755d23a49170 match: resolve filesets in subrepos for commands given the '-S' argument
Matt Harbison <matt_harbison@yahoo.com>
parents: 25114
diff changeset
330 self.excludepat, em = _buildmatch(ctx, kindpats, '(?:/|$)',
25238
5a55ad6e8e24 match: add root to _buildmatch
Durham Goode <durham@fb.com>
parents: 25233
diff changeset
331 listsubrepos, root)
25362
20ad936ac5d2 treemanifest: visit directory 'foo' when given e.g. '-X foo/ba?'
Martin von Zweigbergk <martinvonz@google.com>
parents: 25301
diff changeset
332 if not _anypats(kindpats):
31013
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31012
diff changeset
333 # Only consider recursive excludes as such - if a non-recursive
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31012
diff changeset
334 # exclude is used, we must still recurse into the excluded
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31012
diff changeset
335 # directory, at least to find subdirectories. In such a case,
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31012
diff changeset
336 # the regex still won't match the non-recursively-excluded
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31012
diff changeset
337 # files.
25362
20ad936ac5d2 treemanifest: visit directory 'foo' when given e.g. '-X foo/ba?'
Martin von Zweigbergk <martinvonz@google.com>
parents: 25301
diff changeset
338 self._excluderoots.update(_roots(kindpats))
22513
ca709785caf2 match: simplify brittle predicate construction
Martin von Zweigbergk <martinvonz@gmail.com>
parents: 21915
diff changeset
339 matchfns.append(lambda f: not em(f))
8586
347fe1ac4f21 match: add exact flag to match() to unify all match forms
Matt Mackall <mpm@selenic.com>
parents: 8585
diff changeset
340 if exact:
16789
c17ce7cd5090 match: make 'match.files()' return list object always
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 16182
diff changeset
341 if isinstance(patterns, list):
c17ce7cd5090 match: make 'match.files()' return list object always
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 16182
diff changeset
342 self._files = patterns
c17ce7cd5090 match: make 'match.files()' return list object always
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 16182
diff changeset
343 else:
c17ce7cd5090 match: make 'match.files()' return list object always
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 16182
diff changeset
344 self._files = list(patterns)
22513
ca709785caf2 match: simplify brittle predicate construction
Martin von Zweigbergk <martinvonz@gmail.com>
parents: 21915
diff changeset
345 matchfns.append(self.exact)
8586
347fe1ac4f21 match: add exact flag to match() to unify all match forms
Matt Mackall <mpm@selenic.com>
parents: 8585
diff changeset
346 elif patterns:
32399
1c1f7c946666 match: pass in normalize() function to matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32398
diff changeset
347 kindpats = normalize(patterns, default, root, cwd, auditor, warn)
24447
d44d53bc9a1e matcher: make e.g. 'relpath:.' lead to fast paths
Martin von Zweigbergk <martinvonz@google.com>
parents: 23686
diff changeset
348 if not _kindpatsalwaysmatch(kindpats):
31012
88358446da16 match: adding support for matching files inside a directory
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 30399
diff changeset
349 self._files = _explicitfiles(kindpats)
24447
d44d53bc9a1e matcher: make e.g. 'relpath:.' lead to fast paths
Martin von Zweigbergk <martinvonz@google.com>
parents: 23686
diff changeset
350 self._anypats = self._anypats or _anypats(kindpats)
25122
755d23a49170 match: resolve filesets in subrepos for commands given the '-S' argument
Matt Harbison <matt_harbison@yahoo.com>
parents: 25114
diff changeset
351 self.patternspat, pm = _buildmatch(ctx, kindpats, '$',
25238
5a55ad6e8e24 match: add root to _buildmatch
Durham Goode <durham@fb.com>
parents: 25233
diff changeset
352 listsubrepos, root)
24447
d44d53bc9a1e matcher: make e.g. 'relpath:.' lead to fast paths
Martin von Zweigbergk <martinvonz@google.com>
parents: 23686
diff changeset
353 matchfns.append(pm)
8581
101d305c1d0b match: fold _matcher into match.__init__
Matt Mackall <mpm@selenic.com>
parents: 8580
diff changeset
354
22513
ca709785caf2 match: simplify brittle predicate construction
Martin von Zweigbergk <martinvonz@gmail.com>
parents: 21915
diff changeset
355 if not matchfns:
ca709785caf2 match: simplify brittle predicate construction
Martin von Zweigbergk <martinvonz@gmail.com>
parents: 21915
diff changeset
356 m = util.always
ca709785caf2 match: simplify brittle predicate construction
Martin von Zweigbergk <martinvonz@gmail.com>
parents: 21915
diff changeset
357 self._always = True
ca709785caf2 match: simplify brittle predicate construction
Martin von Zweigbergk <martinvonz@gmail.com>
parents: 21915
diff changeset
358 elif len(matchfns) == 1:
ca709785caf2 match: simplify brittle predicate construction
Martin von Zweigbergk <martinvonz@gmail.com>
parents: 21915
diff changeset
359 m = matchfns[0]
8581
101d305c1d0b match: fold _matcher into match.__init__
Matt Mackall <mpm@selenic.com>
parents: 8580
diff changeset
360 else:
22513
ca709785caf2 match: simplify brittle predicate construction
Martin von Zweigbergk <martinvonz@gmail.com>
parents: 21915
diff changeset
361 def m(f):
ca709785caf2 match: simplify brittle predicate construction
Martin von Zweigbergk <martinvonz@gmail.com>
parents: 21915
diff changeset
362 for matchfn in matchfns:
ca709785caf2 match: simplify brittle predicate construction
Martin von Zweigbergk <martinvonz@gmail.com>
parents: 21915
diff changeset
363 if not matchfn(f):
ca709785caf2 match: simplify brittle predicate construction
Martin von Zweigbergk <martinvonz@gmail.com>
parents: 21915
diff changeset
364 return False
ca709785caf2 match: simplify brittle predicate construction
Martin von Zweigbergk <martinvonz@gmail.com>
parents: 21915
diff changeset
365 return True
8581
101d305c1d0b match: fold _matcher into match.__init__
Matt Mackall <mpm@selenic.com>
parents: 8580
diff changeset
366
8587
8f15d54437b9 match: fold match into _match base class
Matt Mackall <mpm@selenic.com>
parents: 8586
diff changeset
367 self.matchfn = m
8f15d54437b9 match: fold match into _match base class
Matt Mackall <mpm@selenic.com>
parents: 8586
diff changeset
368
23480
88d2d77eb981 match: introduce uipath() to properly style a file path
Matt Harbison <matt_harbison@yahoo.com>
parents: 22777
diff changeset
369 def uipath(self, f):
23686
164915e8ef7b narrowmatcher: propagate the rel() method
Matt Harbison <matt_harbison@yahoo.com>
parents: 23685
diff changeset
370 return (self._pathrestricted and self.rel(f)) or self.abs(f)
23480
88d2d77eb981 match: introduce uipath() to properly style a file path
Matt Harbison <matt_harbison@yahoo.com>
parents: 22777
diff changeset
371
32322
23c9a2a71c6e match: make _fileroots a @propertycache and rename it to _fileset
Martin von Zweigbergk <martinvonz@google.com>
parents: 32312
diff changeset
372 @propertycache
24636
36872036169b treemanifest: further optimize treemanifest.matches()
Drew Gottlieb <drgott@google.com>
parents: 24452
diff changeset
373 def _dirs(self):
32322
23c9a2a71c6e match: make _fileroots a @propertycache and rename it to _fileset
Martin von Zweigbergk <martinvonz@google.com>
parents: 32312
diff changeset
374 return set(util.dirs(self._fileset)) | {'.'}
24636
36872036169b treemanifest: further optimize treemanifest.matches()
Drew Gottlieb <drgott@google.com>
parents: 24452
diff changeset
375
36872036169b treemanifest: further optimize treemanifest.matches()
Drew Gottlieb <drgott@google.com>
parents: 24452
diff changeset
376 def visitdir(self, dir):
32322
23c9a2a71c6e match: make _fileroots a @propertycache and rename it to _fileset
Martin von Zweigbergk <martinvonz@google.com>
parents: 32312
diff changeset
377 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
378 return 'all'
25231
8545bd381504 match: have visitdir() consider includes and excludes
Drew Gottlieb <drgott@google.com>
parents: 25216
diff changeset
379 if dir in self._excluderoots:
8545bd381504 match: have visitdir() consider includes and excludes
Drew Gottlieb <drgott@google.com>
parents: 25216
diff changeset
380 return False
32176
cf042543afa2 match: optimize visitdir() for patterns matching only root directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 32132
diff changeset
381 if ((self._includeroots or self._includedirs) and
25579
b76410eed482 match: don't remove '.' from _includeroots
Martin von Zweigbergk <martinvonz@google.com>
parents: 25578
diff changeset
382 '.' not in self._includeroots and
25576
d02f4b3e71f5 match: break boolean expressions into one operand per line
Martin von Zweigbergk <martinvonz@google.com>
parents: 25575
diff changeset
383 dir not in self._includeroots and
25578
4b1ec70b9713 match: join two nested if-blocks
Martin von Zweigbergk <martinvonz@google.com>
parents: 25577
diff changeset
384 dir not in self._includedirs and
4b1ec70b9713 match: join two nested if-blocks
Martin von Zweigbergk <martinvonz@google.com>
parents: 25577
diff changeset
385 not any(parent in self._includeroots
4b1ec70b9713 match: join two nested if-blocks
Martin von Zweigbergk <martinvonz@google.com>
parents: 25577
diff changeset
386 for parent in util.finddirs(dir))):
4b1ec70b9713 match: join two nested if-blocks
Martin von Zweigbergk <martinvonz@google.com>
parents: 25577
diff changeset
387 return False
32322
23c9a2a71c6e match: make _fileroots a @propertycache and rename it to _fileset
Martin von Zweigbergk <martinvonz@google.com>
parents: 32312
diff changeset
388 return (not self._fileset or
23c9a2a71c6e match: make _fileroots a @propertycache and rename it to _fileset
Martin von Zweigbergk <martinvonz@google.com>
parents: 32312
diff changeset
389 '.' in self._fileset or
23c9a2a71c6e match: make _fileroots a @propertycache and rename it to _fileset
Martin von Zweigbergk <martinvonz@google.com>
parents: 32312
diff changeset
390 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
391 dir in self._dirs or
32322
23c9a2a71c6e match: make _fileroots a @propertycache and rename it to _fileset
Martin von Zweigbergk <martinvonz@google.com>
parents: 32312
diff changeset
392 any(parentdir in self._fileset
25577
a410479c7ee7 match: drop optimization (?) of 'parentdirs' calculation
Martin von Zweigbergk <martinvonz@google.com>
parents: 25576
diff changeset
393 for parentdir in util.finddirs(dir)))
24636
36872036169b treemanifest: further optimize treemanifest.matches()
Drew Gottlieb <drgott@google.com>
parents: 24452
diff changeset
394
8587
8f15d54437b9 match: fold match into _match base class
Matt Mackall <mpm@selenic.com>
parents: 8586
diff changeset
395 def anypats(self):
8f15d54437b9 match: fold match into _match base class
Matt Mackall <mpm@selenic.com>
parents: 8586
diff changeset
396 return self._anypats
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
397
16645
9a21fc2c7d32 localrepo: optimize internode status calls using match.always
Jesse Glick <jesse.glick@oracle.com>
parents: 16182
diff changeset
398 def always(self):
18713
8728579f6bdc match: more accurately report when we're always going to match
Bryan O'Sullivan <bryano@fb.com>
parents: 17425
diff changeset
399 return self._always
8568
4fa1618bf495 match: refactor patkind
Matt Mackall <mpm@selenic.com>
parents: 8567
diff changeset
400
24448
55c449345b10 match: add isexact() method to hide internals
Martin von Zweigbergk <martinvonz@google.com>
parents: 24447
diff changeset
401 def isexact(self):
55c449345b10 match: add isexact() method to hide internals
Martin von Zweigbergk <martinvonz@google.com>
parents: 24447
diff changeset
402 return self.matchfn == self.exact
55c449345b10 match: add isexact() method to hide internals
Martin von Zweigbergk <martinvonz@google.com>
parents: 24447
diff changeset
403
32406
952017471f93 match: implement __repr__() and update users (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32401
diff changeset
404 def __repr__(self):
952017471f93 match: implement __repr__() and update users (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32401
diff changeset
405 return ('<matcher files=%r, patterns=%r, includes=%r, excludes=%r>' %
952017471f93 match: implement __repr__() and update users (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32401
diff changeset
406 (self._files, self.patternspat, self.includepat,
952017471f93 match: implement __repr__() and update users (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32401
diff changeset
407 self.excludepat))
952017471f93 match: implement __repr__() and update users (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32401
diff changeset
408
32395
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
409 class subdirmatcher(matcher):
12165
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
410 """Adapt a matcher to work on a subdirectory only.
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
411
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
412 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
413
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
414 >>> m1 = match('root', '', ['a.txt', 'sub/b.txt'])
28017
d3f1b7ee5e70 match: rename "narrowmatcher" to "subdirmatcher" (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 27595
diff changeset
415 >>> m2 = subdirmatcher('sub', m1)
12165
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
416 >>> bool(m2('a.txt'))
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
417 False
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
418 >>> bool(m2('b.txt'))
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
419 True
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
420 >>> bool(m2.matchfn('a.txt'))
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
421 False
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
422 >>> bool(m2.matchfn('b.txt'))
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
423 True
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
424 >>> m2.files()
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
425 ['b.txt']
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
426 >>> m2.exact('b.txt')
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
427 True
23686
164915e8ef7b narrowmatcher: propagate the rel() method
Matt Harbison <matt_harbison@yahoo.com>
parents: 23685
diff changeset
428 >>> util.pconvert(m2.rel('b.txt'))
164915e8ef7b narrowmatcher: propagate the rel() method
Matt Harbison <matt_harbison@yahoo.com>
parents: 23685
diff changeset
429 'sub/b.txt'
12268
83aaeba32b88 narrowmatcher: propagate bad method
Martin Geisler <mg@lazybytes.net>
parents: 12267
diff changeset
430 >>> def bad(f, msg):
83aaeba32b88 narrowmatcher: propagate bad method
Martin Geisler <mg@lazybytes.net>
parents: 12267
diff changeset
431 ... print "%s: %s" % (f, msg)
83aaeba32b88 narrowmatcher: propagate bad method
Martin Geisler <mg@lazybytes.net>
parents: 12267
diff changeset
432 >>> m1.bad = bad
83aaeba32b88 narrowmatcher: propagate bad method
Martin Geisler <mg@lazybytes.net>
parents: 12267
diff changeset
433 >>> m2.bad('x.txt', 'No such file')
83aaeba32b88 narrowmatcher: propagate bad method
Martin Geisler <mg@lazybytes.net>
parents: 12267
diff changeset
434 sub/x.txt: No such file
23685
5b1eac343ccd match: add the abs() method
Matt Harbison <matt_harbison@yahoo.com>
parents: 23549
diff changeset
435 >>> m2.abs('c.txt')
5b1eac343ccd match: add the abs() method
Matt Harbison <matt_harbison@yahoo.com>
parents: 23549
diff changeset
436 'sub/c.txt'
12165
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
437 """
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
438
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
439 def __init__(self, path, matcher):
12267
69e43c0515f2 narrowmatcher: fix broken rel method
Martin Geisler <mg@lazybytes.net>
parents: 12165
diff changeset
440 self._root = matcher._root
69e43c0515f2 narrowmatcher: fix broken rel method
Martin Geisler <mg@lazybytes.net>
parents: 12165
diff changeset
441 self._cwd = matcher._cwd
12165
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
442 self._path = path
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
443 self._matcher = matcher
18713
8728579f6bdc match: more accurately report when we're always going to match
Bryan O'Sullivan <bryano@fb.com>
parents: 17425
diff changeset
444 self._always = matcher._always
12165
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
445
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
446 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
447 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
448
32325
763d72925691 match: use match.prefix() in subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32324
diff changeset
449 # If the parent repo had a path to this subrepo and the matcher is
763d72925691 match: use match.prefix() in subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32324
diff changeset
450 # a prefix matcher, this submatcher always matches.
763d72925691 match: use match.prefix() in subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32324
diff changeset
451 if matcher.prefix():
25195
472a685a4961 merge with stable
Matt Mackall <mpm@selenic.com>
parents: 25189 25194
diff changeset
452 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
453
12165
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
454 self._anypats = matcher._anypats
28128
92f2c69ee5a5 match: override 'visitdir' in subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 28017
diff changeset
455 # Some information is lost in the superclass's constructor, so we
92f2c69ee5a5 match: override 'visitdir' in subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 28017
diff changeset
456 # can not accurately create the matching function for the subdirectory
92f2c69ee5a5 match: override 'visitdir' in subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 28017
diff changeset
457 # from the inputs. Instead, we override matchfn() and visitdir() to
92f2c69ee5a5 match: override 'visitdir' in subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 28017
diff changeset
458 # call the original matcher with the subdirectory path prepended.
12165
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
459 self.matchfn = lambda fn: matcher.matchfn(self._path + "/" + fn)
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
460
32324
77dac8fd30ee match: avoid accessing match._pathrestricted from subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32323
diff changeset
461 def bad(self, f, msg):
77dac8fd30ee match: avoid accessing match._pathrestricted from subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32323
diff changeset
462 self._matcher.bad(self._path + "/" + f, msg)
77dac8fd30ee match: avoid accessing match._pathrestricted from subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32323
diff changeset
463
23685
5b1eac343ccd match: add the abs() method
Matt Harbison <matt_harbison@yahoo.com>
parents: 23549
diff changeset
464 def abs(self, f):
5b1eac343ccd match: add the abs() method
Matt Harbison <matt_harbison@yahoo.com>
parents: 23549
diff changeset
465 return self._matcher.abs(self._path + "/" + f)
5b1eac343ccd match: add the abs() method
Matt Harbison <matt_harbison@yahoo.com>
parents: 23549
diff changeset
466
23686
164915e8ef7b narrowmatcher: propagate the rel() method
Matt Harbison <matt_harbison@yahoo.com>
parents: 23685
diff changeset
467 def rel(self, f):
164915e8ef7b narrowmatcher: propagate the rel() method
Matt Harbison <matt_harbison@yahoo.com>
parents: 23685
diff changeset
468 return self._matcher.rel(self._path + "/" + f)
164915e8ef7b narrowmatcher: propagate the rel() method
Matt Harbison <matt_harbison@yahoo.com>
parents: 23685
diff changeset
469
32324
77dac8fd30ee match: avoid accessing match._pathrestricted from subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32323
diff changeset
470 def uipath(self, f):
77dac8fd30ee match: avoid accessing match._pathrestricted from subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32323
diff changeset
471 return self._matcher.uipath(self._path + "/" + f)
77dac8fd30ee match: avoid accessing match._pathrestricted from subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32323
diff changeset
472
32323
0aa4032a97e1 match: override visitdir() the usual way in subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32322
diff changeset
473 def visitdir(self, dir):
0aa4032a97e1 match: override visitdir() the usual way in subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32322
diff changeset
474 if dir == '.':
0aa4032a97e1 match: override visitdir() the usual way in subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32322
diff changeset
475 dir = self._path
0aa4032a97e1 match: override visitdir() the usual way in subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32322
diff changeset
476 else:
0aa4032a97e1 match: override visitdir() the usual way in subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32322
diff changeset
477 dir = self._path + "/" + dir
0aa4032a97e1 match: override visitdir() the usual way in subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32322
diff changeset
478 return self._matcher.visitdir(dir)
0aa4032a97e1 match: override visitdir() the usual way in subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32322
diff changeset
479
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
480 def patkind(pattern, default=None):
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
481 '''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
482 return _patsplit(pattern, default)[0]
8570
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
483
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
484 def _patsplit(pattern, default):
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
485 """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
486 pattern."""
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
487 if ':' in pattern:
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
488 kind, pat = pattern.split(':', 1)
13218
1f4721de2ca9 match: support reading pattern lists from files
Steve Borho <steve@borho.org>
parents: 12268
diff changeset
489 if kind in ('re', 'glob', 'path', 'relglob', 'relpath', 'relre',
31012
88358446da16 match: adding support for matching files inside a directory
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 30399
diff changeset
490 'listfile', 'listfile0', 'set', 'include', 'subinclude',
88358446da16 match: adding support for matching files inside a directory
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 30399
diff changeset
491 'rootfilesin'):
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
492 return kind, pat
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
493 return default, pattern
8570
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
494
8582
a4c199e12b5a match: remove head and tail args from _globre
Matt Mackall <mpm@selenic.com>
parents: 8581
diff changeset
495 def _globre(pat):
21112
03782d2fc776 match: _globre doctests
Mads Kiilerich <madski@unity3d.com>
parents: 21111
diff changeset
496 r'''Convert an extended glob string to a regexp string.
03782d2fc776 match: _globre doctests
Mads Kiilerich <madski@unity3d.com>
parents: 21111
diff changeset
497
03782d2fc776 match: _globre doctests
Mads Kiilerich <madski@unity3d.com>
parents: 21111
diff changeset
498 >>> print _globre(r'?')
03782d2fc776 match: _globre doctests
Mads Kiilerich <madski@unity3d.com>
parents: 21111
diff changeset
499 .
03782d2fc776 match: _globre doctests
Mads Kiilerich <madski@unity3d.com>
parents: 21111
diff changeset
500 >>> print _globre(r'*')
03782d2fc776 match: _globre doctests
Mads Kiilerich <madski@unity3d.com>
parents: 21111
diff changeset
501 [^/]*
03782d2fc776 match: _globre doctests
Mads Kiilerich <madski@unity3d.com>
parents: 21111
diff changeset
502 >>> print _globre(r'**')
03782d2fc776 match: _globre doctests
Mads Kiilerich <madski@unity3d.com>
parents: 21111
diff changeset
503 .*
21815
a4b67bf1f0a5 match: make glob '**/' match the empty string
Siddharth Agarwal <sid0@fb.com>
parents: 21191
diff changeset
504 >>> print _globre(r'**/a')
a4b67bf1f0a5 match: make glob '**/' match the empty string
Siddharth Agarwal <sid0@fb.com>
parents: 21191
diff changeset
505 (?:.*/)?a
a4b67bf1f0a5 match: make glob '**/' match the empty string
Siddharth Agarwal <sid0@fb.com>
parents: 21191
diff changeset
506 >>> print _globre(r'a/**/b')
a4b67bf1f0a5 match: make glob '**/' match the empty string
Siddharth Agarwal <sid0@fb.com>
parents: 21191
diff changeset
507 a\/(?:.*/)?b
21112
03782d2fc776 match: _globre doctests
Mads Kiilerich <madski@unity3d.com>
parents: 21111
diff changeset
508 >>> print _globre(r'[a*?!^][^b][!c]')
03782d2fc776 match: _globre doctests
Mads Kiilerich <madski@unity3d.com>
parents: 21111
diff changeset
509 [a*?!^][\^b][^c]
03782d2fc776 match: _globre doctests
Mads Kiilerich <madski@unity3d.com>
parents: 21111
diff changeset
510 >>> print _globre(r'{a,b}')
03782d2fc776 match: _globre doctests
Mads Kiilerich <madski@unity3d.com>
parents: 21111
diff changeset
511 (?:a|b)
03782d2fc776 match: _globre doctests
Mads Kiilerich <madski@unity3d.com>
parents: 21111
diff changeset
512 >>> print _globre(r'.\*\?')
03782d2fc776 match: _globre doctests
Mads Kiilerich <madski@unity3d.com>
parents: 21111
diff changeset
513 \.\*\?
03782d2fc776 match: _globre doctests
Mads Kiilerich <madski@unity3d.com>
parents: 21111
diff changeset
514 '''
8570
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
515 i, n = 0, len(pat)
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
516 res = ''
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
517 group = 0
21915
d516b6de3821 match: use util.re.escape instead of re.escape
Siddharth Agarwal <sid0@fb.com>
parents: 21909
diff changeset
518 escape = util.re.escape
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10263
diff changeset
519 def peek():
31421
5c9cda37d7f6 match: slice over bytes to get the byteschr instead of ascii value
Pulkit Goyal <7895pulkit@gmail.com>
parents: 31420
diff changeset
520 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
521 while i < n:
31421
5c9cda37d7f6 match: slice over bytes to get the byteschr instead of ascii value
Pulkit Goyal <7895pulkit@gmail.com>
parents: 31420
diff changeset
522 c = pat[i:i + 1]
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10263
diff changeset
523 i += 1
8583
19d1b2aec562 match: optimize escaping in _globre
Matt Mackall <mpm@selenic.com>
parents: 8582
diff changeset
524 if c not in '*?[{},\\':
19d1b2aec562 match: optimize escaping in _globre
Matt Mackall <mpm@selenic.com>
parents: 8582
diff changeset
525 res += escape(c)
19d1b2aec562 match: optimize escaping in _globre
Matt Mackall <mpm@selenic.com>
parents: 8582
diff changeset
526 elif c == '*':
8570
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
527 if peek() == '*':
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
528 i += 1
21815
a4b67bf1f0a5 match: make glob '**/' match the empty string
Siddharth Agarwal <sid0@fb.com>
parents: 21191
diff changeset
529 if peek() == '/':
a4b67bf1f0a5 match: make glob '**/' match the empty string
Siddharth Agarwal <sid0@fb.com>
parents: 21191
diff changeset
530 i += 1
a4b67bf1f0a5 match: make glob '**/' match the empty string
Siddharth Agarwal <sid0@fb.com>
parents: 21191
diff changeset
531 res += '(?:.*/)?'
a4b67bf1f0a5 match: make glob '**/' match the empty string
Siddharth Agarwal <sid0@fb.com>
parents: 21191
diff changeset
532 else:
a4b67bf1f0a5 match: make glob '**/' match the empty string
Siddharth Agarwal <sid0@fb.com>
parents: 21191
diff changeset
533 res += '.*'
8570
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
534 else:
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
535 res += '[^/]*'
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
536 elif c == '?':
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
537 res += '.'
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
538 elif c == '[':
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
539 j = i
31421
5c9cda37d7f6 match: slice over bytes to get the byteschr instead of ascii value
Pulkit Goyal <7895pulkit@gmail.com>
parents: 31420
diff changeset
540 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
541 j += 1
31421
5c9cda37d7f6 match: slice over bytes to get the byteschr instead of ascii value
Pulkit Goyal <7895pulkit@gmail.com>
parents: 31420
diff changeset
542 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
543 j += 1
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
544 if j >= n:
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
545 res += '\\['
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
546 else:
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
547 stuff = pat[i:j].replace('\\','\\\\')
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
548 i = j + 1
31421
5c9cda37d7f6 match: slice over bytes to get the byteschr instead of ascii value
Pulkit Goyal <7895pulkit@gmail.com>
parents: 31420
diff changeset
549 if stuff[0:1] == '!':
8570
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
550 stuff = '^' + stuff[1:]
31421
5c9cda37d7f6 match: slice over bytes to get the byteschr instead of ascii value
Pulkit Goyal <7895pulkit@gmail.com>
parents: 31420
diff changeset
551 elif stuff[0:1] == '^':
8570
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
552 stuff = '\\' + stuff
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
553 res = '%s[%s]' % (res, stuff)
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
554 elif c == '{':
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
555 group += 1
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
556 res += '(?:'
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
557 elif c == '}' and group:
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
558 res += ')'
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
559 group -= 1
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
560 elif c == ',' and group:
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
561 res += '|'
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
562 elif c == '\\':
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
563 p = peek()
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
564 if p:
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
565 i += 1
8583
19d1b2aec562 match: optimize escaping in _globre
Matt Mackall <mpm@selenic.com>
parents: 8582
diff changeset
566 res += escape(p)
8570
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
567 else:
8583
19d1b2aec562 match: optimize escaping in _globre
Matt Mackall <mpm@selenic.com>
parents: 8582
diff changeset
568 res += escape(c)
8570
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
569 else:
8583
19d1b2aec562 match: optimize escaping in _globre
Matt Mackall <mpm@selenic.com>
parents: 8582
diff changeset
570 res += escape(c)
8582
a4c199e12b5a match: remove head and tail args from _globre
Matt Mackall <mpm@selenic.com>
parents: 8581
diff changeset
571 return res
8570
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
572
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
573 def _regex(kind, pat, globsuffix):
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
574 '''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
575 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
576 if not pat:
8574
63a7ed2128d5 match: unnest functions in _matcher
Matt Mackall <mpm@selenic.com>
parents: 8573
diff changeset
577 return ''
63a7ed2128d5 match: unnest functions in _matcher
Matt Mackall <mpm@selenic.com>
parents: 8573
diff changeset
578 if kind == 're':
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
579 return pat
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
580 if kind == 'path':
25636
bfe9ed85f27c match: let 'path:.' and 'path:' match everything (issue4687)
Matt Harbison <matt_harbison@yahoo.com>
parents: 25194
diff changeset
581 if pat == '.':
bfe9ed85f27c match: let 'path:.' and 'path:' match everything (issue4687)
Matt Harbison <matt_harbison@yahoo.com>
parents: 25194
diff changeset
582 return ''
21915
d516b6de3821 match: use util.re.escape instead of re.escape
Siddharth Agarwal <sid0@fb.com>
parents: 21909
diff changeset
583 return '^' + util.re.escape(pat) + '(?:/|$)'
31012
88358446da16 match: adding support for matching files inside a directory
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 30399
diff changeset
584 if kind == 'rootfilesin':
88358446da16 match: adding support for matching files inside a directory
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 30399
diff changeset
585 if pat == '.':
88358446da16 match: adding support for matching files inside a directory
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 30399
diff changeset
586 escaped = ''
88358446da16 match: adding support for matching files inside a directory
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 30399
diff changeset
587 else:
88358446da16 match: adding support for matching files inside a directory
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 30399
diff changeset
588 # Pattern is a directory name.
88358446da16 match: adding support for matching files inside a directory
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 30399
diff changeset
589 escaped = util.re.escape(pat) + '/'
88358446da16 match: adding support for matching files inside a directory
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 30399
diff changeset
590 # Anything after the pattern must be a non-directory.
88358446da16 match: adding support for matching files inside a directory
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 30399
diff changeset
591 return '^' + escaped + '[^/]+$'
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
592 if kind == 'relglob':
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
593 return '(?:|.*/)' + _globre(pat) + globsuffix
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
594 if kind == 'relpath':
21915
d516b6de3821 match: use util.re.escape instead of re.escape
Siddharth Agarwal <sid0@fb.com>
parents: 21909
diff changeset
595 return util.re.escape(pat) + '(?:/|$)'
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
596 if kind == 'relre':
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
597 if pat.startswith('^'):
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
598 return pat
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
599 return '.*' + pat
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
600 return _globre(pat) + globsuffix
8574
63a7ed2128d5 match: unnest functions in _matcher
Matt Mackall <mpm@selenic.com>
parents: 8573
diff changeset
601
25238
5a55ad6e8e24 match: add root to _buildmatch
Durham Goode <durham@fb.com>
parents: 25233
diff changeset
602 def _buildmatch(ctx, kindpats, globsuffix, listsubrepos, root):
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
603 '''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
604 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
605 matchfuncs = []
714f612f2afc match: allow unioning arbitrary match functions
Durham Goode <durham@fb.com>
parents: 25238
diff changeset
606
25283
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
607 subincludes, kindpats = _expandsubinclude(kindpats, root)
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
608 if subincludes:
32132
6dea1701f170 match: make subinclude construction lazy
Durham Goode <durham@fb.com>
parents: 31433
diff changeset
609 submatchers = {}
25283
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
610 def matchsubinclude(f):
32132
6dea1701f170 match: make subinclude construction lazy
Durham Goode <durham@fb.com>
parents: 31433
diff changeset
611 for prefix, matcherargs in subincludes:
6dea1701f170 match: make subinclude construction lazy
Durham Goode <durham@fb.com>
parents: 31433
diff changeset
612 if f.startswith(prefix):
6dea1701f170 match: make subinclude construction lazy
Durham Goode <durham@fb.com>
parents: 31433
diff changeset
613 mf = submatchers.get(prefix)
6dea1701f170 match: make subinclude construction lazy
Durham Goode <durham@fb.com>
parents: 31433
diff changeset
614 if mf is None:
6dea1701f170 match: make subinclude construction lazy
Durham Goode <durham@fb.com>
parents: 31433
diff changeset
615 mf = match(*matcherargs)
6dea1701f170 match: make subinclude construction lazy
Durham Goode <durham@fb.com>
parents: 31433
diff changeset
616 submatchers[prefix] = mf
6dea1701f170 match: make subinclude construction lazy
Durham Goode <durham@fb.com>
parents: 31433
diff changeset
617
6dea1701f170 match: make subinclude construction lazy
Durham Goode <durham@fb.com>
parents: 31433
diff changeset
618 if mf(f[len(prefix):]):
6dea1701f170 match: make subinclude construction lazy
Durham Goode <durham@fb.com>
parents: 31433
diff changeset
619 return True
25283
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
620 return False
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
621 matchfuncs.append(matchsubinclude)
14675
cfc89398f710 match: introduce basic fileset support
Matt Mackall <mpm@selenic.com>
parents: 14674
diff changeset
622
25122
755d23a49170 match: resolve filesets in subrepos for commands given the '-S' argument
Matt Harbison <matt_harbison@yahoo.com>
parents: 25114
diff changeset
623 fset, kindpats = _expandsets(kindpats, ctx, listsubrepos)
14675
cfc89398f710 match: introduce basic fileset support
Matt Mackall <mpm@selenic.com>
parents: 14674
diff changeset
624 if fset:
25239
714f612f2afc match: allow unioning arbitrary match functions
Durham Goode <durham@fb.com>
parents: 25238
diff changeset
625 matchfuncs.append(fset.__contains__)
14675
cfc89398f710 match: introduce basic fileset support
Matt Mackall <mpm@selenic.com>
parents: 14674
diff changeset
626
25239
714f612f2afc match: allow unioning arbitrary match functions
Durham Goode <durham@fb.com>
parents: 25238
diff changeset
627 regex = ''
714f612f2afc match: allow unioning arbitrary match functions
Durham Goode <durham@fb.com>
parents: 25238
diff changeset
628 if kindpats:
714f612f2afc match: allow unioning arbitrary match functions
Durham Goode <durham@fb.com>
parents: 25238
diff changeset
629 regex, mf = _buildregexmatch(kindpats, globsuffix)
714f612f2afc match: allow unioning arbitrary match functions
Durham Goode <durham@fb.com>
parents: 25238
diff changeset
630 matchfuncs.append(mf)
714f612f2afc match: allow unioning arbitrary match functions
Durham Goode <durham@fb.com>
parents: 25238
diff changeset
631
714f612f2afc match: allow unioning arbitrary match functions
Durham Goode <durham@fb.com>
parents: 25238
diff changeset
632 if len(matchfuncs) == 1:
714f612f2afc match: allow unioning arbitrary match functions
Durham Goode <durham@fb.com>
parents: 25238
diff changeset
633 return regex, matchfuncs[0]
714f612f2afc match: allow unioning arbitrary match functions
Durham Goode <durham@fb.com>
parents: 25238
diff changeset
634 else:
714f612f2afc match: allow unioning arbitrary match functions
Durham Goode <durham@fb.com>
parents: 25238
diff changeset
635 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
636
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
637 def _buildregexmatch(kindpats, globsuffix):
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
638 """Build a match function from a list of kinds and kindpats,
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
639 return regexp string and a matcher function."""
8574
63a7ed2128d5 match: unnest functions in _matcher
Matt Mackall <mpm@selenic.com>
parents: 8573
diff changeset
640 try:
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
641 regex = '(?:%s)' % '|'.join([_regex(k, p, globsuffix)
25213
08a8e9da0ae7 match: add source to kindpats list
Durham Goode <durham@fb.com>
parents: 25195
diff changeset
642 for (k, p, s) in kindpats])
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
643 if len(regex) > 20000:
16687
e34106fa0dc3 cleanup: "raise SomeException()" -> "raise SomeException"
Brodie Rao <brodie@sf.io>
parents: 16645
diff changeset
644 raise OverflowError
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
645 return regex, _rematcher(regex)
8574
63a7ed2128d5 match: unnest functions in _matcher
Matt Mackall <mpm@selenic.com>
parents: 8573
diff changeset
646 except OverflowError:
63a7ed2128d5 match: unnest functions in _matcher
Matt Mackall <mpm@selenic.com>
parents: 8573
diff changeset
647 # We're using a Python with a tiny regex engine and we
63a7ed2128d5 match: unnest functions in _matcher
Matt Mackall <mpm@selenic.com>
parents: 8573
diff changeset
648 # made it explode, so we'll divide the pattern list in two
63a7ed2128d5 match: unnest functions in _matcher
Matt Mackall <mpm@selenic.com>
parents: 8573
diff changeset
649 # until it works
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
650 l = len(kindpats)
8574
63a7ed2128d5 match: unnest functions in _matcher
Matt Mackall <mpm@selenic.com>
parents: 8573
diff changeset
651 if l < 2:
63a7ed2128d5 match: unnest functions in _matcher
Matt Mackall <mpm@selenic.com>
parents: 8573
diff changeset
652 raise
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
653 regexa, a = _buildregexmatch(kindpats[:l//2], globsuffix)
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
654 regexb, b = _buildregexmatch(kindpats[l//2:], globsuffix)
21191
a2f4ea82d6d3 match: fix NameError 'pat' on overflow of regex pattern length
Yuya Nishihara <yuya@tcha.org>
parents: 21113
diff changeset
655 return regex, lambda s: a(s) or b(s)
8574
63a7ed2128d5 match: unnest functions in _matcher
Matt Mackall <mpm@selenic.com>
parents: 8573
diff changeset
656 except re.error:
25213
08a8e9da0ae7 match: add source to kindpats list
Durham Goode <durham@fb.com>
parents: 25195
diff changeset
657 for k, p, s in kindpats:
8574
63a7ed2128d5 match: unnest functions in _matcher
Matt Mackall <mpm@selenic.com>
parents: 8573
diff changeset
658 try:
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
659 _rematcher('(?:%s)' % _regex(k, p, globsuffix))
8574
63a7ed2128d5 match: unnest functions in _matcher
Matt Mackall <mpm@selenic.com>
parents: 8573
diff changeset
660 except re.error:
25213
08a8e9da0ae7 match: add source to kindpats list
Durham Goode <durham@fb.com>
parents: 25195
diff changeset
661 if s:
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26014
diff changeset
662 raise error.Abort(_("%s: invalid pattern (%s): %s") %
25213
08a8e9da0ae7 match: add source to kindpats list
Durham Goode <durham@fb.com>
parents: 25195
diff changeset
663 (s, k, p))
08a8e9da0ae7 match: add source to kindpats list
Durham Goode <durham@fb.com>
parents: 25195
diff changeset
664 else:
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26014
diff changeset
665 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
666 raise error.Abort(_("invalid pattern"))
8574
63a7ed2128d5 match: unnest functions in _matcher
Matt Mackall <mpm@selenic.com>
parents: 8573
diff changeset
667
31013
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31012
diff changeset
668 def _patternrootsanddirs(kindpats):
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31012
diff changeset
669 '''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
670
31013
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31012
diff changeset
671 This calculates the roots and directories exactly matching the patterns and
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31012
diff changeset
672 returns a tuple of (roots, dirs) for each. It does not return other
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31012
diff changeset
673 directories which may also need to be considered, like the parent
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31012
diff changeset
674 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
675 '''
8576
ec4ed21db4b2 match: split up _normalizepats
Matt Mackall <mpm@selenic.com>
parents: 8575
diff changeset
676 r = []
31013
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31012
diff changeset
677 d = []
25213
08a8e9da0ae7 match: add source to kindpats list
Durham Goode <durham@fb.com>
parents: 25195
diff changeset
678 for kind, pat, source in kindpats:
8584
0f06e72abfdc match: fold _globprefix into _roots
Matt Mackall <mpm@selenic.com>
parents: 8583
diff changeset
679 if kind == 'glob': # find the non-glob prefix
0f06e72abfdc match: fold _globprefix into _roots
Matt Mackall <mpm@selenic.com>
parents: 8583
diff changeset
680 root = []
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
681 for p in pat.split('/'):
8584
0f06e72abfdc match: fold _globprefix into _roots
Matt Mackall <mpm@selenic.com>
parents: 8583
diff changeset
682 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
683 break
0f06e72abfdc match: fold _globprefix into _roots
Matt Mackall <mpm@selenic.com>
parents: 8583
diff changeset
684 root.append(p)
0f06e72abfdc match: fold _globprefix into _roots
Matt Mackall <mpm@selenic.com>
parents: 8583
diff changeset
685 r.append('/'.join(root) or '.')
31013
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31012
diff changeset
686 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
687 r.append(pat or '.')
31013
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31012
diff changeset
688 elif kind in ('rootfilesin',):
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31012
diff changeset
689 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
690 else: # relglob, re, relre
8576
ec4ed21db4b2 match: split up _normalizepats
Matt Mackall <mpm@selenic.com>
parents: 8575
diff changeset
691 r.append('.')
31013
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31012
diff changeset
692 return r, d
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31012
diff changeset
693
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31012
diff changeset
694 def _roots(kindpats):
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31012
diff changeset
695 '''Returns root directories to match recursively from the given patterns.'''
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31012
diff changeset
696 roots, dirs = _patternrootsanddirs(kindpats)
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31012
diff changeset
697 return roots
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31012
diff changeset
698
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31012
diff changeset
699 def _rootsanddirs(kindpats):
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31012
diff changeset
700 '''Returns roots and exact directories from patterns.
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31012
diff changeset
701
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31012
diff changeset
702 roots are directories to match recursively, whereas exact directories should
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31012
diff changeset
703 be matched non-recursively. The returned (roots, dirs) tuple will also
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31012
diff changeset
704 include directories that need to be implicitly considered as either, such as
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31012
diff changeset
705 parent directories.
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31012
diff changeset
706
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31012
diff changeset
707 >>> _rootsanddirs(\
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31012
diff changeset
708 [('glob', 'g/h/*', ''), ('glob', 'g/h', ''), ('glob', 'g*', '')])
32176
cf042543afa2 match: optimize visitdir() for patterns matching only root directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 32132
diff changeset
709 (['g/h', 'g/h', '.'], ['g', '.'])
31013
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31012
diff changeset
710 >>> _rootsanddirs(\
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31012
diff changeset
711 [('rootfilesin', 'g/h', ''), ('rootfilesin', '', '')])
32176
cf042543afa2 match: optimize visitdir() for patterns matching only root directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 32132
diff changeset
712 ([], ['g/h', '.', 'g', '.'])
31013
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31012
diff changeset
713 >>> _rootsanddirs(\
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31012
diff changeset
714 [('relpath', 'r', ''), ('path', 'p/p', ''), ('path', '', '')])
32176
cf042543afa2 match: optimize visitdir() for patterns matching only root directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 32132
diff changeset
715 (['r', 'p/p', '.'], ['p', '.'])
31013
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31012
diff changeset
716 >>> _rootsanddirs(\
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31012
diff changeset
717 [('relglob', 'rg*', ''), ('re', 're/', ''), ('relre', 'rr', '')])
32176
cf042543afa2 match: optimize visitdir() for patterns matching only root directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 32132
diff changeset
718 (['.', '.', '.'], ['.'])
31013
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31012
diff changeset
719 '''
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31012
diff changeset
720 r, d = _patternrootsanddirs(kindpats)
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31012
diff changeset
721
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31012
diff changeset
722 # 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: 31012
diff changeset
723 # scanned to get to either the roots or the other exact directories.
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31012
diff changeset
724 d.extend(util.dirs(d))
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31012
diff changeset
725 d.extend(util.dirs(r))
32176
cf042543afa2 match: optimize visitdir() for patterns matching only root directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 32132
diff changeset
726 # util.dirs() does not include the root directory, so add it manually
cf042543afa2 match: optimize visitdir() for patterns matching only root directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 32132
diff changeset
727 d.append('.')
31013
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31012
diff changeset
728
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31012
diff changeset
729 return r, d
8576
ec4ed21db4b2 match: split up _normalizepats
Matt Mackall <mpm@selenic.com>
parents: 8575
diff changeset
730
31012
88358446da16 match: adding support for matching files inside a directory
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 30399
diff changeset
731 def _explicitfiles(kindpats):
88358446da16 match: adding support for matching files inside a directory
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 30399
diff changeset
732 '''Returns the potential explicit filenames from the patterns.
88358446da16 match: adding support for matching files inside a directory
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 30399
diff changeset
733
88358446da16 match: adding support for matching files inside a directory
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 30399
diff changeset
734 >>> _explicitfiles([('path', 'foo/bar', '')])
88358446da16 match: adding support for matching files inside a directory
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 30399
diff changeset
735 ['foo/bar']
88358446da16 match: adding support for matching files inside a directory
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 30399
diff changeset
736 >>> _explicitfiles([('rootfilesin', 'foo/bar', '')])
88358446da16 match: adding support for matching files inside a directory
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 30399
diff changeset
737 []
88358446da16 match: adding support for matching files inside a directory
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 30399
diff changeset
738 '''
88358446da16 match: adding support for matching files inside a directory
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 30399
diff changeset
739 # Keep only the pattern kinds where one can specify filenames (vs only
88358446da16 match: adding support for matching files inside a directory
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 30399
diff changeset
740 # directory names).
88358446da16 match: adding support for matching files inside a directory
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 30399
diff changeset
741 filable = [kp for kp in kindpats if kp[0] not in ('rootfilesin',)]
88358446da16 match: adding support for matching files inside a directory
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 30399
diff changeset
742 return _roots(filable)
88358446da16 match: adding support for matching files inside a directory
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 30399
diff changeset
743
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
744 def _anypats(kindpats):
25213
08a8e9da0ae7 match: add source to kindpats list
Durham Goode <durham@fb.com>
parents: 25195
diff changeset
745 for kind, pat, source in kindpats:
31012
88358446da16 match: adding support for matching files inside a directory
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 30399
diff changeset
746 if kind in ('glob', 're', 'relglob', 'relre', 'set', 'rootfilesin'):
8576
ec4ed21db4b2 match: split up _normalizepats
Matt Mackall <mpm@selenic.com>
parents: 8575
diff changeset
747 return True
25167
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
748
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
749 _commentre = None
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
750
27595
9e2d01707e71 match: add option to return line and lineno from readpattern
Laurent Charignon <lcharignon@fb.com>
parents: 27343
diff changeset
751 def readpatternfile(filepath, warn, sourceinfo=False):
25167
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
752 '''parse a pattern file, returning a list of
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
753 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
754 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
755
dc562165044a ignore: use 'include:' rules instead of custom syntax
Durham Goode <durham@fb.com>
parents: 25215
diff changeset
756 trailing white space is dropped.
dc562165044a ignore: use 'include:' rules instead of custom syntax
Durham Goode <durham@fb.com>
parents: 25215
diff changeset
757 the escape character is backslash.
dc562165044a ignore: use 'include:' rules instead of custom syntax
Durham Goode <durham@fb.com>
parents: 25215
diff changeset
758 comments start with #.
dc562165044a ignore: use 'include:' rules instead of custom syntax
Durham Goode <durham@fb.com>
parents: 25215
diff changeset
759 empty lines are skipped.
dc562165044a ignore: use 'include:' rules instead of custom syntax
Durham Goode <durham@fb.com>
parents: 25215
diff changeset
760
dc562165044a ignore: use 'include:' rules instead of custom syntax
Durham Goode <durham@fb.com>
parents: 25215
diff changeset
761 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
762
dc562165044a ignore: use 'include:' rules instead of custom syntax
Durham Goode <durham@fb.com>
parents: 25215
diff changeset
763 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
764 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
765 re:pattern # non-rooted regular expression
dc562165044a ignore: use 'include:' rules instead of custom syntax
Durham Goode <durham@fb.com>
parents: 25215
diff changeset
766 glob:pattern # non-rooted glob
27595
9e2d01707e71 match: add option to return line and lineno from readpattern
Laurent Charignon <lcharignon@fb.com>
parents: 27343
diff changeset
767 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
768
9e2d01707e71 match: add option to return line and lineno from readpattern
Laurent Charignon <lcharignon@fb.com>
parents: 27343
diff changeset
769 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
770 (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
771 '''
25216
dc562165044a ignore: use 'include:' rules instead of custom syntax
Durham Goode <durham@fb.com>
parents: 25215
diff changeset
772
25215
4040e06e9b99 match: add 'include:' syntax
Durham Goode <durham@fb.com>
parents: 25214
diff changeset
773 syntaxes = {'re': 'relre:', 'regexp': 'relre:', 'glob': 'relglob:',
25283
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
774 'include': 'include', 'subinclude': 'subinclude'}
25167
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
775 syntax = 'relre:'
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
776 patterns = []
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
777
31403
10c17f8bfcf3 py3: open file in rb mode
Rishabh Madan <rishabhmadan96@gmail.com>
parents: 31392
diff changeset
778 fp = open(filepath, 'rb')
30399
7f3593c29473 match: migrate to util.iterfile
Jun Wu <quark@fb.com>
parents: 29803
diff changeset
779 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
780 if "#" in line:
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
781 global _commentre
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
782 if not _commentre:
31420
40704098853f match: make regular expression bytes to prevent TypeError
Pulkit Goyal <7895pulkit@gmail.com>
parents: 31403
diff changeset
783 _commentre = util.re.compile(br'((?:^|[^\\])(?:\\\\)*)#.*')
25167
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
784 # 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
785 m = _commentre.search(line)
d500341e4f55 match: use re2 in readpatternfile if possible
Bryan O'Sullivan <bos@serpentine.com>
parents: 26781
diff changeset
786 if m:
d500341e4f55 match: use re2 in readpatternfile if possible
Bryan O'Sullivan <bos@serpentine.com>
parents: 26781
diff changeset
787 line = line[:m.end(1)]
25167
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
788 # fixup properly escaped comments that survived the above
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
789 line = line.replace("\\#", "#")
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
790 line = line.rstrip()
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
791 if not line:
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
792 continue
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
793
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
794 if line.startswith('syntax:'):
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
795 s = line[7:].strip()
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
796 try:
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
797 syntax = syntaxes[s]
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
798 except KeyError:
25214
08703b10c3ae match: add optional warn argument
Durham Goode <durham@fb.com>
parents: 25213
diff changeset
799 if warn:
08703b10c3ae match: add optional warn argument
Durham Goode <durham@fb.com>
parents: 25213
diff changeset
800 warn(_("%s: ignoring invalid syntax '%s'\n") %
08703b10c3ae match: add optional warn argument
Durham Goode <durham@fb.com>
parents: 25213
diff changeset
801 (filepath, s))
25167
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
802 continue
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
803
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
804 linesyntax = syntax
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
805 for s, rels in syntaxes.iteritems():
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
806 if line.startswith(rels):
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
807 linesyntax = rels
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
808 line = line[len(rels):]
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
809 break
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
810 elif line.startswith(s+':'):
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
811 linesyntax = rels
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
812 line = line[len(s) + 1:]
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
813 break
27595
9e2d01707e71 match: add option to return line and lineno from readpattern
Laurent Charignon <lcharignon@fb.com>
parents: 27343
diff changeset
814 if sourceinfo:
9e2d01707e71 match: add option to return line and lineno from readpattern
Laurent Charignon <lcharignon@fb.com>
parents: 27343
diff changeset
815 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
816 else:
9e2d01707e71 match: add option to return line and lineno from readpattern
Laurent Charignon <lcharignon@fb.com>
parents: 27343
diff changeset
817 patterns.append(linesyntax + line)
25167
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
818 fp.close()
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
819 return patterns