[PATCH 2 of 6 V3] hgweb: add revsetsearch() function when query can be parsed as a revset

Augie Fackler raf at durin42.com
Tue Aug 27 10:07:50 CDT 2013


On Tue, Aug 27, 2013 at 11:34:51AM +0400, Alexander Plavin wrote:
>
>
> 26.08.2013, 18:47, "Augie Fackler" <raf at durin42.com>:
> > On Thu, Aug 22, 2013 at 07:11:13PM +0400, Alexander Plavin wrote:
> >
> >>  # HG changeset patch
> >>  # User Alexander Plavin <alexander at plav.in>
> >>  # Date 1375823774 -14400
> >>  #      Wed Aug 07 01:16:14 2013 +0400
> >>  # Node ID c9ded075156603c15bb0a71273d2babbd19ab6fb
> >>  # Parent  f32bf1774cc3e6cd7ee99a7be2724daa23223a98
> >>  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.
> >
> > Looks great.
> >
> >>  diff -r f32bf1774cc3 -r c9ded0751566 mercurial/hgweb/webcommands.py
> >>  --- a/mercurial/hgweb/webcommands.py Fri Aug 09 22:52:58 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,18 +143,50 @@
> >>
> >>               yield ctx
> >>
> >>  +    def revsetsearch(revdef):
> >>  +        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 getsearchmode(query):
> >>           try:
> >>               ctx = web.repo[query]
> >>           except (error.RepoError, error.LookupError):
> >>  +            # query is not an exact revision pointer, need to
> >>  +            # decide if it's a revset expession or keywords
> >>  +            pass
> >>  +        else:
> >>  +            return 'rev', ctx
> >
> > Why not just return from the try block instead of using try/else?
>
> try/except/else here is actually introduced in an earlier patch (https://hg.plav.in/hg_fork/rev/5407b1e23932), and as for me it looks more symmetrical ('except' and 'else' branches), thus easier to read. Am I wrong here?
>

Doesn't bother me much one way or the other. I don't feel strongly.

> >
> >>  +
> >>  +        revdef = 'reverse(%s)' % query
> >>  +        try:
> >>  +            p = parser.parser(revset.tokenize, revset.elements)
> >>  +            tree, pos = p.parse(revdef)
> >>  +        except ParseError:
> >>  +            # can't parse to a revset tree
> >>  +            return 'kw', query
> >>  +
> >>  +        if revset.depth(tree) <= 2:
> >>  +            # no revset syntax used
> >>  +            return 'kw', query
> >>  +
> >>  +        mfunc = revset.match(None, revdef)
> >>  +        try:
> >>  +            # try running against empty subset
> >>  +            mfunc(web.repo, [])
> >>  +            # ParseError: wrongly placed tokens, wrongs arguments, etc
> >>  +            # RepoLookupError: no such revision, e.g. in 'revision:'
> >>  +            # Abort: bookmark/tag not exists
> >>  +        except (ParseError, RepoLookupError, Abort):
> >>               return 'kw', query
> >>           else:
> >>  -            return 'rev', ctx
> >>  +            return 'revset', revdef
> >>
> >>       def changelist(**map):
> >>           count = 0
> >>  diff -r f32bf1774cc3 -r c9ded0751566 tests/test-hgweb-commands.t
> >>  --- a/tests/test-hgweb-commands.t Fri Aug 09 22:52:58 2013 +0400
> >>  +++ b/tests/test-hgweb-commands.t Wed Aug 07 01:16:14 2013 +0400
> >>  @@ -537,6 +537,101 @@
> >>     $ "$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'
> >>  +  200 Script output follows
> >>  +
> >>  +
> >>  +  # HG changesets search
> >>  +  # Node ID cad8025a2e87f88c06259790adfa15acb4080123
> >>  +  # Query "tip^"
> >>  +
> >>  +  changeset:   1d22e65f027e5a0609357e7d8e7508cd2ba5d2fe
> >>  +  revision:    2
> >>  +  user:        test
> >>  +  date:        Thu, 01 Jan 1970 00:00:00 +0000
> >>  +  summary:     branch
> >>  +  branch:      stable
> >>  +
> >>  +
> >>  +  $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT 'log?rev=last(all(),2)^&style=raw'
> >>  +  200 Script output follows
> >>  +
> >>  +
> >>  +  # HG changesets search
> >>  +  # Node ID cad8025a2e87f88c06259790adfa15acb4080123
> >>  +  # Query "last(all(),2)^"
> >>  +
> >>  +  changeset:   1d22e65f027e5a0609357e7d8e7508cd2ba5d2fe
> >>  +  revision:    2
> >>  +  user:        test
> >>  +  date:        Thu, 01 Jan 1970 00:00:00 +0000
> >>  +  summary:     branch
> >>  +  branch:      stable
> >>  +
> >>  +  changeset:   a4f92ed23982be056b9852de5dfe873eaac7f0de
> >>  +  revision:    1
> >>  +  user:        test
> >>  +  date:        Thu, 01 Jan 1970 00:00:00 +0000
> >>  +  summary:     Added tag 1.0 for changeset 2ef0ac749a14
> >>  +  branch:      default
> >>  +
> >>  +
> >>  +  $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT 'log?rev=last(all(,2)^&style=raw'
> >>  +  200 Script output follows
> >>  +
> >>  +
> >>  +  # HG changesets search
> >>  +  # Node ID cad8025a2e87f88c06259790adfa15acb4080123
> >>  +  # Query "last(all(,2)^"
> >>  +
> >>  +
> >>  +  $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT 'log?rev=last(al(),2)^&style=raw'
> >>  +  200 Script output follows
> >>  +
> >>  +
> >>  +  # HG changesets search
> >>  +  # Node ID cad8025a2e87f88c06259790adfa15acb4080123
> >>  +  # Query "last(al(),2)^"
> >>  +
> >>  +
> >>  +  $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT 'log?rev=bookmark(anotherthing)&style=raw'
> >>  +  200 Script output follows
> >>  +
> >>  +
> >>  +  # HG changesets search
> >>  +  # Node ID cad8025a2e87f88c06259790adfa15acb4080123
> >>  +  # Query "bookmark(anotherthing)"
> >>  +
> >>  +  changeset:   2ef0ac749a14e4f57a5a822464a0902c6f7f448f
> >>  +  revision:    0
> >>  +  user:        test
> >>  +  date:        Thu, 01 Jan 1970 00:00:00 +0000
> >>  +  summary:     base
> >>  +  tag:         1.0
> >>  +  bookmark:    anotherthing
> >>  +
> >>  +
> >>  +  $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT 'log?rev=bookmark(abc)&style=raw'
> >>  +  200 Script output follows
> >>  +
> >>  +
> >>  +  # HG changesets search
> >>  +  # Node ID cad8025a2e87f88c06259790adfa15acb4080123
> >>  +  # Query "bookmark(abc)"
> >>  +
> >>  +
> >>  +  $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT 'log?rev=deadbeef:&style=raw'
> >>  +  200 Script output follows
> >>  +
> >>  +
> >>  +  # HG changesets search
> >>  +  # Node ID cad8025a2e87f88c06259790adfa15acb4080123
> >>  +  # Query "deadbeef:"
> >>  +
> >>  +
> >>  +
> >>   File-related
> >>
> >>     $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT 'file/1/foo/?style=raw'
> >>  _______________________________________________
> >>  Mercurial-devel mailing list
> >>  Mercurial-devel at selenic.com
> >>  http://selenic.com/mailman/listinfo/mercurial-devel


More information about the Mercurial-devel mailing list