comparison mercurial/fileset.py @ 38863:61ab546b71c3

fileset: introduce weight constants for readability These constants are defined in the filesetlang module since it's the bottommost module depending on WEIGHT_CHECK_FILENAME, and extensions will be likely to import it to process function arguments. Credit for the naming goes to Augie Fackler.
author Yuya Nishihara <yuya@tcha.org>
date Sat, 04 Aug 2018 17:08:33 +0900
parents bfd5def3fe02
children 899b4c74209c
comparison
equal deleted inserted replaced
38862:1ff45c518e6f 38863:61ab546b71c3
23 ) 23 )
24 from .utils import ( 24 from .utils import (
25 stringutil, 25 stringutil,
26 ) 26 )
27 27
28 # common weight constants
29 _WEIGHT_CHECK_FILENAME = filesetlang.WEIGHT_CHECK_FILENAME
30 _WEIGHT_READ_CONTENTS = filesetlang.WEIGHT_READ_CONTENTS
31 _WEIGHT_STATUS = filesetlang.WEIGHT_STATUS
32 _WEIGHT_STATUS_THOROUGH = filesetlang.WEIGHT_STATUS_THOROUGH
33
28 # helpers for processing parsed tree 34 # helpers for processing parsed tree
29 getsymbol = filesetlang.getsymbol 35 getsymbol = filesetlang.getsymbol
30 getstring = filesetlang.getstring 36 getstring = filesetlang.getstring
31 _getkindpat = filesetlang.getkindpat 37 _getkindpat = filesetlang.getkindpat
32 getpattern = filesetlang.getpattern 38 getpattern = filesetlang.getpattern
86 # filesets using matchctx.status() 92 # filesets using matchctx.status()
87 _statuscallers = set() 93 _statuscallers = set()
88 94
89 predicate = registrar.filesetpredicate() 95 predicate = registrar.filesetpredicate()
90 96
91 @predicate('modified()', callstatus=True, weight=10) 97 @predicate('modified()', callstatus=True, weight=_WEIGHT_STATUS)
92 def modified(mctx, x): 98 def modified(mctx, x):
93 """File that is modified according to :hg:`status`. 99 """File that is modified according to :hg:`status`.
94 """ 100 """
95 # i18n: "modified" is a keyword 101 # i18n: "modified" is a keyword
96 getargs(x, 0, 0, _("modified takes no arguments")) 102 getargs(x, 0, 0, _("modified takes no arguments"))
97 s = set(mctx.status().modified) 103 s = set(mctx.status().modified)
98 return mctx.predicate(s.__contains__, predrepr='modified') 104 return mctx.predicate(s.__contains__, predrepr='modified')
99 105
100 @predicate('added()', callstatus=True, weight=10) 106 @predicate('added()', callstatus=True, weight=_WEIGHT_STATUS)
101 def added(mctx, x): 107 def added(mctx, x):
102 """File that is added according to :hg:`status`. 108 """File that is added according to :hg:`status`.
103 """ 109 """
104 # i18n: "added" is a keyword 110 # i18n: "added" is a keyword
105 getargs(x, 0, 0, _("added takes no arguments")) 111 getargs(x, 0, 0, _("added takes no arguments"))
106 s = set(mctx.status().added) 112 s = set(mctx.status().added)
107 return mctx.predicate(s.__contains__, predrepr='added') 113 return mctx.predicate(s.__contains__, predrepr='added')
108 114
109 @predicate('removed()', callstatus=True, weight=10) 115 @predicate('removed()', callstatus=True, weight=_WEIGHT_STATUS)
110 def removed(mctx, x): 116 def removed(mctx, x):
111 """File that is removed according to :hg:`status`. 117 """File that is removed according to :hg:`status`.
112 """ 118 """
113 # i18n: "removed" is a keyword 119 # i18n: "removed" is a keyword
114 getargs(x, 0, 0, _("removed takes no arguments")) 120 getargs(x, 0, 0, _("removed takes no arguments"))
115 s = set(mctx.status().removed) 121 s = set(mctx.status().removed)
116 return mctx.predicate(s.__contains__, predrepr='removed') 122 return mctx.predicate(s.__contains__, predrepr='removed')
117 123
118 @predicate('deleted()', callstatus=True, weight=10) 124 @predicate('deleted()', callstatus=True, weight=_WEIGHT_STATUS)
119 def deleted(mctx, x): 125 def deleted(mctx, x):
120 """Alias for ``missing()``. 126 """Alias for ``missing()``.
121 """ 127 """
122 # i18n: "deleted" is a keyword 128 # i18n: "deleted" is a keyword
123 getargs(x, 0, 0, _("deleted takes no arguments")) 129 getargs(x, 0, 0, _("deleted takes no arguments"))
124 s = set(mctx.status().deleted) 130 s = set(mctx.status().deleted)
125 return mctx.predicate(s.__contains__, predrepr='deleted') 131 return mctx.predicate(s.__contains__, predrepr='deleted')
126 132
127 @predicate('missing()', callstatus=True, weight=10) 133 @predicate('missing()', callstatus=True, weight=_WEIGHT_STATUS)
128 def missing(mctx, x): 134 def missing(mctx, x):
129 """File that is missing according to :hg:`status`. 135 """File that is missing according to :hg:`status`.
130 """ 136 """
131 # i18n: "missing" is a keyword 137 # i18n: "missing" is a keyword
132 getargs(x, 0, 0, _("missing takes no arguments")) 138 getargs(x, 0, 0, _("missing takes no arguments"))
133 s = set(mctx.status().deleted) 139 s = set(mctx.status().deleted)
134 return mctx.predicate(s.__contains__, predrepr='deleted') 140 return mctx.predicate(s.__contains__, predrepr='deleted')
135 141
136 @predicate('unknown()', callstatus=True, weight=50) 142 @predicate('unknown()', callstatus=True, weight=_WEIGHT_STATUS_THOROUGH)
137 def unknown(mctx, x): 143 def unknown(mctx, x):
138 """File that is unknown according to :hg:`status`.""" 144 """File that is unknown according to :hg:`status`."""
139 # i18n: "unknown" is a keyword 145 # i18n: "unknown" is a keyword
140 getargs(x, 0, 0, _("unknown takes no arguments")) 146 getargs(x, 0, 0, _("unknown takes no arguments"))
141 s = set(mctx.status().unknown) 147 s = set(mctx.status().unknown)
142 return mctx.predicate(s.__contains__, predrepr='unknown') 148 return mctx.predicate(s.__contains__, predrepr='unknown')
143 149
144 @predicate('ignored()', callstatus=True, weight=50) 150 @predicate('ignored()', callstatus=True, weight=_WEIGHT_STATUS_THOROUGH)
145 def ignored(mctx, x): 151 def ignored(mctx, x):
146 """File that is ignored according to :hg:`status`.""" 152 """File that is ignored according to :hg:`status`."""
147 # i18n: "ignored" is a keyword 153 # i18n: "ignored" is a keyword
148 getargs(x, 0, 0, _("ignored takes no arguments")) 154 getargs(x, 0, 0, _("ignored takes no arguments"))
149 s = set(mctx.status().ignored) 155 s = set(mctx.status().ignored)
150 return mctx.predicate(s.__contains__, predrepr='ignored') 156 return mctx.predicate(s.__contains__, predrepr='ignored')
151 157
152 @predicate('clean()', callstatus=True, weight=10) 158 @predicate('clean()', callstatus=True, weight=_WEIGHT_STATUS)
153 def clean(mctx, x): 159 def clean(mctx, x):
154 """File that is clean according to :hg:`status`. 160 """File that is clean according to :hg:`status`.
155 """ 161 """
156 # i18n: "clean" is a keyword 162 # i18n: "clean" is a keyword
157 getargs(x, 0, 0, _("clean takes no arguments")) 163 getargs(x, 0, 0, _("clean takes no arguments"))
163 """File that is under Mercurial control.""" 169 """File that is under Mercurial control."""
164 # i18n: "tracked" is a keyword 170 # i18n: "tracked" is a keyword
165 getargs(x, 0, 0, _("tracked takes no arguments")) 171 getargs(x, 0, 0, _("tracked takes no arguments"))
166 return mctx.predicate(mctx.ctx.__contains__, predrepr='tracked') 172 return mctx.predicate(mctx.ctx.__contains__, predrepr='tracked')
167 173
168 @predicate('binary()', weight=30) 174 @predicate('binary()', weight=_WEIGHT_READ_CONTENTS)
169 def binary(mctx, x): 175 def binary(mctx, x):
170 """File that appears to be binary (contains NUL bytes). 176 """File that appears to be binary (contains NUL bytes).
171 """ 177 """
172 # i18n: "binary" is a keyword 178 # i18n: "binary" is a keyword
173 getargs(x, 0, 0, _("binary takes no arguments")) 179 getargs(x, 0, 0, _("binary takes no arguments"))
190 # i18n: "symlink" is a keyword 196 # i18n: "symlink" is a keyword
191 getargs(x, 0, 0, _("symlink takes no arguments")) 197 getargs(x, 0, 0, _("symlink takes no arguments"))
192 ctx = mctx.ctx 198 ctx = mctx.ctx
193 return mctx.predicate(lambda f: ctx.flags(f) == 'l', predrepr='symlink') 199 return mctx.predicate(lambda f: ctx.flags(f) == 'l', predrepr='symlink')
194 200
195 @predicate('resolved()', weight=10) 201 @predicate('resolved()', weight=_WEIGHT_STATUS)
196 def resolved(mctx, x): 202 def resolved(mctx, x):
197 """File that is marked resolved according to :hg:`resolve -l`. 203 """File that is marked resolved according to :hg:`resolve -l`.
198 """ 204 """
199 # i18n: "resolved" is a keyword 205 # i18n: "resolved" is a keyword
200 getargs(x, 0, 0, _("resolved takes no arguments")) 206 getargs(x, 0, 0, _("resolved takes no arguments"))
202 return mctx.never() 208 return mctx.never()
203 ms = merge.mergestate.read(mctx.ctx.repo()) 209 ms = merge.mergestate.read(mctx.ctx.repo())
204 return mctx.predicate(lambda f: f in ms and ms[f] == 'r', 210 return mctx.predicate(lambda f: f in ms and ms[f] == 'r',
205 predrepr='resolved') 211 predrepr='resolved')
206 212
207 @predicate('unresolved()', weight=10) 213 @predicate('unresolved()', weight=_WEIGHT_STATUS)
208 def unresolved(mctx, x): 214 def unresolved(mctx, x):
209 """File that is marked unresolved according to :hg:`resolve -l`. 215 """File that is marked unresolved according to :hg:`resolve -l`.
210 """ 216 """
211 # i18n: "unresolved" is a keyword 217 # i18n: "unresolved" is a keyword
212 getargs(x, 0, 0, _("unresolved takes no arguments")) 218 getargs(x, 0, 0, _("unresolved takes no arguments"))
214 return mctx.never() 220 return mctx.never()
215 ms = merge.mergestate.read(mctx.ctx.repo()) 221 ms = merge.mergestate.read(mctx.ctx.repo())
216 return mctx.predicate(lambda f: f in ms and ms[f] == 'u', 222 return mctx.predicate(lambda f: f in ms and ms[f] == 'u',
217 predrepr='unresolved') 223 predrepr='unresolved')
218 224
219 @predicate('hgignore()', weight=10) 225 @predicate('hgignore()', weight=_WEIGHT_STATUS)
220 def hgignore(mctx, x): 226 def hgignore(mctx, x):
221 """File that matches the active .hgignore pattern. 227 """File that matches the active .hgignore pattern.
222 """ 228 """
223 # i18n: "hgignore" is a keyword 229 # i18n: "hgignore" is a keyword
224 getargs(x, 0, 0, _("hgignore takes no arguments")) 230 getargs(x, 0, 0, _("hgignore takes no arguments"))
225 return mctx.ctx.repo().dirstate._ignore 231 return mctx.ctx.repo().dirstate._ignore
226 232
227 @predicate('portable()', weight=0.5) 233 @predicate('portable()', weight=_WEIGHT_CHECK_FILENAME)
228 def portable(mctx, x): 234 def portable(mctx, x):
229 """File that has a portable name. (This doesn't include filenames with case 235 """File that has a portable name. (This doesn't include filenames with case
230 collisions.) 236 collisions.)
231 """ 237 """
232 # i18n: "portable" is a keyword 238 # i18n: "portable" is a keyword
233 getargs(x, 0, 0, _("portable takes no arguments")) 239 getargs(x, 0, 0, _("portable takes no arguments"))
234 return mctx.predicate(lambda f: util.checkwinfilename(f) is None, 240 return mctx.predicate(lambda f: util.checkwinfilename(f) is None,
235 predrepr='portable') 241 predrepr='portable')
236 242
237 @predicate('grep(regex)', weight=30) 243 @predicate('grep(regex)', weight=_WEIGHT_READ_CONTENTS)
238 def grep(mctx, x): 244 def grep(mctx, x):
239 """File contains the given regular expression. 245 """File contains the given regular expression.
240 """ 246 """
241 try: 247 try:
242 # i18n: "grep" is a keyword 248 # i18n: "grep" is a keyword
286 else: 292 else:
287 a = util.sizetoint(expr) 293 a = util.sizetoint(expr)
288 b = _sizetomax(expr) 294 b = _sizetomax(expr)
289 return lambda x: x >= a and x <= b 295 return lambda x: x >= a and x <= b
290 296
291 @predicate('size(expression)', weight=10) 297 @predicate('size(expression)', weight=_WEIGHT_STATUS)
292 def size(mctx, x): 298 def size(mctx, x):
293 """File size matches the given expression. Examples: 299 """File size matches the given expression. Examples:
294 300
295 - size('1k') - files from 1024 to 2047 bytes 301 - size('1k') - files from 1024 to 2047 bytes
296 - size('< 20k') - files less than 20480 bytes 302 - size('< 20k') - files less than 20480 bytes
301 expr = getstring(x, _("size requires an expression")) 307 expr = getstring(x, _("size requires an expression"))
302 m = sizematcher(expr) 308 m = sizematcher(expr)
303 return mctx.fpredicate(lambda fctx: m(fctx.size()), 309 return mctx.fpredicate(lambda fctx: m(fctx.size()),
304 predrepr=('size(%r)', expr), cache=True) 310 predrepr=('size(%r)', expr), cache=True)
305 311
306 @predicate('encoding(name)', weight=30) 312 @predicate('encoding(name)', weight=_WEIGHT_READ_CONTENTS)
307 def encoding(mctx, x): 313 def encoding(mctx, x):
308 """File can be successfully decoded with the given character 314 """File can be successfully decoded with the given character
309 encoding. May not be useful for encodings other than ASCII and 315 encoding. May not be useful for encodings other than ASCII and
310 UTF-8. 316 UTF-8.
311 """ 317 """
323 except UnicodeDecodeError: 329 except UnicodeDecodeError:
324 return False 330 return False
325 331
326 return mctx.fpredicate(encp, predrepr=('encoding(%r)', enc), cache=True) 332 return mctx.fpredicate(encp, predrepr=('encoding(%r)', enc), cache=True)
327 333
328 @predicate('eol(style)', weight=30) 334 @predicate('eol(style)', weight=_WEIGHT_READ_CONTENTS)
329 def eol(mctx, x): 335 def eol(mctx, x):
330 """File contains newlines of the given style (dos, unix, mac). Binary 336 """File contains newlines of the given style (dos, unix, mac). Binary
331 files are excluded, files with mixed line endings match multiple 337 files are excluded, files with mixed line endings match multiple
332 styles. 338 styles.
333 """ 339 """
357 def copiedp(fctx): 363 def copiedp(fctx):
358 p = fctx.parents() 364 p = fctx.parents()
359 return p and p[0].path() != fctx.path() 365 return p and p[0].path() != fctx.path()
360 return mctx.fpredicate(copiedp, predrepr='copied', cache=True) 366 return mctx.fpredicate(copiedp, predrepr='copied', cache=True)
361 367
362 @predicate('revs(revs, pattern)', weight=10) 368 @predicate('revs(revs, pattern)', weight=_WEIGHT_STATUS)
363 def revs(mctx, x): 369 def revs(mctx, x):
364 """Evaluate set in the specified revisions. If the revset match multiple 370 """Evaluate set in the specified revisions. If the revset match multiple
365 revs, this will return file matching pattern in any of the revision. 371 revs, this will return file matching pattern in any of the revision.
366 """ 372 """
367 # i18n: "revs" is a keyword 373 # i18n: "revs" is a keyword
379 return mctx.never() 385 return mctx.never()
380 if len(matchers) == 1: 386 if len(matchers) == 1:
381 return matchers[0] 387 return matchers[0]
382 return matchmod.unionmatcher(matchers) 388 return matchmod.unionmatcher(matchers)
383 389
384 @predicate('status(base, rev, pattern)', weight=10) 390 @predicate('status(base, rev, pattern)', weight=_WEIGHT_STATUS)
385 def status(mctx, x): 391 def status(mctx, x):
386 """Evaluate predicate using status change between ``base`` and 392 """Evaluate predicate using status change between ``base`` and
387 ``rev``. Examples: 393 ``rev``. Examples:
388 394
389 - ``status(3, 7, added())`` - matches files added from "3" to "7" 395 - ``status(3, 7, added())`` - matches files added from "3" to "7"