[PATCH] hgweb: extract changeset template mapping generation to own function

Gregory Szorc gregory.szorc at gmail.com
Mon Mar 2 23:07:32 UTC 2015


# HG changeset patch
# User Gregory Szorc <gregory.szorc at gmail.com>
# Date 1425337638 28800
#      Mon Mar 02 15:07:18 2015 -0800
# Node ID fcf16ed2c44e18f31f73a47b6e8c4fdf14ea4bbe
# Parent  4e865115566e75f938cbff9dcf081da39008a161
hgweb: extract changeset template mapping generation to own function

Similar in spirit to 513d47905114, I want to write an extension to
make available extra template keywords so hgweb templates can include
extra data.

To do this today requires monkeypatching the templater, which I think is
the wrong place to perform this modification.

This patch extracts the creation of the templater arguments to a
standalone function - one that can be monkeypatched by extensions.

I would very much like for extensions to be able to inject extra
templater parameters into *any* template. However, I'm not sure the best
way to facilitate this, as hgweb commands invoke the templater before
returning and we want the extensions to have access to rich data
structures like the context instances. We need cooperation inside hgweb
command functions. The use case screams for something like internal-only
"hooks." This is exactly what my (rejected) "events" patch series
provided. Perhaps that feature should be reconsidered...

diff --git a/mercurial/hgweb/webcommands.py b/mercurial/hgweb/webcommands.py
--- a/mercurial/hgweb/webcommands.py
+++ b/mercurial/hgweb/webcommands.py
@@ -430,58 +430,10 @@ def changeset(web, req, tmpl):
     ``changesetbookmark``, ``filenodelink``, ``filenolink``, and the many
     templates related to diffs may all be used to produce the output.
     """
     ctx = webutil.changectx(web.repo, req)
-    basectx = webutil.basechangectx(web.repo, req)
-    if basectx is None:
-        basectx = ctx.p1()
-    showtags = webutil.showtag(web.repo, tmpl, 'changesettag', ctx.node())
-    showbookmarks = webutil.showbookmark(web.repo, tmpl, 'changesetbookmark',
-                                         ctx.node())
-    showbranch = webutil.nodebranchnodefault(ctx)
 
-    files = []
-    parity = paritygen(web.stripecount)
-    for blockno, f in enumerate(ctx.files()):
-        template = f in ctx and 'filenodelink' or 'filenolink'
-        files.append(tmpl(template,
-                          node=ctx.hex(), file=f, blockno=blockno + 1,
-                          parity=parity.next()))
-
-    style = web.config('web', 'style', 'paper')
-    if 'style' in req.form:
-        style = req.form['style'][0]
-
-    parity = paritygen(web.stripecount)
-    diffs = webutil.diffs(web.repo, tmpl, ctx, basectx, None, parity, style)
-
-    parity = paritygen(web.stripecount)
-    diffstatgen = webutil.diffstatgen(ctx, basectx)
-    diffstat = webutil.diffstat(tmpl, ctx, diffstatgen, parity)
-
-    return tmpl('changeset',
-                diff=diffs,
-                rev=ctx.rev(),
-                node=ctx.hex(),
-                parent=tuple(webutil.parents(ctx)),
-                child=webutil.children(ctx),
-                basenode=basectx.hex(),
-                changesettag=showtags,
-                changesetbookmark=showbookmarks,
-                changesetbranch=showbranch,
-                author=ctx.user(),
-                desc=ctx.description(),
-                extra=ctx.extra(),
-                date=ctx.date(),
-                files=files,
-                diffsummary=lambda **x: webutil.diffsummary(diffstatgen),
-                diffstat=diffstat,
-                archives=web.archivelist(ctx.hex()),
-                tags=webutil.nodetagsdict(web.repo, ctx.node()),
-                bookmarks=webutil.nodebookmarksdict(web.repo, ctx.node()),
-                branch=webutil.nodebranchnodefault(ctx),
-                inbranch=webutil.nodeinbranch(web.repo, ctx),
-                branches=webutil.nodebranchdict(web.repo, ctx))
+    return tmpl('changeset', **webutil.changesetentry(web, req, tmpl, ctx))
 
 rev = webcommand('rev')(changeset)
 
 def decodepath(path):
diff --git a/mercurial/hgweb/webutil.py b/mercurial/hgweb/webutil.py
--- a/mercurial/hgweb/webutil.py
+++ b/mercurial/hgweb/webutil.py
@@ -9,9 +9,9 @@
 import os, copy
 from mercurial import match, patch, error, ui, util, pathutil, context
 from mercurial.i18n import _
 from mercurial.node import hex, nullid
-from common import ErrorResponse
+from common import ErrorResponse, paritygen
 from common import HTTP_NOT_FOUND
 import difflib
 
 def up(p):
@@ -278,8 +278,63 @@ def changelistentry(web, ctx, tmpl):
         "inbranch": nodeinbranch(repo, ctx),
         "branches": nodebranchdict(repo, ctx)
     }
 
+def changesetentry(web, req, tmpl, ctx):
+    '''Obtain a dictionary to be used to render the "changeset" template.'''
+
+    showtags = showtag(web.repo, tmpl, 'changesettag', ctx.node())
+    showbookmarks = showbookmark(web.repo, tmpl, 'changesetbookmark',
+                                 ctx.node())
+    showbranch = nodebranchnodefault(ctx)
+
+    files = []
+    parity = paritygen(web.stripecount)
+    for blockno, f in enumerate(ctx.files()):
+        template = f in ctx and 'filenodelink' or 'filenolink'
+        files.append(tmpl(template,
+                          node=ctx.hex(), file=f, blockno=blockno + 1,
+                          parity=parity.next()))
+
+    basectx = basechangectx(web.repo, req)
+    if basectx is None:
+        basectx = ctx.p1()
+
+    style = web.config('web', 'style', 'paper')
+    if 'style' in req.form:
+        style = req.form['style'][0]
+
+    parity = paritygen(web.stripecount)
+    diff = diffs(web.repo, tmpl, ctx, basectx, None, parity, style)
+
+    parity = paritygen(web.stripecount)
+    diffstatsgen = diffstatgen(ctx, basectx)
+    diffstats = diffstat(tmpl, ctx, diffstatsgen, parity)
+
+    return dict(
+        diff=diff,
+        rev=ctx.rev(),
+        node=ctx.hex(),
+        parent=tuple(parents(ctx)),
+        child=children(ctx),
+        basenode=basectx.hex(),
+        changesettag=showtags,
+        changesetbookmark=showbookmarks,
+        changesetbranch=showbranch,
+        author=ctx.user(),
+        desc=ctx.description(),
+        extra=ctx.extra(),
+        date=ctx.date(),
+        files=files,
+        diffsummary=lambda **x: diffsummary(diffstatsgen),
+        diffstat=diffstats,
+        archives=web.archivelist(ctx.hex()),
+        tags=nodetagsdict(web.repo, ctx.node()),
+        bookmarks=nodebookmarksdict(web.repo, ctx.node()),
+        branch=nodebranchnodefault(ctx),
+        inbranch=nodeinbranch(web.repo, ctx),
+        branches=nodebranchdict(web.repo, ctx))
+
 def listfilediffs(tmpl, files, node, max):
     for f in files[:max]:
         yield tmpl('filedifflink', node=hex(node), file=f)
     if len(files) > max:


More information about the Mercurial-devel mailing list