D5813: revset: add expect to check the size of a set

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
31 messages Options
12
Reply | Threaded
Open this post in threaded view
|

D5813: revset: add expect to check the size of a set

pulkit (Pulkit Goyal)
navaneeth.suresh created this revision.
Herald added subscribers: mercurial-devel, mjpieters.
Herald added a reviewer: hg-reviewers.

REVISION SUMMARY
  `expect(<set>, <int>)` revset fails if `<set>` is not exactly `<int>` elements.
  `expect(<set>, <min>, <max>)` revset fails if `<set>` is not exactly between
  `<min>` and `<max>` inclusive.
  `one(<set>)` alias for `expect(<set>, 1)`.
 
  This then allows an alias for `hg next` to be `update -r one(children(.))`
  with sane failure behavior, and also makes some other scripting tasks
  a little less difficult.
 
  (Summary from WeShouldDoThat[0])

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D5813

AFFECTED FILES
  mercurial/revset.py
  tests/test-revset.t

CHANGE DETAILS

diff --git a/tests/test-revset.t b/tests/test-revset.t
--- a/tests/test-revset.t
+++ b/tests/test-revset.t
@@ -2950,3 +2950,74 @@
   * set:
   <baseset+ [0]>
   0
+
+abort if the revset doesn't expect given size
+  $ hg log -r 'expect()'
+  hg: parse error: invalid set of arguments
+  [255]
+  $ hg log -r 'expect(0:2, 3)'
+  changeset:   0:2785f51eece5
+  branch:      a
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     0
+  
+  changeset:   1:d75937da8da0
+  branch:      b
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     1
+  
+  changeset:   2:5ed5505e9f1c
+  branch:      a-b-c-
+  user:        Bob
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     2
+  
+  $ hg log -r 'expect(0:1, 1)'
+  abort: revset is not of expected size
+  [255]
+  $ hg log -r 'expect(0:4, -1)'
+  hg: parse error: negative size
+  [255]
+  $ hg log -r 'expect(0:2, min=2, max=4)'
+  changeset:   0:2785f51eece5
+  branch:      a
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     0
+  
+  changeset:   1:d75937da8da0
+  branch:      b
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     1
+  
+  changeset:   2:5ed5505e9f1c
+  branch:      a-b-c-
+  user:        Bob
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     2
+  
+  $ hg log -r 'expect(0:1, min=3, max=5)'
+  abort: revset is not of expected size
+  [255]
+  $ hg log -r 'expect(0:1, min=-1, max=2)'
+  hg: parse error: negative size
+  [255]
+  $ hg log -r 'expect(0:1, min=1, max=-2)'
+  hg: parse error: negative size
+  [255]
+  $ hg log -r 'one()'
+  hg: parse error: invalid set of arguments
+  [255]
+  $ hg log -r 'one(2)'
+  changeset:   2:5ed5505e9f1c
+  branch:      a-b-c-
+  user:        Bob
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     2
+  
+  $ hg log -r 'one(0:2)'
+  abort: revset is not of size 1
+  [255]
diff --git a/mercurial/revset.py b/mercurial/revset.py
--- a/mercurial/revset.py
+++ b/mercurial/revset.py
@@ -815,6 +815,41 @@
     contentdivergent = obsmod.getrevs(repo, 'contentdivergent')
     return subset & contentdivergent
 
+@predicate('expect(set[, size[, min, max]])', safe=True, takeorder=True)
+def expectrevsetsize(repo, subset, x, n=None):
+    """Abort if the revset doesn't expect given size"""
+    args = getargsdict(x, 'expect', 'set size min max')
+    hasset = 'set' in args
+    hassize = 'size' in args
+    hasmin = 'min' in args
+    hasmax = 'max' in args
+
+    if (not (hasset and hassize) and not n or
+        (not (hasset and hasmax and hasmin) and not n) or
+        (not hasset and n)):
+        raise error.ParseError(_('invalid set of arguments'))
+    rev = getset(repo, fullreposet(repo), args['set'])
+    if hassize:
+        n = getinteger(args['size'],
+                       'expect requires an integer size')
+        if n < 0:
+            raise error.ParseError(_('negative size'))
+        if len(rev) != n:
+            raise error.Abort(_('revset is not of expected size'))
+    if n==1:
+        if len(rev) != n:
+            raise error.Abort(_('revset is not of size 1'))
+    if hasmin and hasmax:
+        i = getinteger(args['min'],
+                       'expect requires an integer min size')
+        j = getinteger(args['max'],
+                       'expect requires an integer max size')
+        if i < 0 or j < 0:
+            raise error.ParseError(_('negative size'))
+        if not (len(rev) >= i and len(rev) <= j):
+            raise error.Abort(_('revset is not of expected size'))
+    return rev
+
 @predicate('extdata(source)', safe=False, weight=100)
 def extdata(repo, subset, x):
     """Changesets in the specified extdata source. (EXPERIMENTAL)"""
@@ -1404,6 +1439,11 @@
     obsoletes = obsmod.getrevs(repo, 'obsolete')
     return subset & obsoletes
 
