From patchwork Fri Aug 9 18:54:57 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [3, of, 4, V2] hgweb: add revsetsearch() function when query can be parsed as a revset From: Alexander Plavin X-Patchwork-Id: 2103 Message-Id: <80319cecf93938fb5299.1376074497@debian-alexander.dolgopa> To: mercurial-devel@selenic.com Date: Fri, 09 Aug 2013 22:54:57 +0400 # HG changeset patch # User Alexander Plavin # 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'