[PATCH 01 of 22 hgweb-help] webcommands: define web commands using a decorator
Gregory Szorc
gregory.szorc at gmail.com
Sat Feb 7 07:15:39 UTC 2015
# HG changeset patch
# User Gregory Szorc <gregory.szorc at gmail.com>
# Date 1423278377 28800
# Fri Feb 06 19:06:17 2015 -0800
# Node ID a54bf6a609310887f4fa824579b9db3e29b3e550
# Parent ff5caa8dfd993680d9602ca6ebb14da9de10d5f4
webcommands: define web commands using a decorator
Other parts of Mercurial have evolved to use decorators to declare
commands or handlers. This patch gives the same treatment to web
commands.
diff --git a/mercurial/hgweb/webcommands.py b/mercurial/hgweb/webcommands.py
--- a/mercurial/hgweb/webcommands.py
+++ b/mercurial/hgweb/webcommands.py
@@ -21,20 +21,38 @@ from mercurial import 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.
-__all__ = [
- 'log', 'rawfile', 'file', 'changelog', 'shortlog', 'changeset', 'rev',
- 'manifest', 'tags', 'bookmarks', 'branches', 'summary', 'filediff', 'diff',
- 'comparison', 'annotate', 'filelog', 'archive', 'static', 'graph', 'help',
-]
+__all__ = []
+class webcommand(object):
+ """Decorator used to register a web command handler.
+
+ The decorator takes as its positional arguments the name/path the
+ command should be accessible under.
+
+ Usage:
+
+ @webcommand('mycommand')
+ def mycommand(web, req, tmpl):
+ pass
+ """
+
+ def __init__(self, name):
+ self.name = name
+
+ def __call__(self, func):
+ __all__.append(self.name)
+ return func
+
+ at webcommand('log')
def log(web, req, tmpl):
if 'file' in req.form and req.form['file'][0]:
return filelog(web, req, tmpl)
else:
return changelog(web, req, tmpl)
+ at webcommand('rawfile')
def rawfile(web, req, tmpl):
guessmime = web.configbool('web', 'guessmime', False)
path = webutil.cleanpath(web.repo, req.form.get('file', [''])[0])
@@ -97,8 +115,9 @@ def _filerevision(web, tmpl, fctx):
child=webutil.children(fctx),
rename=webutil.renamelink(fctx),
permissions=fctx.manifest().flags(f))
+ at webcommand('file')
def file(web, req, tmpl):
path = webutil.cleanpath(web.repo, req.form.get('file', [''])[0])
if not path:
return manifest(web, req, tmpl)
@@ -266,8 +285,9 @@ def _search(web, req, tmpl):
morevars=morevars, lessvars=lessvars,
modedesc=searchfunc[1],
showforcekw=showforcekw, showunforcekw=showunforcekw)
+ at webcommand('changelog')
def changelog(web, req, tmpl, shortlog=False):
query = ''
if 'node' in req.form:
@@ -325,11 +345,13 @@ def changelog(web, req, tmpl, shortlog=F
latestentry=latestentry, nextentry=nextentry,
archives=web.archivelist("tip"), revcount=revcount,
morevars=morevars, lessvars=lessvars, query=query)
+ at webcommand('shortlog')
def shortlog(web, req, tmpl):
return changelog(web, req, tmpl, shortlog=True)
+ at webcommand('changeset')
def changeset(web, req, tmpl):
ctx = webutil.changectx(web.repo, req)
basectx = webutil.basechangectx(web.repo, req)
if basectx is None:
@@ -381,9 +403,9 @@ def changeset(web, req, tmpl):
branch=webutil.nodebranchnodefault(ctx),
inbranch=webutil.nodeinbranch(web.repo, ctx),
branches=webutil.nodebranchdict(web.repo, ctx))
-rev = changeset
+rev = webcommand('rev')(changeset)
def decodepath(path):
"""Hook for mapping a path in the repository to a path in the
working copy.
@@ -391,8 +413,9 @@ def decodepath(path):
Extensions (e.g., largefiles) can override this to remap files in
the virtual file system presented by the manifest command below."""
return path
+ at webcommand('manifest')
def manifest(web, req, tmpl):
ctx = webutil.changectx(web.repo, req)
path = webutil.cleanpath(web.repo, req.form.get('file', [''])[0])
mf = ctx.manifest()
@@ -473,8 +496,9 @@ def manifest(web, req, tmpl):
bookmarks=webutil.nodebookmarksdict(web.repo, node),
inbranch=webutil.nodeinbranch(web.repo, ctx),
branches=webutil.nodebranchdict(web.repo, ctx))
+ at webcommand('tags')
def tags(web, req, tmpl):
i = list(reversed(web.repo.tagslist()))
parity = paritygen(web.stripecount)
@@ -495,8 +519,9 @@ def tags(web, req, tmpl):
entries=lambda **x: entries(False, False, **x),
entriesnotip=lambda **x: entries(True, False, **x),
latestentry=lambda **x: entries(True, True, **x))
+ at webcommand('bookmarks')
def bookmarks(web, req, tmpl):
i = [b for b in web.repo._bookmarks.items() if b[1] in web.repo]
parity = paritygen(web.stripecount)
@@ -515,8 +540,9 @@ def bookmarks(web, req, tmpl):
node=hex(web.repo.changelog.tip()),
entries=lambda **x: entries(latestonly=False, **x),
latestentry=lambda **x: entries(latestonly=True, **x))
+ at webcommand('branches')
def branches(web, req, tmpl):
tips = []
heads = web.repo.heads()
parity = paritygen(web.stripecount)
@@ -546,8 +572,9 @@ def branches(web, req, tmpl):
return tmpl('branches', node=hex(web.repo.changelog.tip()),
entries=lambda **x: entries(0, **x),
latestentry=lambda **x: entries(1, **x))
+ at webcommand('summary')
def summary(web, req, tmpl):
i = reversed(web.repo.tagslist())
def tagentries(**map):
@@ -631,8 +658,9 @@ def summary(web, req, tmpl):
shortlog=changelist,
node=tip.hex(),
archives=web.archivelist("tip"))
+ at webcommand('filediff')
def filediff(web, req, tmpl):
fctx, ctx = None, None
try:
fctx = webutil.filectx(web.repo, req)
@@ -671,10 +699,11 @@ def filediff(web, req, tmpl):
parent=webutil.parents(ctx),
child=webutil.children(ctx),
diff=diffs)
-diff = filediff
+diff = webcommand('diff')(filediff)
+ at webcommand('comparison')
def comparison(web, req, tmpl):
ctx = webutil.changectx(web.repo, req)
if 'file' not in req.form:
raise ErrorResponse(HTTP_NOT_FOUND, 'file not given')
@@ -731,8 +760,9 @@ def comparison(web, req, tmpl):
rightrev=rightrev,
rightnode=hex(rightnode),
comparison=comparison)
+ at webcommand('annotate')
def annotate(web, req, tmpl):
fctx = webutil.filectx(web.repo, req)
f = fctx.path()
parity = paritygen(web.stripecount)
@@ -783,8 +813,9 @@ def annotate(web, req, tmpl):
parent=webutil.parents(fctx),
child=webutil.children(fctx),
permissions=fctx.manifest().flags(f))
+ at webcommand('filelog')
def filelog(web, req, tmpl):
try:
fctx = webutil.filectx(web.repo, req)
@@ -861,8 +892,9 @@ def filelog(web, req, tmpl):
entries=entries,
latestentry=latestentry,
revcount=revcount, morevars=morevars, lessvars=lessvars)
+ at webcommand('archive')
def archive(web, req, tmpl):
type_ = req.form.get('type', [None])[0]
allowed = web.configlist("web", "allow_archive")
key = req.form['node'][0]
@@ -910,8 +942,9 @@ def archive(web, req, tmpl):
subrepos=web.configbool("web", "archivesubrepos"))
return []
+ at webcommand('static')
def static(web, req, tmpl):
fname = req.form['file'][0]
# a repo owner may set web.static in .hg/hgrc to get any file
# readable by the user running the CGI script
@@ -923,8 +956,9 @@ def static(web, req, tmpl):
static = [os.path.join(p, 'static') for p in tp]
staticfile(static, fname, req)
return []
+ at webcommand('graph')
def graph(web, req, tmpl):
ctx = webutil.changectx(web.repo, req)
rev = ctx.rev()
@@ -1046,8 +1080,9 @@ def _getdoc(e):
else:
doc = _('(no help text available)')
return doc
+ at webcommand('help')
def help(web, req, tmpl):
from mercurial import commands # avoid cycle
topicname = req.form.get('node', [None])[0]
More information about the Mercurial-devel
mailing list