comparison mercurial/fileset.py @ 14683:281102f37b24

fileset: add size() predicate
author Matt Mackall <mpm@selenic.com>
date Sat, 18 Jun 2011 16:53:49 -0500
parents 8785fd757077
children 87b9d6a7d807
comparison
equal deleted inserted replaced
14682:8785fd757077 14683:281102f37b24
241 """ 241 """
242 pat = getstring(x, _("grep requires a pattern")) 242 pat = getstring(x, _("grep requires a pattern"))
243 r = re.compile(pat) 243 r = re.compile(pat)
244 return [f for f in mctx.subset if r.search(mctx.ctx[f].data())] 244 return [f for f in mctx.subset if r.search(mctx.ctx[f].data())]
245 245
246 _units = dict(k=2**10, K=2**10, kB=2**10, KB=2**10,
247 M=2**20, MB=2**20, G=2**30, GB=2**30,
248 kiB=10**3, MiB=10**6, GiB=10**9)
249
250 def _sizetoint(s):
251 try:
252 s = s.strip()
253 for k, v in _units.items():
254 if s.endswith(k):
255 return int(float(s[:-len(k)]) * v)
256 return int(s)
257 except ValueError:
258 raise
259 raise error.ParseError(_("couldn't parse size"), s)
260
261 def _sizetomax(s):
262 try:
263 s = s.strip()
264 for k, v in _units.items():
265 if s.endswith(k):
266 # max(4k) = 5k - 1, max(4.5k) = 4.6k - 1
267 n = s[:-len(k)]
268 inc = 1.0
269 if "." in n:
270 inc /= 10 ** len(n.split(".")[1])
271 return int((float(n) + inc) * v) - 1
272 # no extension, this is a precise value
273 return int(s)
274 except ValueError:
275 raise
276 raise error.ParseError(_("couldn't parse size"), s)
277
278 def size(mctx, x):
279 """``size(expression)``
280 File size matches the given expression. Examples:
281
282 - 1k (files from 1024 to 2047 bytes)
283 - 1.0kiB (files from 1000 to 1100 bytes)
284 - < 20k (files less than 20480 bytes)
285 - >= .5MiB (files at least 500000 bytes)
286 - 4k - 1MB (files from 4096 bytes to 1048576 bytes)
287 """
288
289 expr = getstring(x, _("grep requires a pattern")).strip()
290 if '-' in expr: # do we have a range?
291 a, b = expr.split('-', 1)
292 a = _sizetoint(a)
293 b = _sizetoint(b)
294 m = lambda x: x >= a and x <= b
295 elif expr.startswith("<="):
296 a = _sizetoint(expr[2:])
297 m = lambda x: x <= a
298 elif expr.startswith("<"):
299 a = _sizetoint(expr[1:])
300 m = lambda x: x < a
301 elif expr.startswith(">="):
302 a = _sizetoint(expr[2:])
303 m = lambda x: x >= a
304 elif expr.startswith(">"):
305 a = _sizetoint(expr[1:])
306 m = lambda x: x > a
307 elif expr[0].isdigit or expr[0] == '.':
308 a = _sizetoint(expr)
309 b = _sizetomax(expr)
310 m = lambda x: x >=a and x <= b
311 else:
312 raise error.ParseError(_("couldn't parse size"), expr)
313
314 return [f for f in mctx.subset if m(mctx.ctx[f].size())]
315
246 symbols = { 316 symbols = {
247 'added': added, 317 'added': added,
248 'binary': binary, 318 'binary': binary,
249 'clean': clean, 319 'clean': clean,
250 'deleted': deleted, 320 'deleted': deleted,
253 'ignored': ignored, 323 'ignored': ignored,
254 'hgignore': hgignore, 324 'hgignore': hgignore,
255 'modified': modified, 325 'modified': modified,
256 'removed': removed, 326 'removed': removed,
257 'resolved': resolved, 327 'resolved': resolved,
328 'size': size,
258 'symlink': symlink, 329 'symlink': symlink,
259 'unknown': unknown, 330 'unknown': unknown,
260 'unresolved': unresolved, 331 'unresolved': unresolved,
261 } 332 }
262 333