Mercurial > public > mercurial-scm > hg-stable
diff mercurial/hgweb/webcommands.py @ 43076:2372284d9457
formatting: blacken the codebase
This is using my patch to black
(https://github.com/psf/black/pull/826) so we don't un-wrap collection
literals.
Done with:
hg files 'set:**.py - mercurial/thirdparty/** - "contrib/python-zstandard/**"' | xargs black -S
# skip-blame mass-reformatting only
# no-check-commit reformats foo_bar functions
Differential Revision: https://phab.mercurial-scm.org/D6971
author | Augie Fackler <augie@google.com> |
---|---|
date | Sun, 06 Oct 2019 09:45:02 -0400 |
parents | 0bd56c291359 |
children | 687b865b95ad |
line wrap: on
line diff
--- a/mercurial/hgweb/webcommands.py Sat Oct 05 10:29:34 2019 -0400 +++ b/mercurial/hgweb/webcommands.py Sun Oct 06 09:45:02 2019 -0400 @@ -39,17 +39,14 @@ templateutil, ) -from ..utils import ( - stringutil, -) +from ..utils import stringutil -from . import ( - webutil, -) +from . import webutil __all__ = [] commands = {} + class webcommand(object): """Decorator used to register a web command handler. @@ -81,6 +78,7 @@ commands[self.name] = func return func + @webcommand('log') def log(web): """ @@ -103,6 +101,7 @@ else: return changelog(web) + @webcommand('rawfile') def rawfile(web): guessmime = web.configbool('web', 'guessmime') @@ -136,12 +135,14 @@ mt += '; charset="%s"' % encoding.encoding web.res.headers['Content-Type'] = mt - filename = (path.rpartition('/')[-1] - .replace('\\', '\\\\').replace('"', '\\"')) + filename = ( + path.rpartition('/')[-1].replace('\\', '\\\\').replace('"', '\\"') + ) web.res.headers['Content-Disposition'] = 'inline; filename="%s"' % filename web.res.setbodybytes(text) return web.res.sendresponse() + def _filerevision(web, fctx): f = fctx.path() text = fctx.data() @@ -151,15 +152,18 @@ if stringutil.binary(text): mt = pycompat.sysbytes( mimetypes.guess_type(pycompat.fsdecode(f))[0] - or r'application/octet-stream') + or r'application/octet-stream' + ) text = '(binary:%s)' % mt def lines(context): for lineno, t in enumerate(text.splitlines(True)): - yield {"line": t, - "lineid": "l%d" % (lineno + 1), - "linenumber": "% 6d" % (lineno + 1), - "parity": next(parity)} + yield { + "line": t, + "lineid": "l%d" % (lineno + 1), + "linenumber": "% 6d" % (lineno + 1), + "parity": next(parity), + } return web.sendtemplate( 'filerevision', @@ -170,7 +174,9 @@ rename=webutil.renamelink(fctx), permissions=fctx.manifest().flags(f), ishead=int(ishead), - **pycompat.strkwargs(webutil.commonentry(web.repo, fctx))) + **pycompat.strkwargs(webutil.commonentry(web.repo, fctx)) + ) + @webcommand('file') def file(web): @@ -206,6 +212,7 @@ except ErrorResponse: raise inst + def _search(web): MODE_REVISION = 'rev' MODE_KEYWORD = 'keyword' @@ -232,9 +239,11 @@ for ctx in revgen(): miss = 0 for q in qw: - if not (q in lower(ctx.user()) or - q in lower(ctx.description()) or - q in lower(" ".join(ctx.files()))): + if not ( + q in lower(ctx.user()) + or q in lower(ctx.description()) + or q in lower(" ".join(ctx.files())) + ): miss = 1 break if miss: @@ -273,8 +282,10 @@ # no revset syntax used return MODE_KEYWORD, query - if any((token, (value or '')[:3]) == ('string', 're:') - for token, value, pos in revsetlang.tokenize(revdef)): + if any( + (token, (value or '')[:3]) == ('string', 're:') + for token, value, pos in revsetlang.tokenize(revdef) + ): return MODE_KEYWORD, query funcsused = revsetlang.funcsused(tree) @@ -282,16 +293,21 @@ return MODE_KEYWORD, query try: - mfunc = revset.match(web.repo.ui, revdef, - lookup=revset.lookupfn(web.repo)) + mfunc = revset.match( + web.repo.ui, revdef, lookup=revset.lookupfn(web.repo) + ) revs = mfunc(web.repo) return MODE_REVSET, revs # ParseError: wrongly placed tokens, wrongs arguments, etc # RepoLookupError: no such revision, e.g. in 'revision:' # Abort: bookmark/tag not exists # LookupError: ambiguous identifier, e.g. in '(bc)' on a large repo - except (error.ParseError, error.RepoLookupError, error.Abort, - LookupError): + except ( + error.ParseError, + error.RepoLookupError, + error.Abort, + LookupError, + ): return MODE_KEYWORD, query def changelist(context): @@ -304,11 +320,13 @@ files = webutil.listfilediffs(ctx.files(), n, web.maxfiles) lm = webutil.commonentry(web.repo, ctx) - lm.update({ - 'parity': next(parity), - 'changelogtag': showtags, - 'files': files, - }) + lm.update( + { + 'parity': next(parity), + 'changelogtag': showtags, + 'files': files, + } + ) yield lm if count >= revcount: @@ -361,7 +379,9 @@ lessvars=lessvars, modedesc=searchfunc[1], showforcekw=showforcekw, - showunforcekw=showunforcekw) + showunforcekw=showunforcekw, + ) + @webcommand('changelog') def changelog(web, shortlog=False): @@ -453,7 +473,9 @@ revcount=revcount, morevars=morevars, lessvars=lessvars, - query=query) + query=query, + ) + @webcommand('shortlog') def shortlog(web): @@ -469,6 +491,7 @@ """ return changelog(web, shortlog=True) + @webcommand('changeset') def changeset(web): """ @@ -487,12 +510,12 @@ """ ctx = webutil.changectx(web.repo, web.req) - return web.sendtemplate( - 'changeset', - **webutil.changesetentry(web, ctx)) + return web.sendtemplate('changeset', **webutil.changesetentry(web, ctx)) + rev = webcommand('rev')(changeset) + def decodepath(path): """Hook for mapping a path in the repository to a path in the working copy. @@ -501,6 +524,7 @@ the virtual file system presented by the manifest command below.""" return path + @webcommand('manifest') def manifest(web): """ @@ -549,14 +573,14 @@ if len(elements) == 1: files[remain] = full else: - h = dirs # need to retain ref to dirs (root) + h = dirs # need to retain ref to dirs (root) for elem in elements[0:-1]: if elem not in h: h[elem] = {} h = h[elem] if len(h) > 1: break - h[None] = None # denotes files present + h[None] = None # denotes files present if mf and not files and not dirs: raise ErrorResponse(HTTP_NOT_FOUND, 'path not found: ' + path) @@ -566,12 +590,14 @@ full = files[f] fctx = ctx.filectx(full) - yield {"file": full, - "parity": next(parity), - "basename": f, - "date": fctx.date(), - "size": fctx.size(), - "permissions": mf.flags(full)} + yield { + "file": full, + "parity": next(parity), + "basename": f, + "date": fctx.date(), + "size": fctx.size(), + "permissions": mf.flags(full), + } def dirlist(context): for d in sorted(dirs): @@ -585,10 +611,12 @@ h = v path = "%s%s" % (abspath, d) - yield {"parity": next(parity), - "path": path, - "emptydirs": "/".join(emptydirs), - "basename": d} + yield { + "parity": next(parity), + "path": path, + "emptydirs": "/".join(emptydirs), + "basename": d, + } return web.sendtemplate( 'manifest', @@ -599,7 +627,9 @@ fentries=templateutil.mappinggenerator(filelist), dentries=templateutil.mappinggenerator(dirlist), archives=web.archivelist(hex(node)), - **pycompat.strkwargs(webutil.commonentry(web.repo, ctx))) + **pycompat.strkwargs(webutil.commonentry(web.repo, ctx)) + ) + @webcommand('tags') def tags(web): @@ -623,18 +653,21 @@ if latestonly: t = t[:1] for k, n in t: - yield {"parity": next(parity), - "tag": k, - "date": web.repo[n].date(), - "node": hex(n)} + yield { + "parity": next(parity), + "tag": k, + "date": web.repo[n].date(), + "node": hex(n), + } return web.sendtemplate( 'tags', node=hex(web.repo.changelog.tip()), entries=templateutil.mappinggenerator(entries, args=(False, False)), - entriesnotip=templateutil.mappinggenerator(entries, - args=(True, False)), - latestentry=templateutil.mappinggenerator(entries, args=(True, True))) + entriesnotip=templateutil.mappinggenerator(entries, args=(True, False)), + latestentry=templateutil.mappinggenerator(entries, args=(True, True)), + ) + @webcommand('bookmarks') def bookmarks(web): @@ -658,10 +691,12 @@ if latestonly: t = i[:1] for k, n in t: - yield {"parity": next(parity), - "bookmark": k, - "date": web.repo[n].date(), - "node": hex(n)} + yield { + "parity": next(parity), + "bookmark": k, + "date": web.repo[n].date(), + "node": hex(n), + } if i: latestrev = i[0][1] @@ -674,7 +709,9 @@ node=hex(web.repo.changelog.tip()), lastchange=templateutil.mappinglist([{'date': lastdate}]), entries=templateutil.mappinggenerator(entries, args=(False,)), - latestentry=templateutil.mappinggenerator(entries, args=(True,))) + latestentry=templateutil.mappinggenerator(entries, args=(True,)), + ) + @webcommand('branches') def branches(web): @@ -697,7 +734,9 @@ 'branches', node=hex(web.repo.changelog.tip()), entries=entries, - latestentry=latestentry) + latestentry=latestentry, + ) + @webcommand('summary') def summary(web): @@ -718,11 +757,11 @@ parity = paritygen(web.stripecount) count = 0 for k, n in i: - if k == "tip": # skip tip + if k == "tip": # skip tip continue count += 1 - if count > 10: # limit to 10 tags + if count > 10: # limit to 10 tags break yield { @@ -738,14 +777,16 @@ sortkey = lambda b: (web.repo[b[1]].rev(), b[0]) marks = sorted(marks, key=sortkey, reverse=True) for k, n in marks[:10]: # limit to 10 bookmarks - yield {'parity': next(parity), - 'bookmark': k, - 'date': web.repo[n].date(), - 'node': hex(n)} + yield { + 'parity': next(parity), + 'bookmark': k, + 'date': web.repo[n].date(), + 'node': hex(n), + } def changelist(context): parity = paritygen(web.stripecount, offset=start - end) - l = [] # build a list in forward order for efficiency + l = [] # build a list in forward order for efficiency revs = [] if start < end: revs = web.repo.changelog.revs(start, end - 1) @@ -776,12 +817,15 @@ tags=templateutil.mappinggenerator(tagentries, name='tagentry'), bookmarks=templateutil.mappinggenerator(bookmarks), branches=webutil.branchentries(web.repo, web.stripecount, 10), - shortlog=templateutil.mappinggenerator(changelist, - name='shortlogentry'), + shortlog=templateutil.mappinggenerator( + changelist, name='shortlogentry' + ), node=tip.hex(), symrev='tip', archives=web.archivelist('tip'), - labels=templateutil.hybridlist(labels, name='label')) + labels=templateutil.hybridlist(labels, name='label'), + ) + @webcommand('filediff') def filediff(web): @@ -828,10 +872,13 @@ symrev=webutil.symrevorshortnode(web.req, ctx), rename=rename, diff=diffs, - **pycompat.strkwargs(webutil.commonentry(web.repo, ctx))) + **pycompat.strkwargs(webutil.commonentry(web.repo, ctx)) + ) + diff = webcommand('diff')(filediff) + @webcommand('comparison') def comparison(web): """ @@ -864,7 +911,8 @@ if f.isbinary(): mt = pycompat.sysbytes( mimetypes.guess_type(pycompat.fsdecode(f.path()))[0] - or r'application/octet-stream') + or r'application/octet-stream' + ) return [_('(binary file %s, hash: %s)') % (mt, hex(f.filenode()))] return f.data().splitlines() @@ -905,7 +953,9 @@ rightrev=rightrev, rightnode=hex(rightnode), comparison=comparison, - **pycompat.strkwargs(webutil.commonentry(web.repo, ctx))) + **pycompat.strkwargs(webutil.commonentry(web.repo, ctx)) + ) + @webcommand('annotate') def annotate(web): @@ -934,6 +984,7 @@ # TODO there are still redundant operations within basefilectx.parents() # and from the fctx.annotate() call itself that could be cached. parentscache = {} + def parents(context, f): rev = f.rev() if rev not in parentscache: @@ -952,9 +1003,15 @@ if fctx.isbinary(): mt = pycompat.sysbytes( mimetypes.guess_type(pycompat.fsdecode(fctx.path()))[0] - or r'application/octet-stream') - lines = [dagop.annotateline(fctx=fctx.filectx(fctx.filerev()), - lineno=1, text='(binary:%s)' % mt)] + or r'application/octet-stream' + ) + lines = [ + dagop.annotateline( + fctx=fctx.filectx(fctx.filerev()), + lineno=1, + text='(binary:%s)' % mt, + ) + ] else: lines = webutil.annotate(web.req, fctx, web.repo.ui) @@ -969,22 +1026,24 @@ else: blockhead = None previousrev = rev - yield {"parity": next(parity), - "node": f.hex(), - "rev": rev, - "author": f.user(), - "parents": templateutil.mappinggenerator(parents, args=(f,)), - "desc": f.description(), - "extra": f.extra(), - "file": f.path(), - "blockhead": blockhead, - "blockparity": blockparity, - "targetline": aline.lineno, - "line": aline.text, - "lineno": lineno + 1, - "lineid": "l%d" % (lineno + 1), - "linenumber": "% 6d" % (lineno + 1), - "revdate": f.date()} + yield { + "parity": next(parity), + "node": f.hex(), + "rev": rev, + "author": f.user(), + "parents": templateutil.mappinggenerator(parents, args=(f,)), + "desc": f.description(), + "extra": f.extra(), + "file": f.path(), + "blockhead": blockhead, + "blockparity": blockparity, + "targetline": aline.lineno, + "line": aline.text, + "lineno": lineno + 1, + "lineid": "l%d" % (lineno + 1), + "linenumber": "% 6d" % (lineno + 1), + "revdate": f.date(), + } diffopts = webutil.difffeatureopts(web.req, web.repo.ui, 'annotate') diffopts = {k: getattr(diffopts, k) for k in diffopts.defaults} @@ -999,7 +1058,9 @@ permissions=fctx.manifest().flags(f), ishead=int(ishead), diffopts=templateutil.hybriddict(diffopts), - **pycompat.strkwargs(webutil.commonentry(web.repo, fctx))) + **pycompat.strkwargs(webutil.commonentry(web.repo, fctx)) + ) + @webcommand('filelog') def filelog(web): @@ -1023,11 +1084,11 @@ f = webutil.cleanpath(web.repo, web.req.qsparams['file']) fl = web.repo.file(f) numrevs = len(fl) - if not numrevs: # file doesn't exist at all + if not numrevs: # file doesn't exist at all raise rev = webutil.changectx(web.repo, web.req).rev() first = fl.linkrev(0) - if rev < first: # current rev is from before file existed + if rev < first: # current rev is from before file existed raise frev = numrevs - 1 while fl.linkrev(frev) > rev: @@ -1058,14 +1119,17 @@ lessvars['descend'] = morevars['descend'] = web.req.qsparams['descend'] count = fctx.filerev() + 1 - start = max(0, count - revcount) # first rev on this page - end = min(count, start + revcount) # last rev on this page + start = max(0, count - revcount) # first rev on this page + end = min(count, start + revcount) # last rev on this page parity = paritygen(web.stripecount, offset=start - end) repo = web.repo filelog = fctx.filelog() - revs = [filerev for filerev in filelog.revs(start, end - 1) - if filelog.linkrev(filerev) in repo] + revs = [ + filerev + for filerev in filelog.revs(start, end - 1) + if filelog.linkrev(filerev) in repo + ] entries = [] diffstyle = web.config('web', 'style') @@ -1076,9 +1140,15 @@ ctx = fctx.changectx() basectx = ctx.p1() path = fctx.path() - return webutil.diffs(web, ctx, basectx, [path], diffstyle, - linerange=linerange, - lineidprefix='%s-' % ctx.hex()[:12]) + return webutil.diffs( + web, + ctx, + basectx, + [path], + diffstyle, + linerange=linerange, + lineidprefix='%s-' % ctx.hex()[:12], + ) linerange = None if lrange is not None: @@ -1097,14 +1167,16 @@ # follow renames accross filtered (not in range) revisions path = c.path() lm = webutil.commonentry(repo, c) - lm.update({ - 'parity': next(parity), - 'filerev': c.rev(), - 'file': path, - 'diff': diffs, - 'linerange': webutil.formatlinerange(*lr), - 'rename': templateutil.mappinglist([]), - }) + lm.update( + { + 'parity': next(parity), + 'filerev': c.rev(), + 'file': path, + 'diff': diffs, + 'linerange': webutil.formatlinerange(*lr), + 'rename': templateutil.mappinglist([]), + } + ) entries.append(lm) if i == revcount: break @@ -1117,13 +1189,15 @@ if patch: diffs = diff(iterfctx) lm = webutil.commonentry(repo, iterfctx) - lm.update({ - 'parity': next(parity), - 'filerev': i, - 'file': f, - 'diff': diffs, - 'rename': webutil.renamelink(iterfctx), - }) + lm.update( + { + 'parity': next(parity), + 'filerev': i, + 'file': f, + 'diff': diffs, + 'rename': webutil.renamelink(iterfctx), + } + ) entries.append(lm) entries.reverse() revnav = webutil.filerevnav(web.repo, fctx.path()) @@ -1144,7 +1218,9 @@ revcount=revcount, morevars=morevars, lessvars=lessvars, - **pycompat.strkwargs(webutil.commonentry(web.repo, fctx))) + **pycompat.strkwargs(webutil.commonentry(web.repo, fctx)) + ) + @webcommand('archive') def archive(web): @@ -1175,8 +1251,7 @@ msg = 'Unsupported archive type: %s' % stringutil.pprint(type_) raise ErrorResponse(HTTP_NOT_FOUND, msg) - if not ((type_ in allowed or - web.configbool("web", "allow" + type_))): + if not ((type_ in allowed or web.configbool("web", "allow" + type_))): msg = 'Archive type not allowed: %s' % type_ raise ErrorResponse(HTTP_FORBIDDEN, msg) @@ -1197,30 +1272,42 @@ if pats: files = [f for f in ctx.manifest().keys() if match(f)] if not files: - raise ErrorResponse(HTTP_NOT_FOUND, - 'file(s) not found: %s' % file) + raise ErrorResponse( + HTTP_NOT_FOUND, 'file(s) not found: %s' % file + ) mimetype, artype, extension, encoding = webutil.archivespecs[type_] web.res.headers['Content-Type'] = mimetype web.res.headers['Content-Disposition'] = 'attachment; filename=%s%s' % ( - name, extension) + name, + extension, + ) if encoding: web.res.headers['Content-Encoding'] = encoding web.res.setbodywillwrite() if list(web.res.sendresponse()): - raise error.ProgrammingError('sendresponse() should not emit data ' - 'if writing later') + raise error.ProgrammingError( + 'sendresponse() should not emit data ' 'if writing later' + ) bodyfh = web.res.getbodyfile() - archival.archive(web.repo, bodyfh, cnode, artype, prefix=name, match=match, - subrepos=web.configbool("web", "archivesubrepos")) + archival.archive( + web.repo, + bodyfh, + cnode, + artype, + prefix=name, + match=match, + subrepos=web.configbool("web", "archivesubrepos"), + ) return [] + @webcommand('static') def static(web): fname = web.req.qsparams['file'] @@ -1236,6 +1323,7 @@ staticfile(static, fname, web.res) return web.res.sendresponse() + @webcommand('graph') def graph(web): """ @@ -1316,8 +1404,11 @@ # since hgweb graphing code is not itself lazy yet. dag = graphmod.dagwalker(web.repo, smartset.baseset(revs)) # As we said one line above... not lazy. - tree = list(item for item in graphmod.colored(dag, web.repo) - if item[1] == graphmod.CHANGESET) + tree = list( + item + for item in graphmod.colored(dag, web.repo) + if item[1] == graphmod.CHANGESET + ) def fulltree(): pos = web.repo[graphtop].rev() @@ -1325,34 +1416,47 @@ if pos != -1: revs = web.repo.changelog.revs(pos, lastrev) dag = graphmod.dagwalker(web.repo, smartset.baseset(revs)) - tree = list(item for item in graphmod.colored(dag, web.repo) - if item[1] == graphmod.CHANGESET) + tree = list( + item + for item in graphmod.colored(dag, web.repo) + if item[1] == graphmod.CHANGESET + ) return tree def jsdata(context): for (id, type, ctx, vtx, edges) in fulltree(): - yield {'node': pycompat.bytestr(ctx), - 'graphnode': webutil.getgraphnode(web.repo, ctx), - 'vertex': vtx, - 'edges': edges} + yield { + 'node': pycompat.bytestr(ctx), + 'graphnode': webutil.getgraphnode(web.repo, ctx), + 'vertex': vtx, + 'edges': edges, + } def nodes(context): parity = paritygen(web.stripecount) for row, (id, type, ctx, vtx, edges) in enumerate(tree): entry = webutil.commonentry(web.repo, ctx) - edgedata = [{'col': edge[0], - 'nextcol': edge[1], - 'color': (edge[2] - 1) % 6 + 1, - 'width': edge[3], - 'bcolor': edge[4]} - for edge in edges] + edgedata = [ + { + 'col': edge[0], + 'nextcol': edge[1], + 'color': (edge[2] - 1) % 6 + 1, + 'width': edge[3], + 'bcolor': edge[4], + } + for edge in edges + ] - entry.update({'col': vtx[0], - 'color': (vtx[1] - 1) % 6 + 1, - 'parity': next(parity), - 'edges': templateutil.mappinglist(edgedata), - 'row': row, - 'nextrow': row + 1}) + entry.update( + { + 'col': vtx[0], + 'color': (vtx[1] - 1) % 6 + 1, + 'parity': next(parity), + 'edges': templateutil.mappinglist(edgedata), + 'row': row, + 'nextrow': row + 1, + } + ) yield entry @@ -1376,7 +1480,9 @@ nodes=templateutil.mappinggenerator(nodes), node=ctx.hex(), archives=web.archivelist('tip'), - changenav=changenav) + changenav=changenav, + ) + def _getdoc(e): doc = e[0].__doc__ @@ -1386,6 +1492,7 @@ doc = _('(no help text available)') return doc + @webcommand('help') def help(web): """ @@ -1405,6 +1512,7 @@ topicname = web.req.qsparams.get('node') if not topicname: + def topics(context): for h in helpmod.helptable: entries, summary, _doc = h[0:3] @@ -1438,23 +1546,27 @@ topics=templateutil.mappinggenerator(topics), earlycommands=templateutil.mappinggenerator(earlycommands), othercommands=templateutil.mappinggenerator(othercommands), - title='Index') + title='Index', + ) # Render an index of sub-topics. if topicname in helpmod.subtopics: topics = [] for entries, summary, _doc in helpmod.subtopics[topicname]: - topics.append({ - 'topic': '%s.%s' % (topicname, entries[0]), - 'basename': entries[0], - 'summary': summary, - }) + topics.append( + { + 'topic': '%s.%s' % (topicname, entries[0]), + 'basename': entries[0], + 'summary': summary, + } + ) return web.sendtemplate( 'helptopics', topics=templateutil.mappinglist(topics), title=topicname, - subindex=True) + subindex=True, + ) u = webutil.wsgiui.load() u.verbose = True @@ -1475,10 +1587,8 @@ except error.Abort: raise ErrorResponse(HTTP_NOT_FOUND) - return web.sendtemplate( - 'help', - topic=topicname, - doc=doc) + return web.sendtemplate('help', topic=topicname, doc=doc) + # tell hggettext to extract docstrings from these functions: i18nfunctions = commands.values()