+@predicate('one(set)', safe=True)
+def one(repo, subset, x):
+    """An alias for expect(<set>, 1)"""
+    return expectrevsetsize(repo, subset, x, n=1)
+
 @predicate('only(set, [set])', safe=True)
 def only(repo, subset, x):
     """Changesets that are ancestors of the first set that are not ancestors



To: navaneeth.suresh, #hg-reviewers
Cc: mjpieters, mercurial-devel
_______________________________________________
Mercurial-devel mailing list
[hidden email]
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Reply | Threaded
Open this post in threaded view
|

D5813: revset: add expect to check the size of a set

pulkit (Pulkit Goyal)
pulkit added subscribers: durin42, pulkit.
pulkit added a comment.


  > This then allows an alias for hg next to be update -r one(children(.))
  >  with sane failure behavior, and also makes some other scripting tasks
  >  a little less difficult.
 
  Just for record, `hg next` has a nice prompt if there are multiple childrens. So the `expect` or `one` revset might not be very useful there.

INLINE COMMENTS

> revset.py:838
> +        if len(rev) != n:
> +            raise error.Abort(_('revset is not of expected size'))
> +    if n==1:

it will be good if we add the length of revset in the error message here.

> revset.py:839
> +            raise error.Abort(_('revset is not of expected size'))
> +    if n==1:
> +        if len(rev) != n:

why are we special casing 1 here?

> revset.py:1442
>  
> +@predicate('one(set)', safe=True)
> +def one(repo, subset, x):

I am not sure why we need this. @durin42 might have thoughts on this.

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D5813

To: navaneeth.suresh, #hg-reviewers
Cc: pulkit, durin42, mjpieters, mercurial-devel
_______________________________________________
Mercurial-devel mailing list
[hidden email]
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Reply | Threaded
Open this post in threaded view
|

D5813: revset: add expect to check the size of a set

pulkit (Pulkit Goyal)
In reply to this post by pulkit (Pulkit Goyal)
navaneeth.suresh updated this revision to Diff 13735.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D5813?vs=13731&id=13735

REVISION DETAIL
  https://phab.mercurial-scm.org/D5813

AFFECTED FILES
  mercurial/revset.py
  tests/test-revset.t

CHANGE DETAILS

diff --git a/tests/test-revset.t b/tests/test-revset.t
--- a/tests/test-revset.t
+++ b/tests/test-revset.t
@@ -2950,3 +2950,83 @@
   * set:
   <baseset+ [0]>
   0
+
+abort if the revset doesn't expect given size
+  $ hg log -r 'expect()'
+  hg: parse error: invalid set of arguments
+  [255]
+  $ hg log -r 'expect(0:2, a)'
+  hg: parse error: expect requires an integer size
+  [255]
+  $ hg log -r 'expect(0:2, 3)'
+  changeset:   0:2785f51eece5
+  branch:      a
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     0
+  
+  changeset:   1:d75937da8da0
+  branch:      b
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     1
+  
+  changeset:   2:5ed5505e9f1c
+  branch:      a-b-c-
+  user:        Bob
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     2
+  
+  $ hg log -r 'expect(0:1, 1)'
+  abort: revset size mismatch. expected 1, got 2
+  [255]
+  $ hg log -r 'expect(0:4, -1)'
+  hg: parse error: negative size
+  [255]
+  $ hg log -r 'expect(0:2, min=2, max=4)'
+  changeset:   0:2785f51eece5
+  branch:      a
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     0
+  
+  changeset:   1:d75937da8da0
+  branch:      b
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     1
+  
+  changeset:   2:5ed5505e9f1c
+  branch:      a-b-c-
+  user:        Bob
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     2
+  
+  $ hg log -r 'expect(0:1, min=3, max=5)'
+  abort: revset size mismatch. expected between 3 and 5, got 2
+  [255]
+  $ hg log -r 'expect(0:1, min=-1, max=2)'
+  hg: parse error: negative size
+  [255]
+  $ hg log -r 'expect(0:1, min=1, max=-2)'
+  hg: parse error: negative size
+  [255]
+  $ hg log -r 'expect(0:2, min=a, max=4)'
+  hg: parse error: expect requires an integer min size
+  [255]
+  $ hg log -r 'expect(0:2, min=2, max=b)'
+  hg: parse error: expect requires an integer max size
+  [255]
+  $ hg log -r 'one()'
+  hg: parse error: invalid set of arguments
+  [255]
+  $ hg log -r 'one(2)'
+  changeset:   2:5ed5505e9f1c
+  branch:      a-b-c-
+  user:        Bob
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     2
+  
+  $ hg log -r 'one(0:2)'
+  abort: revset size mismatch. expected 1, got 3
+  [255]
diff --git a/mercurial/revset.py b/mercurial/revset.py
--- a/mercurial/revset.py
+++ b/mercurial/revset.py
@@ -815,6 +815,42 @@
     contentdivergent = obsmod.getrevs(repo, 'contentdivergent')
     return subset & contentdivergent
 
+@predicate('expect(set[, size[, min, max]])', safe=True, takeorder=True)
+def expectrevsetsize(repo, subset, x, n=None):
+    """Abort if the revset doesn't expect given size"""
+    args = getargsdict(x, 'expect', 'set size min max')
+    hasset = 'set' in args
+    hassize = 'size' in args
+    hasmin = 'min' in args
+    hasmax = 'max' in args
+
+    if (not (hasset and hassize) and not n or
+        (not (hasset and hasmax and hasmin) and not n) or
+        (not hasset and n)):
+        raise error.ParseError(_('invalid set of arguments'))
+    rev = getset(repo, fullreposet(repo), args['set'])
+    if hassize or isinstance(n, int):
+        n = getinteger(args.get('size', ('string', str(n))),
+                       'expect requires an integer size')
+        if n < 0:
+            raise error.ParseError(_('negative size'))
+        if len(rev) != n:
+            raise error.Abort(
+                _('revset size mismatch.'
+                ' expected %d, got %d') % (n, len(rev)))
+    if hasmin and hasmax:
+        i = getinteger(args['min'],
+                       'expect requires an integer min size')
+        j = getinteger(args['max'],
+                       'expect requires an integer max size')
+        if i < 0 or j < 0:
+            raise error.ParseError(_('negative size'))
+        if not (len(rev) >= i and len(rev) <= j):
+            raise error.Abort(
+                _('revset size mismatch.'
+                ' expected between %d and %d, got %d') % (i, j, len(rev)))
+    return rev
+
 @predicate('extdata(source)', safe=False, weight=100)
 def extdata(repo, subset, x):
     """Changesets in the specified extdata source. (EXPERIMENTAL)"""
@@ -1404,6 +1440,11 @@
     obsoletes = obsmod.getrevs(repo, 'obsolete')
     return subset & obsoletes
 
