mercurial/hgweb/webcommands.py
changeset 19722 bf15935b68a3
parent 19657 145636d31bb4
child 19735 6907251122e3
equal deleted inserted replaced
19721:d8ca6d965230 19722:bf15935b68a3
    14 from common import HTTP_OK, HTTP_FORBIDDEN, HTTP_NOT_FOUND
    14 from common import HTTP_OK, HTTP_FORBIDDEN, HTTP_NOT_FOUND
    15 from mercurial import graphmod, patch
    15 from mercurial import graphmod, patch
    16 from mercurial import help as helpmod
    16 from mercurial import help as helpmod
    17 from mercurial import scmutil
    17 from mercurial import scmutil
    18 from mercurial.i18n import _
    18 from mercurial.i18n import _
       
    19 from mercurial.error import ParseError, RepoLookupError, Abort
       
    20 from mercurial import revset
    19 
    21 
    20 # __all__ is populated with the allowed commands. Be sure to add to it if
    22 # __all__ is populated with the allowed commands. Be sure to add to it if
    21 # you're adding a new command, or the new command won't work.
    23 # you're adding a new command, or the new command won't work.
    22 
    24 
    23 __all__ = [
    25 __all__ = [
   109             raise inst
   111             raise inst
   110 
   112 
   111 def _search(web, req, tmpl):
   113 def _search(web, req, tmpl):
   112     MODE_REVISION = 'rev'
   114     MODE_REVISION = 'rev'
   113     MODE_KEYWORD = 'keyword'
   115     MODE_KEYWORD = 'keyword'
       
   116     MODE_REVSET = 'revset'
   114 
   117 
   115     def revsearch(ctx):
   118     def revsearch(ctx):
   116         yield ctx
   119         yield ctx
   117 
   120 
   118     def keywordsearch(query):
   121     def keywordsearch(query):
   141             if miss:
   144             if miss:
   142                 continue
   145                 continue
   143 
   146 
   144             yield ctx
   147             yield ctx
   145 
   148 
       
   149     def revsetsearch(revs):
       
   150         for r in revs:
       
   151             yield web.repo[r]
       
   152 
   146     searchfuncs = {
   153     searchfuncs = {
   147         MODE_REVISION: revsearch,
   154         MODE_REVISION: revsearch,
   148         MODE_KEYWORD: keywordsearch,
   155         MODE_KEYWORD: keywordsearch,
       
   156         MODE_REVSET: revsetsearch,
   149     }
   157     }
   150 
   158 
   151     def getsearchmode(query):
   159     def getsearchmode(query):
   152         try:
   160         try:
   153             ctx = web.repo[query]
   161             ctx = web.repo[query]
   154         except (error.RepoError, error.LookupError):
   162         except (error.RepoError, error.LookupError):
   155             return MODE_KEYWORD, query
   163             # query is not an exact revision pointer, need to
       
   164             # decide if it's a revset expession or keywords
       
   165             pass
   156         else:
   166         else:
   157             return MODE_REVISION, ctx
   167             return MODE_REVISION, ctx
       
   168 
       
   169         revdef = 'reverse(%s)' % query
       
   170         try:
       
   171             tree, pos = revset.parse(revdef)
       
   172         except ParseError:
       
   173             # can't parse to a revset tree
       
   174             return MODE_KEYWORD, query
       
   175 
       
   176         if revset.depth(tree) <= 2:
       
   177             # no revset syntax used
       
   178             return MODE_KEYWORD, query
       
   179 
       
   180         if util.any((token, (value or '')[:3]) == ('string', 're:')
       
   181                     for token, value, pos in revset.tokenize(revdef)):
       
   182             return MODE_KEYWORD, query
       
   183 
       
   184         funcsused = revset.funcsused(tree)
       
   185         if not funcsused.issubset(revset.safesymbols):
       
   186             return MODE_KEYWORD, query
       
   187 
       
   188         mfunc = revset.match(web.repo.ui, revdef)
       
   189         try:
       
   190             revs = mfunc(web.repo, list(web.repo))
       
   191             return MODE_REVSET, revs
       
   192             # ParseError: wrongly placed tokens, wrongs arguments, etc
       
   193             # RepoLookupError: no such revision, e.g. in 'revision:'
       
   194             # Abort: bookmark/tag not exists
       
   195             # LookupError: ambiguous identifier, e.g. in '(bc)' on a large repo
       
   196         except (ParseError, RepoLookupError, Abort, LookupError):
       
   197             return MODE_KEYWORD, query
   158 
   198 
   159     def changelist(**map):
   199     def changelist(**map):
   160         count = 0
   200         count = 0
   161 
   201 
   162         for ctx in searchfunc(funcarg):
   202         for ctx in searchfunc(funcarg):