hgmo: refactor filelog entries modification (
bug 1360007); r?glob
We have a custom wrapper function for the "filelog" web command that
adds pushlog info. This was added in 3ac7f2de1e6b.
The previous implementation was a bit fragile in that it relied
on implementation details of the templater too much. We constructed a
fake templater class and passed it into the original function. Then,
we inspected the arguments passed to __call__, modified them in place,
then called the original templater with those arguments.
Something - I'm not sure what - broke in 4.2. This commit refactors
the code to instead create a new proxy class for the templater that
intercepts __call__ and does modification there. This fixes whatever
the problem was with 4.2.
While we could probably leave the .__class__ monkeypatched, it is
restored out of paranoia.
MozReview-Commit-ID: 5qugurPWzOh
--- a/hgext/hgmo/__init__.py
+++ b/hgext/hgmo/__init__.py
@@ -708,42 +708,40 @@ def processbundlesmanifest(orig, repo, p
except Exception as e:
repo.ui.log('hgmo', 'exception filtering bundle source IPs: %s\n', e)
return manifest
def filelog(orig, web, req, tmpl):
"""Wraps webcommands.filelog to provide pushlog metadata to template."""
-
- if hasattr(web.repo, 'pushlog'):
-
- class _tmpl(object):
-
- def __init__(self):
- self.defaults = tmpl.defaults
-
- def __call__(self, *args, **kwargs):
- self.args = args
- self.kwargs = kwargs
- return self
+ # Template wrapper to add pushlog data to entries when the template is
+ # evaluated.
+ class tmplwrapper(tmpl.__class__):
+ def __call__(self, *args, **kwargs):
+ for entry in kwargs.get('entries', []):
+ push = web.repo.pushlog.pushfromnode(bin(entry['node']))
+ if push:
+ entry['pushid'] = push.pushid
+ entry['pushdate'] = util.makedate(push.when)
+ else:
+ entry['pushid'] = None
+ entry['pushdate'] = None
- t = orig(web, req, _tmpl())
- for entry in t.kwargs['entries']:
- push = web.repo.pushlog.pushfromnode(bin(entry['node']))
- if push:
- entry['pushid'] = push.pushid
- entry['pushdate'] = util.makedate(push.when)
- else:
- entry['pushid'] = None
- entry['pushdate'] = None
+ return super(tmplwrapper, self).__call__(*args, **kwargs)
- return tmpl(*t.args, **t.kwargs)
- else:
- return orig(web, req, tmpl)
+ orig_class = tmpl.__class__
+ try:
+ if hasattr(web.repo, 'pushlog'):
+ tmpl.__class__ = tmplwrapper
+
+ for r in orig(web, req, tmpl):
+ yield r
+ finally:
+ tmpl.__class__ = orig_class
def extsetup(ui):
extensions.wrapfunction(exchange, 'pull', pull)
extensions.wrapfunction(webutil, 'changesetentry', changesetentry)
extensions.wrapfunction(webutil, 'changelistentry', changelistentry)
extensions.wrapfunction(bookmarks, 'updatefromremote', bmupdatefromremote)
extensions.wrapfunction(webcommands, 'filelog', filelog)