revset: abuse x:y syntax to specify line range of followlines()
authorYuya Nishihara <yuya@tcha.org>
Mon, 09 Jan 2017 17:58:19 +0900
changeset 30804 4227f80f72b2
parent 30803 d389f19f14aa
child 30805 0ae287eb6a4f
revset: abuse x:y syntax to specify line range of followlines() This slightly complicates the parsing (see the previous patch), but the overall result seems not bad. I keep x:, :y and : for future extension.
mercurial/revset.py
tests/test-annotate.t
--- a/mercurial/revset.py	Mon Jan 09 16:55:56 2017 +0900
+++ b/mercurial/revset.py	Mon Jan 09 17:58:19 2017 +0900
@@ -329,6 +329,20 @@
         return list(x[1:])
     return [x]
 
+def getrange(x, err):
+    if not x:
+        raise error.ParseError(err)
+    op = x[0]
+    if op == 'range':
+        return x[1], x[2]
+    elif op == 'rangepre':
+        return None, x[1]
+    elif op == 'rangepost':
+        return x[1], None
+    elif op == 'rangeall':
+        return None, None
+    raise error.ParseError(err)
+
 def getargs(x, min, max, err):
     l = getlist(x)
     if len(l) < min or (max >= 0 and len(l) > max):
@@ -1083,7 +1097,7 @@
     # of every revisions or files revisions.
     return _follow(repo, subset, x, '_followfirst', followfirst=True)
 