+@predicate('one(set)', safe=True)
+def one(repo, subset, x):
+    """An alias for expect(<set>, 1)"""
+    return expectrevsetsize(repo, subset, x, n=1)
+
 @predicate('only(set, [set])', safe=True)
 def only(repo, subset, x):
     """Changesets that are ancestors of the first set that are not ancestors



To: navaneeth.suresh, #hg-reviewers
Cc: pulkit, durin42, mjpieters, mercurial-devel
_______________________________________________
Mercurial-devel mailing list
[hidden email]
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Reply | Threaded
Open this post in threaded view
|

D5813: revset: add expect to check the size of a set

pulkit (Pulkit Goyal)
In reply to this post by pulkit (Pulkit Goyal)
navaneeth.suresh marked 2 inline comments as done.
navaneeth.suresh added a comment.


  @pulkit Thanks for the quick review! I've updated the revision with the suggested changes. @durin42 It would be great if you let us know your opinion on `one(<set>)` as an alias for `expect(<set>, 1)`. I did it as it was present in WeShouldDoThat page.

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D5813

To: navaneeth.suresh, #hg-reviewers
Cc: pulkit, durin42, mjpieters, mercurial-devel
_______________________________________________
Mercurial-devel mailing list
[hidden email]
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Reply | Threaded
Open this post in threaded view
|

D5813: revset: add expect to check the size of a set

pulkit (Pulkit Goyal)
In reply to this post by pulkit (Pulkit Goyal)
navaneeth.suresh updated this revision to Diff 13736.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D5813?vs=13735&id=13736

REVISION DETAIL
  https://phab.mercurial-scm.org/D5813

AFFECTED FILES
  mercurial/revset.py
  tests/test-revset.t

CHANGE DETAILS

diff --git a/tests/test-revset.t b/tests/test-revset.t
--- a/tests/test-revset.t
+++ b/tests/test-revset.t
@@ -2950,3 +2950,83 @@
   * set:
   <baseset+ [0]>
   0
+
+abort if the revset doesn't expect given size
+  $ hg log -r 'expect()'
+  hg: parse error: invalid set of arguments
+  [255]
+  $ hg log -r 'expect(0:2, a)'
+  hg: parse error: expect requires an integer size
+  [255]
+  $ hg log -r 'expect(0:2, 3)'
+  changeset:   0:2785f51eece5
+  branch:      a
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     0
+  
+  changeset:   1:d75937da8da0
+  branch:      b
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     1
+  
+  changeset:   2:5ed5505e9f1c
+  branch:      a-b-c-
+  user:        Bob
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     2
+  
+  $ hg log -r 'expect(0:1, 1)'
+  abort: revset size mismatch. expected 1, got 2
+  [255]
+  $ hg log -r 'expect(0:4, -1)'
+  hg: parse error: negative size
+  [255]
+  $ hg log -r 'expect(0:2, min=2, max=4)'
+  changeset:   0:2785f51eece5
+  branch:      a
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     0
+  
+  changeset:   1:d75937da8da0
+  branch:      b
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     1
+  
+  changeset:   2:5ed5505e9f1c
+  branch:      a-b-c-
+  user:        Bob
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     2
+  
+  $ hg log -r 'expect(0:1, min=3, max=5)'
+  abort: revset size mismatch. expected between 3 and 5, got 2
+  [255]
+  $ hg log -r 'expect(0:1, min=-1, max=2)'
+  hg: parse error: negative size
+  [255]
+  $ hg log -r 'expect(0:1, min=1, max=-2)'
+  hg: parse error: negative size
+  [255]
+  $ hg log -r 'expect(0:2, min=a, max=4)'
+  hg: parse error: expect requires an integer min size
+  [255]
+  $ hg log -r 'expect(0:2, min=2, max=b)'
+  hg: parse error: expect requires an integer max size
+  [255]
+  $ hg log -r 'one()'
+  hg: parse error: invalid set of arguments
+  [255]
+  $ hg log -r 'one(2)'
+  changeset:   2:5ed5505e9f1c
+  branch:      a-b-c-
+  user:        Bob
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     2
+  
+  $ hg log -r 'one(0:2)'
+  abort: revset size mismatch. expected 1, got 3
+  [255]
diff --git a/mercurial/revset.py b/mercurial/revset.py
--- a/mercurial/revset.py
+++ b/mercurial/revset.py
@@ -815,6 +815,43 @@
     contentdivergent = obsmod.getrevs(repo, 'contentdivergent')
     return subset & contentdivergent
 
+@predicate('expect(set[, size[, min, max]])', safe=True, takeorder=True)
+def expectrevsetsize(repo, subset, x, n=None):
+    """Abort if the revset doesn't expect given size"""
+    args = getargsdict(x, 'expect', 'set size min max')
+    hasset = 'set' in args
+    hassize = 'size' in args
+    hasmin = 'min' in args
+    hasmax = 'max' in args
+
+    if (not (hasset and hassize) and not n or
+        (not (hasset and hasmax and hasmin) and not n) or
+        (not hasset and n)):
+        raise error.ParseError(_('invalid set of arguments'))
+    rev = getset(repo, fullreposet(repo), args['set'])
+    if hassize or isinstance(n, int):
+        if hassize:
+            n = getinteger(args['size'],
+                           'expect requires an integer size')
+        if n < 0:
+            raise error.ParseError(_('negative size'))
+        if len(rev) != n:
+            raise error.Abort(
+                _('revset size mismatch.'
+                ' expected %d, got %d') % (n, len(rev)))
+    elif hasmin and hasmax:
+        i = getinteger(args['min'],
+                       'expect requires an integer min size')
+        j = getinteger(args['max'],
+                       'expect requires an integer max size')
+        if i < 0 or j < 0:
+            raise error.ParseError(_('negative size'))
+        if not (len(rev) >= i and len(rev) <= j):
+            raise error.Abort(
+                _('revset size mismatch.'
+                ' expected between %d and %d, got %d') % (i, j, len(rev)))
+    return rev
+
 @predicate('extdata(source)', safe=False, weight=100)
 def extdata(repo, subset, x):
     """Changesets in the specified extdata source. (EXPERIMENTAL)"""
@@ -1404,6 +1441,11 @@
     obsoletes = obsmod.getrevs(repo, 'obsolete')
     return subset & obsoletes
 
