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

login
register
mail settings
Submitter phabricator
Date Feb. 7, 2019, 7:28 p.m.
Message ID <c3b346579c5be487960b935993863c10@localhost.localdomain>
Download mbox | patch
Permalink /patch/38533/
State Not Applicable
Headers show

Comments

phabricator - Feb. 7, 2019, 7:28 p.m.
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




To: navaneeth.suresh, #hg-reviewers
Cc: yuja, pulkit, durin42, mjpieters, mercurial-devel
Yuya Nishihara - Feb. 10, 2019, 1:26 a.m.
> +@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
phabricator - Feb. 10, 2019, 1:27 a.m.
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

Patch

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)"""