-@predicate('followlines(file, fromline, toline[, startrev=.])', safe=True)
+@predicate('followlines(file, fromline:toline[, startrev=.])', safe=True)
 def followlines(repo, subset, x):
     """Changesets modifying `file` in line range ('fromline', 'toline').
 
@@ -1094,8 +1108,8 @@
     from . import context  # avoid circular import issues
 
     args = getargsdict(x, 'followlines', 'file *lines startrev')
-    if len(args['lines']) != 2:
-        raise error.ParseError(_("followlines takes at least three arguments"))
+    if len(args['lines']) != 1:
+        raise error.ParseError(_("followlines requires a line range"))
 
     rev = '.'
     if 'startrev' in args:
@@ -1115,8 +1129,9 @@
             raise error.ParseError(_("followlines expects exactly one file"))
         fname = files[0]
 
+    lr = getrange(args['lines'][0], _("followlines expects a line range"))
     fromline, toline = [getinteger(a, _("line range bounds must be integers"))
-                        for a in args['lines']]
+                        for a in lr]
     if toline - fromline < 0:
         raise error.ParseError(_("line range must be positive"))
     if fromline < 1:
--- a/tests/test-annotate.t	Mon Jan 09 16:55:56 2017 +0900
+++ b/tests/test-annotate.t	Mon Jan 09 17:58:19 2017 +0900
@@ -486,43 +486,43 @@
 
 Test followlines() revset
 
-  $ hg log -T '{rev}: {desc}\n' -r 'followlines(baz, 3, 5)'
+  $ hg log -T '{rev}: {desc}\n' -r 'followlines(baz, 3:5)'
   16: baz:0
   19: baz:3
   20: baz:4
-  $ hg log -T '{rev}: {desc}\n' -r 'followlines(baz, 3, 5, startrev=20)'
+  $ hg log -T '{rev}: {desc}\n' -r 'followlines(baz, 3:5, startrev=20)'
   16: baz:0
   19: baz:3
   20: baz:4
-  $ hg log -T '{rev}: {desc}\n' -r 'followlines(baz, 3, 5, startrev=.^)'
+  $ hg log -T '{rev}: {desc}\n' -r 'followlines(baz, 3:5, startrev=.^)'
   16: baz:0
   19: baz:3
   $ printf "0\n0\n" | cat - baz > baz1
   $ mv baz1 baz
   $ hg ci -m 'added two lines with 0'
-  $ hg log -T '{rev}: {desc}\n' -r 'followlines(baz, 5, 7)'
+  $ hg log -T '{rev}: {desc}\n' -r 'followlines(baz, 5:7)'
   16: baz:0
   19: baz:3
   20: baz:4
   $ echo 6 >> baz
   $ hg ci -m 'added line 8'
-  $ hg log -T '{rev}: {desc}\n' -r 'followlines(baz, 5, 7)'
+  $ hg log -T '{rev}: {desc}\n' -r 'followlines(baz, 5:7)'
   16: baz:0
   19: baz:3
   20: baz:4
   $ sed 's/3/3+/' baz > baz.new
   $ mv baz.new baz
   $ hg ci -m 'baz:3->3+'
-  $ hg log -T '{rev}: {desc}\n' -r 'followlines(baz, 5, 7)'
+  $ hg log -T '{rev}: {desc}\n' -r 'followlines(baz, 5:7)'
   16: baz:0
   19: baz:3
   20: baz:4
   23: baz:3->3+
-  $ hg log -T '{rev}: {desc}\n' -r 'followlines(baz, 1, 2)'
+  $ hg log -T '{rev}: {desc}\n' -r 'followlines(baz, 1:2)'
   21: added two lines with 0
 
 file patterns are okay
-  $ hg log -T '{rev}: {desc}\n' -r 'followlines("path:baz", 1, 2)'
+  $ hg log -T '{rev}: {desc}\n' -r 'followlines("path:baz", 1:2)'
   21: added two lines with 0
 
 renames are followed
@@ -530,7 +530,7 @@
   $ sed 's/4/4+/' qux > qux.new
   $ mv qux.new qux
   $ hg ci -m 'qux:4->4+'
-  $ hg log -T '{rev}: {desc}\n' -r 'followlines(qux, 5, 7)'
+  $ hg log -T '{rev}: {desc}\n' -r 'followlines(qux, 5:7)'
   16: baz:0
   19: baz:3
   20: baz:4
@@ -545,7 +545,7 @@
   $ sed 's/3+/3-/' baz > baz.new
   $ mv baz.new baz
   $ hg ci -m 'baz:3+->3-'
-  $ hg log -T '{rev}: {desc}\n' -r 'followlines(baz, 5, 7)'
+  $ hg log -T '{rev}: {desc}\n' -r 'followlines(baz, 5:7)'
   16: baz:0
   19: baz:3
   20: baz:4
@@ -556,7 +556,7 @@
   0 files updated, 1 files merged, 0 files removed, 0 files unresolved
   (branch merge, don't forget to commit)
   $ hg ci -m merge
-  $ hg log -T '{rev}: {desc}\n' -r 'followlines(qux, 5, 7)'
+  $ hg log -T '{rev}: {desc}\n' -r 'followlines(qux, 5:7)'
   16: baz:0
   19: baz:3
   20: baz:4
@@ -571,7 +571,7 @@
   (branch merge, don't forget to commit)
   $ hg ci -m 'merge from other side'
   created new head
-  $ hg log -T '{rev}: {desc}\n' -r 'followlines(qux, 5, 7)'
+  $ hg log -T '{rev}: {desc}\n' -r 'followlines(qux, 5:7)'
   16: baz:0
   19: baz:3
   20: baz:4
@@ -586,27 +586,33 @@
   hg: parse error: followlines takes at least 1 positional arguments
   [255]
   $ hg log -r 'followlines(baz)'
-  hg: parse error: followlines takes at least three arguments
+  hg: parse error: followlines requires a line range
   [255]
   $ hg log -r 'followlines(baz, 1)'
-  hg: parse error: followlines takes at least three arguments
+  hg: parse error: followlines expects a line range
   [255]
-  $ hg log -r 'followlines(baz, 1, 2, startrev=desc("b"))'
+  $ hg log -r 'followlines(baz, 1:2, startrev=desc("b"))'
   hg: parse error: followlines expects exactly one revision
   [255]
-  $ hg log -r 'followlines("glob:*", 1, 2)'
+  $ hg log -r 'followlines("glob:*", 1:2)'
   hg: parse error: followlines expects exactly one file
   [255]
-  $ hg log -r 'followlines(baz, x, 4)'
+  $ hg log -r 'followlines(baz, 1:)'
+  hg: parse error: line range bounds must be integers
+  [255]
+  $ hg log -r 'followlines(baz, :1)'
   hg: parse error: line range bounds must be integers
   [255]
-  $ hg log -r 'followlines(baz, 5, 4)'
+  $ hg log -r 'followlines(baz, x:4)'
+  hg: parse error: line range bounds must be integers
+  [255]
+  $ hg log -r 'followlines(baz, 5:4)'
   hg: parse error: line range must be positive
   [255]
-  $ hg log -r 'followlines(baz, 0, 4)'
+  $ hg log -r 'followlines(baz, 0:4)'
   hg: parse error: fromline must be strictly positive
   [255]
-  $ hg log -r 'followlines(baz, 2, 40)'
+  $ hg log -r 'followlines(baz, 2:40)'
   abort: line range exceeds file size
   [255]