+@predicate('one(set)', safe=True)
+def one(repo, subset, x):
+    """An alias for expect(<set>, 1)"""
+    return expectrevsetsize(repo, subset, x, n=1)
+
 @predicate('only(set, [set])', safe=True)
 def only(repo, subset, x):
     """Changesets that are ancestors of the first set that are not ancestors



To: navaneeth.suresh, #hg-reviewers
Cc: pulkit, durin42, mjpieters, mercurial-devel
_______________________________________________
Mercurial-devel mailing list
[hidden email]
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Reply | Threaded
Open this post in threaded view
|

Re: D5813: revset: add expect to check the size of a set

Yuya Nishihara
In reply to this post by pulkit (Pulkit Goyal)
> +@predicate('expect(set[, size[, min, max]])', safe=True, takeorder=True)

First, I think the word `expect` is too general. Perhaps, this should be called
`expectsize()` or `expectlen()`.

It's also unclear what's the difference between `size` and `min`/`max`.
Instead of these parameters, maybe we can add a `size` parameter that takes
a number or a range `min:max`. See also the following patch.

https://www.mercurial-scm.org/pipermail/mercurial-devel/2019-February/127916.html

> +        if len(rev) != n:
> +            raise error.Abort(_('revset is not of expected size'))

Better to raise RepoLookupError so the error can be caught by `present(...)`.

> +    return rev

You need to filter rev by subset. Since we'll probably want to get an ordered
result from `expect(set)`, we'll have to conditionalize the filtering direction:

```
if order == followorder:
    return subset & rev
else:
    return rev & subset
```

You can try out some combinations of `expect(5:0) & 1:10` and
`10:1 & expect(0:5)`.
_______________________________________________
Mercurial-devel mailing list
[hidden email]
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Reply | Threaded
Open this post in threaded view
|

D5813: revset: add expect to check the size of a set

pulkit (Pulkit Goyal)
yuja added a comment.


  > +@predicate('expect(set[, size[, min, max]])', safe=True, takeorder=True)
 
  First, I think the word `expect` is too general. Perhaps, this should be called
  `expectsize()` or `expectlen()`.
 
  It's also unclear what's the difference between `size` and `min`/`max`.
  Instead of these parameters, maybe we can add a `size` parameter that takes
  a number or a range `min:max`. See also the following patch.
 
  https://www.mercurial-scm.org/pipermail/mercurial-devel/2019-February/127916.html
 
  > +        if len(rev) != n:
  >  +            raise error.Abort(_('revset is not of expected size'))
 
  Better to raise RepoLookupError so the error can be caught by `present(...)`.
 
  > +    return rev
 
  You need to filter rev by subset. Since we'll probably want to get an ordered
  result from `expect(set)`, we'll have to conditionalize the filtering direction:
 
    if order == followorder:
        return subset & rev
    else:
        return rev & subset
 
  You can try out some combinations of `expect(5:0) & 1:10` and
  `10:1 & expect(0:5)`.

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D5813

To: navaneeth.suresh, #hg-reviewers
Cc: yuja, pulkit, durin42, mjpieters, mercurial-devel
_______________________________________________
Mercurial-devel mailing list
[hidden email]
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Reply | Threaded
Open this post in threaded view
|

D5813: revset: add expect to check the size of a set

pulkit (Pulkit Goyal)
In reply to this post by pulkit (Pulkit Goyal)
navaneeth.suresh added a comment.


  > First, I think the word `expect` is too general. Perhaps, this should be called
  >  `expectsize()` or `expectlen()`.
 
  I can make it `expectsize()`.
 
  > It's also unclear what's the difference between `size` and `min`/`max`.
  >  Instead of these parameters, maybe we can add a `size` parameter that takes
  >  a number or a range `min:max`. See also the following patch.
  >
  > https://www.mercurial-scm.org/pipermail/mercurial-devel/2019-February/127916.html
 
  Unfortunately, I can't see this in `hg-stable` which I was working.
 
  >> +        if len(rev) != n:
  >>  +            raise error.Abort(_('revset is not of expected size'))
  >
  > Better to raise RepoLookupError so the error can be caught by `present(...)`.
 
  For sure. I could do that.
 
  >> +    return rev
  >
  > You need to filter rev by subset. Since we'll probably want to get an ordered
  >  result from `expect(set)`, we'll have to conditionalize the filtering direction:
  >
  >   if order == followorder:
  >       return subset & rev
  >   else:
  >       return rev & subset
  >
  >
  > You can try out some combinations of `expect(5:0) & 1:10` and
  >  `10:1 & expect(0:5)`.
 
  I got into many errors while using this. I might be not understanding this correctly. Could you please elaborate?

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D5813

To: navaneeth.suresh, #hg-reviewers
Cc: yuja, pulkit, durin42, mjpieters, mercurial-devel
_______________________________________________
Mercurial-devel mailing list
[hidden email]
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Reply | Threaded
Open this post in threaded view
|

Re: D5813: revset: add expect to check the size of a set

Yuya Nishihara
>   > You can try out some combinations of `expect(5:0) & 1:10` and
>   >  `10:1 & expect(0:5)`.
>  
>   I got into many errors while using this. I might be not understanding this correctly. Could you please elaborate?

Can you share your failed attempt?

Maybe you can get how revset works by testing expression with
`hg debugrevspec -v`.
_______________________________________________
Mercurial-devel mailing list
[hidden email]
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Reply | Threaded
Open this post in threaded view
|

D5813: revset: add expect to check the size of a set

pulkit (Pulkit Goyal)
yuja added a comment.


  >   > You can try out some combinations of `expect(5:0) & 1:10` and
  >   >  `10:1 & expect(0:5)`.
  >  
  >   I got into many errors while using this. I might be not understanding this correctly. Could you please elaborate?
 
  Can you share your failed attempt?
 
  Maybe you can get how revset works by testing expression with
  `hg debugrevspec -v`.

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D5813

To: navaneeth.suresh, #hg-reviewers
Cc: yuja, pulkit, durin42, mjpieters, mercurial-devel
_______________________________________________
Mercurial-devel mailing list
[hidden email]
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Reply | Threaded
Open this post in threaded view
|

D5813: revset: add expect to check the size of a set

pulkit (Pulkit Goyal)
In reply to this post by pulkit (Pulkit Goyal)
navaneeth.suresh updated this revision to Diff 13851.
navaneeth.suresh edited the summary of this revision.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D5813?vs=13736&id=13851

REVISION DETAIL
  https://phab.mercurial-scm.org/D5813

AFFECTED FILES
  mercurial/revset.py
  tests/test-revset.t

CHANGE DETAILS

diff --git a/tests/test-revset.t b/tests/test-revset.t
--- a/tests/test-revset.t
+++ b/tests/test-revset.t
@@ -2950,3 +2950,103 @@
   * set:
   <baseset+ [0]>
   0
+
+abort if the revset doesn't expect given size
+  $ hg log -r 'expectsize()'
+  hg: parse error: invalid set of arguments
+  [255]
+  $ hg log -r 'expectsize(0:2, a)'
+  hg: parse error: expectsize requires a size range or a positive integer
+  [255]
+  $ hg log -r 'expectsize(0:2, 3)'
+  changeset:   0:2785f51eece5
+  branch:      a
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     0
+  
+  changeset:   1:d75937da8da0
+  branch:      b
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     1
+  
+  changeset:   2:5ed5505e9f1c
+  branch:      a-b-c-
+  user:        Bob
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     2
+  
+
+  $ hg log -r 'expectsize(2:0, 3)'
+  changeset:   2:5ed5505e9f1c
+  branch:      a-b-c-
+  user:        Bob
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     2
+  
+  changeset:   1:d75937da8da0
+  branch:      b
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     1
+  
+  changeset:   0:2785f51eece5
+  branch:      a
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     0
+  
+  $ hg log -r 'expectsize(0:1, 1)'
+  abort: revset size mismatch. expected 1, got 2!
+  [255]
+  $ hg log -r 'expectsize(0:4, -1)'
+  hg: parse error: negative size
+  [255]
+  $ hg log -r 'expectsize(0:2, 2:4)'
+  changeset:   0:2785f51eece5
+  branch:      a
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     0
+  
+  changeset:   1:d75937da8da0
+  branch:      b
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     1
+  
+  changeset:   2:5ed5505e9f1c
+  branch:      a-b-c-
+  user:        Bob
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     2
+  
+  $ hg log -r 'expectsize(0:1, 3:5)'
+  abort: revset size mismatch. expected between 3 and 5, got 2!
+  [255]
+  $ hg log -r 'expectsize(0:1, -1:2)'
+  hg: parse error: negative size
+  [255]
+  $ hg log -r 'expectsize(0:1, 1:-2)'
+  hg: parse error: negative size
+  [255]
+  $ hg log -r 'expectsize(0:2, a:4)'
+  hg: parse error: expectsize requires a size range or a positive integer
+  [255]
+  $ hg log -r 'expectsize(0:2, 2:b)'
+  hg: parse error: expectsize requires a size range or a positive integer
+  [255]
+  $ hg log -r 'one()'
+  hg: parse error: invalid set of arguments
+  [255]
+  $ hg log -r 'one(2)'
+  changeset:   2:5ed5505e9f1c
+  branch:      a-b-c-
+  user:        Bob
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     2
+  
+  $ hg log -r 'one(0:2)'
+  abort: revset size mismatch. expected 1, got 3!
+  [255]
diff --git a/mercurial/revset.py b/mercurial/revset.py
--- a/mercurial/revset.py
+++ b/mercurial/revset.py
@@ -815,6 +815,55 @@
     contentdivergent = obsmod.getrevs(repo, 'contentdivergent')
     return subset & contentdivergent
 
+@predicate('expectsize(set[, size])', safe=True, takeorder=True)
+def expectrevsetsize(repo, subset, x, order, n=None):
+    """Abort if the revset doesn't expect given size"""
+    args = getargsdict(x, 'expect', 'set size')
+    size = args.get('size', n)
+    if size is not None:
+        try:
+            # size is given as integer range on expectsize(<set>, <intrange>)
+            lr = getrange(size, _('expectsize requires a size range '
+                                  'or a positive integer'))
+            minsize, maxsize = [getinteger(a,
+                                _('size range bounds must be integers'))
+                                for a in lr]
+            size = (minsize, maxsize)
+        except error.ParseError:
+            # size is given as integer on expectsize(<set>, <int>)
+            size = getinteger(size,
+                              _('expectsize requires a size range '
+                                'or a positive integer'))
+        except TypeError:
+            # size is 1 on one(<set>)
+            pass
+    if size is None or 'set' not in args:
+        raise error.ParseError(_('invalid set of arguments'))
+    rev = getset(repo, fullreposet(repo), args['set'], order=order)
+    if isinstance(size, tuple):
+        if minsize < 0 or maxsize < 0:
+            raise error.ParseError(_('negative size'))
+        if len(rev) not in range(size[0], size[1]+1):
+            raise error.RepoLookupError(
+                _('revset size mismatch.'
+                ' expected between %d and %d, got %d') % (size[0],
+                                                          size[1],
+                                                          len(rev)))
+    if isinstance(size, int):
+        if size < 0:
+            raise error.ParseError(_('negative size'))
+        if len(rev) != size:
+            raise error.RepoLookupError(
+                _('revset size mismatch.'
+                ' expected %d, got %d') % (size, len(rev)))
+    # filter rev by subset. since we'll probably want to get an ordered
+    # result from expectsize(<set>), we'll have to conditionalize the
+    # filtering direction
+    if order == followorder:
+        return subset & rev
+    else:
+        return rev & subset
+
 @predicate('extdata(source)', safe=False, weight=100)
 def extdata(repo, subset, x):
     """Changesets in the specified extdata source. (EXPERIMENTAL)"""
