[PATCH 3 of 4 V2] hgweb: add revsetsearch() function when query can be parsed as a revset

Alexander Plavin alexander at plav.in
Fri Aug 9 13:54:57 CDT 2013


# HG changeset patch
# User Alexander Plavin <alexander at plav.in>
# Date 1375823774 -14400
#      Wed Aug 07 01:16:14 2013 +0400
# Node ID 80319cecf93938fb529984f4a2f5c105bcc709b1
# Parent  dfc9d96b85a4ebb96d7ad876952aad1cd052c444
hgweb: add revsetsearch() function when query can be parsed as a revset

This function is used when all the conditions are met:
- 'reverse(%s)' % query string can be parsed to a revset tree
- this tree has depth more than two, i.e. the query has some part of
revset syntax used
- the repo can be actually matched against this tree, i.e. it has only existent
function/operators and revisions/tags/bookmarks specified are correct

Otherwise keywordsearch() or revsearch() functions are used as before.

Add several new tests for different parsing conditions and exception handling.

diff -r dfc9d96b85a4 -r 80319cecf939 mercurial/hgweb/webcommands.py
--- a/mercurial/hgweb/webcommands.py	Wed Aug 07 01:21:31 2013 +0400
+++ b/mercurial/hgweb/webcommands.py	Wed Aug 07 01:16:14 2013 +0400
@@ -16,6 +16,8 @@
 from mercurial import help as helpmod
 from mercurial import scmutil
 from mercurial.i18n import _
+from mercurial.error import ParseError, RepoLookupError, Abort
+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.
@@ -141,9 +143,15 @@
 
             yield ctx
 
+    def revsetsearch():
+        revs = revset.match(web.repo.ui, revdef)(web.repo, list(web.repo))
+        for r in revs:
+            yield web.repo[r]
+
     searchfuncs = {
         'rev': revsearch,
         'kw': keywordsearch,
+        'revset': revsetsearch,
     }
 
     def changelist(**map):
@@ -193,7 +201,31 @@
         web.repo[query]
         modename = 'rev'
     except (error.RepoError, error.LookupError):
-        modename = 'kw'
+        # query is not an exact revision pointer, now decide if
+        # it's a revset expession or keywords
+        revdef = 'reverse(%s)' % query
+        try:
+            p = parser.parser(revset.tokenize, revset.elements)
+            tree, pos = p.parse(revdef)
+        except ParseError:
+            # can't parse to a tree
+            modename = 'kw'
+        else:
+            if revset.depth(tree) > 2:
+                mfunc = revset.match(None, revdef)
+                try:
+                    # try running against empty subset
+                    mfunc(web.repo, [])
+                    modename = 'revset'
+                    # ParseError: wrongly placed tokens, wrongs arguments, etc
+                    # RepoLookupError: no such revision, e.g. in 'revision:'
+                    # Abort: bookmark/tag not exists
+                except (ParseError, RepoLookupError, Abort):
+                    # can't run the revset query, e.g. some function misspelled
+                    modename = 'kw'
+            else:
+                # no revset syntax used
+                modename = 'kw'
 
     searchfunc = searchfuncs[modename]
 
diff -r dfc9d96b85a4 -r 80319cecf939 tests/test-hgweb-commands.t
--- a/tests/test-hgweb-commands.t	Wed Aug 07 01:21:31 2013 +0400
+++ b/tests/test-hgweb-commands.t	Wed Aug 07 01:16:14 2013 +0400
@@ -537,6 +537,27 @@
   $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT 'log?rev=stable&style=raw' | grep 'revision:'
   revision:    2
 
+Search with revset syntax
+
+  $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT 'log?rev=tip^&style=raw' | egrep 'Query|revision:'
+  # Query "tip^"
+  revision:    2
+  $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT 'log?rev=last(all(),2)^&style=raw' | egrep 'Query|revision:'
+  # Query "last(all(),2)^"
+  revision:    2
+  revision:    1
+  $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT 'log?rev=last(all(,2)^&style=raw' | egrep 'Query|revision:'
+  # Query "last(all(,2)^"
+  $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT 'log?rev=last(al(),2)^&style=raw' | egrep 'Query|revision:'
+  # Query "last(al(),2)^"
+  $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT 'log?rev=bookmark(anotherthing)&style=raw' | egrep 'Query|revision:'
+  # Query "bookmark(anotherthing)"
+  revision:    0
+  $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT 'log?rev=bookmark(abc)&style=raw' | egrep 'Query|revision:'
+  # Query "bookmark(abc)"
+  $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT 'log?rev=deadbeef:&style=raw' | egrep 'Query|revision:'
+  # Query "deadbeef:"
+
 File-related
 
   $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT 'file/1/foo/?style=raw'


More information about the Mercurial-devel mailing list