revset: make repo.anyrevs accept customized alias override (API)
authorJun Wu <quark@fb.com>
Sat, 24 Jun 2017 15:29:42 -0700
changeset 33336 4672db164c98
parent 33335 72f051f9a7d8
child 33337 de324547c751
revset: make repo.anyrevs accept customized alias override (API) Previously repo.anyrevs only expand aliases in [revsetalias] config. This patch makes it more flexible to accept a customized dict defining aliases without having to couple with ui. revsetlang.expandaliases now has the signature (tree, aliases, warn=None) which is more consistent with templater.expandaliases. revsetlang.py is now free from "ui", which seems to be a good thing.
mercurial/debugcommands.py
mercurial/localrepo.py
mercurial/revset.py
mercurial/revsetlang.py
tests/test-revset.t
--- a/mercurial/debugcommands.py	Fri Jul 07 01:05:20 2017 -0400
+++ b/mercurial/debugcommands.py	Sat Jun 24 15:29:42 2017 -0700
@@ -1960,9 +1960,11 @@
     one. Returns 1 if the optimized result differs.
     """
     opts = pycompat.byteskwargs(opts)
+    aliases = ui.configitems('revsetalias')
     stages = [
         ('parsed', lambda tree: tree),
-        ('expanded', lambda tree: revsetlang.expandaliases(ui, tree)),
+        ('expanded', lambda tree: revsetlang.expandaliases(tree, aliases,
+                                                           ui.warn)),
         ('concatenated', revsetlang.foldconcat),
         ('analyzed', revsetlang.analyze),
         ('optimized', revsetlang.optimize),
--- a/mercurial/localrepo.py	Fri Jul 07 01:05:20 2017 -0400
+++ b/mercurial/localrepo.py	Sat Jun 24 15:29:42 2017 -0700
@@ -648,16 +648,19 @@
         for r in self.revs(expr, *args):
             yield self[r]
 
-    def anyrevs(self, specs, user=False):
+    def anyrevs(self, specs, user=False, localalias=None):
         '''Find revisions matching one of the given revsets.
 
         Revset aliases from the configuration are not expanded by default. To
-        expand user aliases, specify ``user=True``.
+        expand user aliases, specify ``user=True``. To provide some local
+        definitions overriding user aliases, set ``localalias`` to
+        ``{name: definitionstring}``.
         '''
         if user:
-            m = revset.matchany(self.ui, specs, repo=self)
+            m = revset.matchany(self.ui, specs, repo=self,
+                                localalias=localalias)
         else:
-            m = revset.matchany(None, specs)
+            m = revset.matchany(None, specs, localalias=localalias)
         return m(self)
 
     def url(self):
--- a/mercurial/revset.py	Fri Jul 07 01:05:20 2017 -0400
+++ b/mercurial/revset.py	Sat Jun 24 15:29:42 2017 -0700
@@ -2001,12 +2001,15 @@
     """
     return matchany(ui, [spec], repo=repo, order=order)
 
-def matchany(ui, specs, repo=None, order=defineorder):
+def matchany(ui, specs, repo=None, order=defineorder, localalias=None):
     """Create a matcher that will include any revisions matching one of the
     given specs
 
     If order=followorder, a matcher takes the ordering specified by the input
     set.
+
+    If localalias is not None, it is a dict {name: definitionstring}. It takes
+    precedence over [revsetalias] config section.
     """
     if not specs:
         def mfunc(repo, subset=None):
@@ -2023,8 +2026,15 @@
         tree = ('or',
                 ('list',) + tuple(revsetlang.parse(s, lookup) for s in specs))
 
+    aliases = []
+    warn = None
     if ui:
-        tree = revsetlang.expandaliases(ui, tree)
+        aliases.extend(ui.configitems('revsetalias'))
+        warn = ui.warn
+    if localalias:
+        aliases.extend(localalias.items())
+    if aliases:
+        tree = revsetlang.expandaliases(tree, aliases, warn=warn)
     tree = revsetlang.foldconcat(tree)
     tree = revsetlang.analyze(tree, order)
     tree = revsetlang.optimize(tree)
--- a/mercurial/revsetlang.py	Fri Jul 07 01:05:20 2017 -0400
+++ b/mercurial/revsetlang.py	Sat Jun 24 15:29:42 2017 -0700
@@ -561,14 +561,16 @@
         if tree[0] == 'func' and tree[1][0] == 'symbol':
             return tree[1][1], getlist(tree[2])
 
-def expandaliases(ui, tree):
-    aliases = _aliasrules.buildmap(ui.configitems('revsetalias'))
+def expandaliases(tree, aliases, warn=None):
+    """Expand aliases in a tree, aliases is a list of (name, value) tuples"""
+    aliases = _aliasrules.buildmap(aliases)
     tree = _aliasrules.expand(aliases, tree)
     # warn about problematic (but not referred) aliases
-    for name, alias in sorted(aliases.iteritems()):
-        if alias.error and not alias.warned:
-            ui.warn(_('warning: %s\n') % (alias.error))
-            alias.warned = True
+    if warn is not None:
+        for name, alias in sorted(aliases.iteritems()):
+            if alias.error and not alias.warned:
+                warn(_('warning: %s\n') % (alias.error))
+                alias.warned = True
     return tree
 
 def foldconcat(tree):
--- a/tests/test-revset.t	Fri Jul 07 01:05:20 2017 -0400
+++ b/tests/test-revset.t	Sat Jun 24 15:29:42 2017 -0700
@@ -4259,4 +4259,27 @@
   hg: parse error: unknown identifier: custom1
   [255]
 
+Test repo.anyrevs with customized revset overrides
+
+  $ cat > $TESTTMP/printprevset.py <<EOF
+  > from mercurial import encoding
+  > def reposetup(ui, repo):
+  >     alias = {}
+  >     p = encoding.environ.get('P')
+  >     if p:
+  >         alias['P'] = p
+  >     revs = repo.anyrevs(['P'], user=True, localalias=alias)
+  >     ui.write('P=%r' % list(revs))
+  > EOF
+
+  $ cat >> .hg/hgrc <<EOF
+  > custompredicate = !
+  > printprevset = $TESTTMP/printprevset.py
+  > EOF
+
+  $ hg --config revsetalias.P=1 log -r . -T '\n'
+  P=[1]
+  $ P=3 hg --config revsetalias.P=2 log -r . -T '\n'
+  P=[3]
+
   $ cd ..