@@ -1404,6 +1453,11 @@
     obsoletes = obsmod.getrevs(repo, 'obsolete')
     return subset & obsoletes
 
+@predicate('one(set)', safe=True, takeorder=True)
+def one(repo, subset, x, order):
+    """An alias for expect(<set>, 1)"""
+    return expectrevsetsize(repo, subset, x, order, n=1)
+
 @predicate('only(set, [set])', safe=True)
 def only(repo, subset, x):
     """Changesets that are ancestors of the first set that are not ancestors



To: navaneeth.suresh, #hg-reviewers
Cc: yuja, pulkit, durin42, mjpieters, mercurial-devel
_______________________________________________
Mercurial-devel mailing list
[hidden email]
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Reply | Threaded
Open this post in threaded view
|

D5813: revset: add expect to check the size of a set

pulkit (Pulkit Goyal)
In reply to this post by pulkit (Pulkit Goyal)
navaneeth.suresh added a comment.


  > Can you share your failed attempt?
  >
  > Maybe you can get how revset works by testing expression with
  >  `hg debugrevspec -v`.
 
  I somehow managed to meet your requirements in the current revision @yuja. Please let me know if I missed out something there.

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D5813

To: navaneeth.suresh, #hg-reviewers
Cc: yuja, pulkit, durin42, mjpieters, mercurial-devel
_______________________________________________
Mercurial-devel mailing list
[hidden email]
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Reply | Threaded
Open this post in threaded view
|

Re: D5813: revset: add expect to check the size of a set

Yuya Nishihara
In reply to this post by pulkit (Pulkit Goyal)
> +  $ hg log -r 'expectsize(0:2, 3)'
> +  changeset:   0:2785f51eece5
> +  branch:      a
> +  user:        test
> +  date:        Thu Jan 01 00:00:00 1970 +0000
> +  summary:     0

Nit: the test outputs look unnecessarily verbose. Use `log` (not `hg log`)
instead.

> +@predicate('expectsize(set[, size])', safe=True, takeorder=True)
> +def expectrevsetsize(repo, subset, x, order, n=None):
> +    """Abort if the revset doesn't expect given size"""
> +    args = getargsdict(x, 'expect', 'set size')
> +    size = args.get('size', n)
> +    if size is not None:
> +        try:
> +            # size is given as integer range on expectsize(<set>, <intrange>)

