fileset: parse argument of size() by predicate function
authorYuya Nishihara <yuya@tcha.org>
Sun, 10 Jun 2018 20:58:10 +0900
changeset 46982 1500cbe22d53ce17093fedaf82a6bcb7a995cc5e
parent 46981 131aae58a3164e6cdd2c7fbf73d3824c2b0d7623
child 46983 2570dca0f21cd58a05ae2d49946a9455696135ca
push id830
push usergszorc@mozilla.com
push dateWed, 18 Jul 2018 00:43:55 +0000
fileset: parse argument of size() by predicate function This change is necessary to pass in a size expression to predicatematcher. See the next patch.
mercurial/fileset.py
mercurial/minifileset.py
--- a/mercurial/fileset.py
+++ b/mercurial/fileset.py
@@ -379,21 +379,19 @@ def _sizetomax(s):
                 if "." in n:
                     inc /= 10 ** len(n.split(".")[1])
                 return int((float(n) + inc) * v) - 1
         # no extension, this is a precise value
         return int(s)
     except ValueError:
         raise error.ParseError(_("couldn't parse size: %s") % s)
 
-def sizematcher(x):
+def sizematcher(expr):
     """Return a function(size) -> bool from the ``size()`` expression"""
-
-    # i18n: "size" is a keyword
-    expr = getstring(x, _("size requires an expression")).strip()
+    expr = expr.strip()
     if '-' in expr: # do we have a range?
         a, b = expr.split('-', 1)
         a = util.sizetoint(a)
         b = util.sizetoint(b)
         return lambda x: x >= a and x <= b
     elif expr.startswith("<="):
         a = util.sizetoint(expr[2:])
         return lambda x: x <= a
@@ -415,17 +413,19 @@ def sizematcher(x):
 def size(mctx, x):
     """File size matches the given expression. Examples:
 
     - size('1k') - files from 1024 to 2047 bytes
     - size('< 20k') - files less than 20480 bytes
     - size('>= .5MB') - files at least 524288 bytes
     - size('4k - 1MB') - files from 4096 bytes to 1048576 bytes
     """
-    m = sizematcher(x)
+    # i18n: "size" is a keyword
+    expr = getstring(x, _("size requires an expression"))
+    m = sizematcher(expr)
     return [f for f in mctx.existing() if m(mctx.ctx[f].size())]
 
 @predicate('encoding(name)', callexisting=True)
 def encoding(mctx, x):
     """File can be successfully decoded with the given character
     encoding. May not be useful for encodings other than ASCII and
     UTF-8.
     """
--- a/mercurial/minifileset.py
+++ b/mercurial/minifileset.py
@@ -9,16 +9,21 @@ from __future__ import absolute_import
 
 from .i18n import _
 from . import (
     error,
     fileset,
     pycompat,
 )
 
+def _sizep(x):
+    # i18n: "size" is a keyword
+    expr = fileset.getstring(x, _("size requires an expression"))
+    return fileset.sizematcher(expr)
+
 def _compile(tree):
     if not tree:
         raise error.ParseError(_("missing argument"))
     op = tree[0]
     if op in {'symbol', 'string', 'kindpat'}:
         name = fileset.getpattern(tree, {'path'}, _('invalid file pattern'))
         if name.startswith('**'): # file extension test, ex. "**.tar.gz"
             ext = name[2:]
@@ -45,17 +50,17 @@ def _compile(tree):
     elif op == 'not':
         return lambda n, s: not _compile(tree[1])(n, s)
     elif op == 'group':
         return _compile(tree[1])
     elif op == 'func':
         symbols = {
             'all': lambda n, s: True,
             'none': lambda n, s: False,
-            'size': lambda n, s: fileset.sizematcher(tree[2])(s),
+            'size': lambda n, s: _sizep(tree[2])(s),
         }
 
         name = fileset.getsymbol(tree[1])
         if name in symbols:
             return symbols[name]
 
         raise error.UnknownIdentifier(name, symbols.keys())
     elif op == 'minus':     # equivalent to 'x and not y'