[PATCH 4 of 4 RFC] hgweb: add condition to use revsetsearch when query can be parsed as a revset

Alexander Plavin me at aplavin.ru
Sun Jul 14 16:45:29 CDT 2013


# HG changeset patch
# User Alexander Plavin <me at aplavin.ru>
# Date 1373836671 -14400
#      Mon Jul 15 01:17:51 2013 +0400
# Node ID 8946b570acdcc1599be6c3dc327608096e0b4040
# Parent  bca776abd685893451086701fac8b11845680b85
hgweb: add condition to use revsetsearch when query can be parsed as a revset

There are several checks:
- the 'reverse(%s)' % query string can be parsed to a tree
- this tree has depth more than two, i.e. the query has some function invocation
- this tree can be 'run', i.e. contains only correctly-named functions and
operators

diff -r bca776abd685 -r 8946b570acdc mercurial/hgweb/webcommands.py
--- a/mercurial/hgweb/webcommands.py	Mon Jul 15 01:13:39 2013 +0400
+++ b/mercurial/hgweb/webcommands.py	Mon Jul 15 01:17:51 2013 +0400
@@ -16,6 +16,8 @@
 from mercurial import help as helpmod
 from mercurial import cmdutil, scmutil
 from mercurial.i18n import _
+from mercurial.error import ParseError
+from mercurial import parser, revset
 
 # __all__ is populated with the allowed commands. Be sure to add to it if
 # you're adding a new command, or the new command won't work.
@@ -139,7 +141,7 @@
             yield ctx
 
     def revsetsearch():
-        opts = {'rev': ['reverse(%s)' % query]}
+        opts = {'rev': [revdef]}
         matchfn = scmutil.match(web.repo[None], [], opts)
 
         def prep(ctx, fns):
@@ -194,7 +196,27 @@
     tip = web.repo['tip']
     parity = paritygen(web.stripecount)
 
-    searchf = simplesearch
+    try:
+        revdef = 'reverse(%s)' % query
+        tree, pos = parser.parser(revset.tokenize, revset.elements).parse(revdef)
+        def depth(t):
+            if isinstance(t, tuple):
+                return max(map(depth, t)) + 1
+            else:
+                return 0
+
+        if depth(tree) > 2:
+            searchf = revsetsearch
+        else:
+            searchf = simplesearch
+
+        mfunc = revset.match(None, revdef)
+        try:
+            mfunc(None, None)
+        except (TypeError, AttributeError):
+            pass
+    except ParseError:
+        searchf = simplesearch
 
     return tmpl('search', query=query, node=tip.hex(),
                 entries=changelist, archives=web.archivelist("tip"),


More information about the Mercurial-devel mailing list