The helper function has been queued. Can you rewrite this to use the
getintrange helper?

> +        if len(rev) not in range(size[0], size[1]+1):

`range()` builds a list of integers on Python 2, which isn't what we want.
Python does support `not (x <= y <= z)` syntax, so you can just compare
integer bounds.

> +@predicate('one(set)', safe=True, takeorder=True)
> +def one(repo, subset, x, order):
> +    """An alias for expect(<set>, 1)"""
> +    return expectrevsetsize(repo, subset, x, order, n=1)

Can you remove `one()` from this patch?

I don't follow the original proposal, but I guess `one()` would be meant to
a user-defined alias (i.e. `revsetalias.one(x) = expectsize(x, 1)`).
_______________________________________________
Mercurial-devel mailing list
[hidden email]
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Reply | Threaded
Open this post in threaded view
|

D5813: revset: add expect to check the size of a set

pulkit (Pulkit Goyal)
yuja added a comment.


  > +  $ hg log -r 'expectsize(0:2, 3)'
  >  +  changeset:   0:2785f51eece5
  >  +  branch:      a
  >  +  user:        test
  >  +  date:        Thu Jan 01 00:00:00 1970 +0000
  >  +  summary:     0
 
  Nit: the test outputs look unnecessarily verbose. Use `log` (not `hg log`)
  instead.
 
  > +@predicate('expectsize(set[, size])', safe=True, takeorder=True)
  >  +def expectrevsetsize(repo, subset, x, order, n=None):
  >  +    """Abort if the revset doesn't expect given size"""
  >  +    args = getargsdict(x, 'expect', 'set size')
  >  +    size = args.get('size', n)
  >  +    if size is not None:
  >  +        try:
  >  +            # size is given as integer range on expectsize(<set>, <intrange>)
 
  The helper function has been queued. Can you rewrite this to use the
  getintrange helper?
 
  > +        if len(rev) not in range(size[0], size[1]+1):
 
  `range()` builds a list of integers on Python 2, which isn't what we want.
  Python does support `not (x <= y <= z)` syntax, so you can just compare
  integer bounds.
 
  > +@predicate('one(set)', safe=True, takeorder=True)
  >  +def one(repo, subset, x, order):
  >  +    """An alias for expect(<set>, 1)"""
  >  +    return expectrevsetsize(repo, subset, x, order, n=1)
 
  Can you remove `one()` from this patch?
 
  I don't follow the original proposal, but I guess `one()` would be meant to
  a user-defined alias (i.e. `revsetalias.one(x) = expectsize(x, 1)`).

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D5813

To: navaneeth.suresh, #hg-reviewers
Cc: yuja, pulkit, durin42, mjpieters, mercurial-devel
_______________________________________________
Mercurial-devel mailing list
[hidden email]
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Reply | Threaded
Open this post in threaded view
|

D5813: revset: add expect to check the size of a set

pulkit (Pulkit Goyal)
In reply to this post by pulkit (Pulkit Goyal)
navaneeth.suresh updated this revision to Diff 13899.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D5813?vs=13851&id=13899

REVISION DETAIL
  https://phab.mercurial-scm.org/D5813

AFFECTED FILES
  mercurial/revset.py
  tests/test-revset.t

CHANGE DETAILS

diff --git a/tests/test-revset.t b/tests/test-revset.t
--- a/tests/test-revset.t
+++ b/tests/test-revset.t
@@ -2950,3 +2950,45 @@
   * set:
   <baseset+ [0]>
   0
+
+abort if the revset doesn't expect given size
+  $ log 'expectsize()'
+  hg: parse error: invalid set of arguments
+  [255]
+  $ log 'expectsize(0:2, a)'
+  hg: parse error: expectsize requires a size range or a positive integer
+  [255]
+  $ log 'expectsize(0:2, 3)'
+  0
+  1
+  2
+
+  $ log 'expectsize(2:0, 3)'
+  2
+  1
+  0
+  $ log 'expectsize(0:1, 1)'
+  abort: revset size mismatch. expected 1, got 2!
+  [255]
+  $ log 'expectsize(0:4, -1)'
+  hg: parse error: negative size
+  [255]
+  $ log 'expectsize(0:2, 2:4)'
+  0
+  1
+  2
+  $ log 'expectsize(0:1, 3:5)'
+  abort: revset size mismatch. expected between 3 and 5, got 2!
+  [255]
+  $ log 'expectsize(0:1, -1:2)'
+  hg: parse error: negative size
+  [255]
+  $ log 'expectsize(0:1, 1:-2)'
+  hg: parse error: negative size
+  [255]
+  $ log 'expectsize(0:2, a:4)'
+  hg: parse error: size range bounds must be integers
+  [255]
+  $ log 'expectsize(0:2, 2:b)'
+  hg: parse error: size range bounds must be integers
+  [255]
diff --git a/mercurial/revset.py b/mercurial/revset.py
--- a/mercurial/revset.py
+++ b/mercurial/revset.py
@@ -815,6 +815,45 @@
     contentdivergent = obsmod.getrevs(repo, 'contentdivergent')
     return subset & contentdivergent
 
+@predicate('expectsize(set[, size])', safe=True, takeorder=True)
+def expectrevsetsize(repo, subset, x, order):
+    """Abort if the revset doesn't expect given size"""
+    args = getargsdict(x, 'expect', 'set size')
+    size = args.get('size')
+    if size is not None:
+        minsize, maxsize = getintrange(size,
+                                       _('expectsize requires a size range'
+                                       ' or a positive integer'),
+                                       _('size range bounds must be integers'))
+        if minsize < 0 or maxsize < 0:
+            raise error.ParseError(_('negative size'))
+        if minsize != maxsize:
+            size = (minsize, maxsize)
+        else:
+            size = minsize
+    if size is None or 'set' not in args:
+        raise error.ParseError(_('invalid set of arguments'))
+    rev = getset(repo, fullreposet(repo), args['set'], order=order)
+    if isinstance(size, tuple):
+        if len(rev) < minsize or len(rev) > maxsize:
+            raise error.RepoLookupError(
+                _('revset size mismatch.'
+                ' expected between %d and %d, got %d') % (minsize,
+                                                          maxsize,
+                                                          len(rev)))
+    if isinstance(size, int):
+        if len(rev) != size:
+            raise error.RepoLookupError(
+                _('revset size mismatch.'
+                ' expected %d, got %d') % (size, len(rev)))
+    # filter rev by subset. since we'll probably want to get an ordered
+    # result from expectsize(<set>), we'll have to conditionalize the
+    # filtering direction
+    if order == followorder:
+        return subset & rev
+    else:
+        return rev & subset
+
 @predicate('extdata(source)', safe=False, weight=100)
 def extdata(repo, subset, x):
     """Changesets in the specified extdata source. (EXPERIMENTAL)"""



To: navaneeth.suresh, #hg-reviewers
Cc: yuja, pulkit, durin42, mjpieters, mercurial-devel
_______________________________________________
Mercurial-devel mailing list
[hidden email]
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Reply | Threaded
Open this post in threaded view
|

D5813: revset: add expect to check the size of a set

pulkit (Pulkit Goyal)
In reply to this post by pulkit (Pulkit Goyal)
navaneeth.suresh added a comment.


  @yuja I've updated the revision with the suggested changes.

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D5813

To: navaneeth.suresh, #hg-reviewers
Cc: yuja, pulkit, durin42, mjpieters, mercurial-devel
_______________________________________________
Mercurial-devel mailing list
[hidden email]
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Reply | Threaded
Open this post in threaded view
|

Re: D5813: revset: add expect to check the size of a set

Yuya Nishihara
In reply to this post by pulkit (Pulkit Goyal)
> +@predicate('expectsize(set[, size])', safe=True, takeorder=True)
> +def expectrevsetsize(repo, subset, x, order):
> +    """Abort if the revset doesn't expect given size"""
> +    args = getargsdict(x, 'expect', 'set size')
> +    size = args.get('size')
> +    if size is not None:
> +        minsize, maxsize = getintrange(size,
> +                                       _('expectsize requires a size range'
> +                                       ' or a positive integer'),
> +                                       _('size range bounds must be integers'))

Maybe needs to specify the default min/max values to e.g. possible min/max
values or `None`.

> +        if minsize != maxsize:
> +            size = (minsize, maxsize)
> +        else:
> +            size = minsize
> +    if size is None or 'set' not in args:
> +        raise error.ParseError(_('invalid set of arguments'))
> +    rev = getset(repo, fullreposet(repo), args['set'], order=order)
> +    if isinstance(size, tuple):
> +        if len(rev) < minsize or len(rev) > maxsize:
> +            raise error.RepoLookupError(
> +                _('revset size mismatch.'
> +                ' expected between %d and %d, got %d') % (minsize,
> +                                                          maxsize,
> +                                                          len(rev)))
> +    if isinstance(size, int):
> +        if len(rev) != size:
> +            raise error.RepoLookupError(
> +                _('revset size mismatch.'
> +                ' expected %d, got %d') % (size, len(rev)))

There's no point to duplicate these "if"s because both minsize/maxsize should
be set. We could switch the error messages by `minsize == maxsize`, but which
doesn't mean we need different `size` types depending on minsize/maxsize values.

> +    # filter rev by subset. since we'll probably want to get an ordered
> +    # result from expectsize(<set>), we'll have to conditionalize the
> +    # filtering direction

Nit: this comment seems unnecessary since it just rephrase the code.

> +    if order == followorder:
> +        return subset & rev
> +    else:
> +        return rev & subset
_______________________________________________
Mercurial-devel mailing list
[hidden email]
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Reply | Threaded
Open this post in threaded view
|

D5813: revset: add expect to check the size of a set

pulkit (Pulkit Goyal)
yuja added a comment.


  > +@predicate('expectsize(set[, size])', safe=True, takeorder=True)
  >  +def expectrevsetsize(repo, subset, x, order):
  >  +    """Abort if the revset doesn't expect given size"""
  >  +    args = getargsdict(x, 'expect', 'set size')
  >  +    size = args.get('size')
  >  +    if size is not None:
  >  +        minsize, maxsize = getintrange(size,
  >  +                                       _('expectsize requires a size range'
  >  +                                       ' or a positive integer'),
  >  +                                       _('size range bounds must be integers'))
 
  Maybe needs to specify the default min/max values to e.g. possible min/max
  values or `None`.
 
  > +        if minsize != maxsize:
  >  +            size = (minsize, maxsize)
  >  +        else:
  >  +            size = minsize
  >  +    if size is None or 'set' not in args:
  >  +        raise error.ParseError(_('invalid set of arguments'))
  >  +    rev = getset(repo, fullreposet(repo), args['set'], order=order)
  >  +    if isinstance(size, tuple):
  >  +        if len(rev) < minsize or len(rev) > maxsize:
  >  +            raise error.RepoLookupError(
  >  +                _('revset size mismatch.'
  >  +                ' expected between %d and %d, got %d') % (minsize,
  >  +                                                          maxsize,
  >  +                                                          len(rev)))
  >  +    if isinstance(size, int):
  >  +        if len(rev) != size:
  >  +            raise error.RepoLookupError(
  >  +                _('revset size mismatch.'
  >  +                ' expected %d, got %d') % (size, len(rev)))
 
  There's no point to duplicate these "if"s because both minsize/maxsize should
  be set. We could switch the error messages by `minsize == maxsize`, but which
  doesn't mean we need different `size` types depending on minsize/maxsize values.
 
  > +    # filter rev by subset. since we'll probably want to get an ordered
  >  +    # result from expectsize(<set>), we'll have to conditionalize the
  >  +    # filtering direction
 
  Nit: this comment seems unnecessary since it just rephrase the code.
 
  > +    if order == followorder:
  >  +        return subset & rev
  >  +    else:
  >  +        return rev & subset

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D5813

