Patchwork hgweb: extract changeset template mapping generation to own function

login
register
mail settings
Submitter Gregory Szorc
Date March 2, 2015, 11:07 p.m.
Message ID <fcf16ed2c44e18f31f73.1425337652@gps-mbp.local>
Download mbox | patch
Permalink /patch/7881/
State Accepted
Commit f53b7174facfa26af24f61fa1142bcc701d37bc3
Headers show

Comments

Gregory Szorc - March 2, 2015, 11:07 p.m.
# HG changeset patch
# User Gregory Szorc <gregory.szorc@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...
Augie Fackler - March 3, 2015, 4:14 p.m.
On Mon, Mar 02, 2015 at 03:07:32PM -0800, Gregory Szorc wrote:
> # HG changeset patch
> # User Gregory Szorc <gregory.szorc@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

I'm a big fan, and I can see some really neat uses of this
(hgsubversion users might want to show the svn rev from extra, for
example). Queued.

>
> 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:
> _______________________________________________
> Mercurial-devel mailing list
> Mercurial-devel@selenic.com
> http://selenic.com/mailman/listinfo/mercurial-devel

Patch

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: