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

login
register
mail settings
Submitter Alexander Plavin
Date July 14, 2013, 9:45 p.m.
Message ID <8946b570acdcc1599be6.1373838329@debian-alexander.dolgopa>
Download mbox | patch
Permalink /patch/1895/
State Superseded
Headers show

Comments

Alexander Plavin - July 14, 2013, 9:45 p.m.
# HG changeset patch
# User Alexander Plavin <me@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

Patch

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