To: navaneeth.suresh, #hg-reviewers
Cc: yuja, pulkit, durin42, mjpieters, mercurial-devel
_______________________________________________
Mercurial-devel mailing list
[hidden email]
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Reply | Threaded
Open this post in threaded view
|

D5813: revset: add expect to check the size of a set

pulkit (Pulkit Goyal)
In reply to this post by pulkit (Pulkit Goyal)
navaneeth.suresh updated this revision to Diff 14000.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D5813?vs=13899&id=14000

REVISION DETAIL
  https://phab.mercurial-scm.org/D5813

AFFECTED FILES
  mercurial/revset.py
  tests/test-revset.t

CHANGE DETAILS

diff --git a/tests/test-revset.t b/tests/test-revset.t
--- a/tests/test-revset.t
+++ b/tests/test-revset.t
@@ -2950,3 +2950,45 @@
   * set:
   <baseset+ [0]>
   0
+
+abort if the revset doesn't expect given size
+  $ log 'expectsize()'
+  hg: parse error: invalid set of arguments
+  [255]
+  $ log 'expectsize(0:2, a)'
+  hg: parse error: expectsize requires a size range or a positive integer
+  [255]
+  $ log 'expectsize(0:2, 3)'
+  0
+  1
+  2
+
+  $ log 'expectsize(2:0, 3)'
+  2
+  1
+  0
+  $ log 'expectsize(0:1, 1)'
+  abort: revset size mismatch. expected 1, got 2!
+  [255]
+  $ log 'expectsize(0:4, -1)'
+  hg: parse error: negative size
+  [255]
+  $ log 'expectsize(0:2, 2:4)'
+  0
+  1
+  2
+  $ log 'expectsize(0:1, 3:5)'
+  abort: revset size mismatch. expected between 3 and 5, got 2!
+  [255]
+  $ log 'expectsize(0:1, -1:2)'
+  hg: parse error: negative size
+  [255]
+  $ log 'expectsize(0:1, 1:-2)'
+  hg: parse error: negative size
+  [255]
+  $ log 'expectsize(0:2, a:4)'
+  hg: parse error: size range bounds must be integers
+  [255]
+  $ log 'expectsize(0:2, 2:b)'
+  hg: parse error: size range bounds must be integers
+  [255]
diff --git a/mercurial/revset.py b/mercurial/revset.py
--- a/mercurial/revset.py
+++ b/mercurial/revset.py
@@ -815,6 +815,38 @@
     contentdivergent = obsmod.getrevs(repo, 'contentdivergent')
     return subset & contentdivergent
 
+@predicate('expectsize(set[, size])', safe=True, takeorder=True)
+def expectrevsetsize(repo, subset, x, order):
+    """Abort if the revset doesn't expect given size"""
+    args = getargsdict(x, 'expect', 'set size')
+    size = args.get('size')
+    minsize = None
+    maxsize = None
+    err = ''
+    if size is not None:
+        minsize, maxsize = getintrange(size,
+                                       _('expectsize requires a size range'
+                                         ' or a positive integer'),
+                                       _('size range bounds must be integers'))
+        if minsize < 0 or maxsize < 0:
+            raise error.ParseError(_('negative size'))
+    if size is None or 'set' not in args:
+        raise error.ParseError(_('invalid set of arguments'))
+    rev = getset(repo, fullreposet(repo), args['set'], order=order)
+    if minsize != maxsize and (len(rev) < minsize or len(rev) > maxsize):
+        err = _('revset size mismatch.'
+                ' expected between %d and %d, got %d') % (minsize, maxsize,
+                                                          len(rev))
+    elif minsize == maxsize and len(rev) != minsize:
+        err = _('revset size mismatch.'
+                ' expected %d, got %d') % (minsize, len(rev))
+    if err:
+        raise error.RepoLookupError(err)
+    if order == followorder:
+        return subset & rev
+    else:
+        return rev & subset
+
 @predicate('extdata(source)', safe=False, weight=100)
 def extdata(repo, subset, x):
     """Changesets in the specified extdata source. (EXPERIMENTAL)"""



To: navaneeth.suresh, #hg-reviewers
Cc: yuja, pulkit, durin42, mjpieters, mercurial-devel
_______________________________________________
Mercurial-devel mailing list
[hidden email]
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Reply | Threaded
Open this post in threaded view
|

Re: D5813: revset: add expect to check the size of a set

Yuya Nishihara
Getting close.

On Sun, 10 Feb 2019 05:19:55 +0000, navaneeth.suresh (Navaneeth Suresh) wrote:
> +  $ log 'expectsize(0:2, 2:4)'

Can you test `:max`, `min:`, and `:` (no constraint)?
They shouldn't fail.

> +@predicate('expectsize(set[, size])', safe=True, takeorder=True)
> +def expectrevsetsize(repo, subset, x, order):
> +    """Abort if the revset doesn't expect given size"""
> +    args = getargsdict(x, 'expect', 'set size')
> +    size = args.get('size')
> +    minsize = None
> +    maxsize = None
> +    err = ''
> +    if size is not None:
> +        minsize, maxsize = getintrange(size,
> +                                       _('expectsize requires a size range'
> +                                         ' or a positive integer'),
> +                                       _('size range bounds must be integers'))
> +        if minsize < 0 or maxsize < 0:
> +            raise error.ParseError(_('negative size'))
> +    if size is None or 'set' not in args:
> +        raise error.ParseError(_('invalid set of arguments'))

Nit: `if size is not None` (and the `size` variable itself) can be removed
if we checked the invalid set of arguments first.
_______________________________________________
Mercurial-devel mailing list
[hidden email]
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
12