Patchwork [1,of,5] summary: augment output with info from extensions

login
register
mail settings
Submitter Bryan O'Sullivan
Date May 14, 2013, 6:24 p.m.
Message ID <50703ffc65cfec6e37f3.1368555867@australite.thefacebook.com>
Download mbox | patch
Permalink /patch/1636/
State Accepted
Commit 3bfd7f1e7485d81477a52be101c52c94601132d1
Headers show

Comments

Bryan O'Sullivan - May 14, 2013, 6:24 p.m.
# HG changeset patch
# User Bryan O'Sullivan <bryano@fb.com>
# Date 1368555795 25200
#      Tue May 14 11:23:15 2013 -0700
# Node ID 50703ffc65cfec6e37f31c74da5e2acf22c9ac08
# Parent  d77922fd8798acbf6daa0435eb7a7b1c13e3918b
summary: augment output with info from extensions
Bryan O'Sullivan - May 14, 2013, 9:58 p.m.
On Tue, May 14, 2013 at 12:18 PM, Kevin Bullock <
kbullock+mercurial@ringworld.org> wrote:

> Sure looks like it should be in its own patch.
>

I respectfully disagree in this case. I'm all for keeping patches small and
simple, but not to the extent that it becomes self-defeating by breaking up
a very small change even further.


> Also, the name 'hooks' is misleading, since it's apparently unrelated to
> the existing pre/post-operation user-configured hooks.
>

I thought about using "callback" instead, but I didn't like that, because
it suggests that it's important that there be a callback present.

I used the term "hook" because this use has been common parlance for
several decades. I also thought about "observer", but that invokes too much
Java stupidity for me to be comfortable. Naming things is hard!

Patch

diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py
--- a/mercurial/cmdutil.py
+++ b/mercurial/cmdutil.py
@@ -2082,3 +2082,6 @@  def command(table):
         return decorator
 
     return cmd
+
+# a list of (ui, repo) functions called by commands.summary
+summaryhooks = util.hooks()
diff --git a/mercurial/commands.py b/mercurial/commands.py
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -5485,6 +5485,8 @@  def summary(ui, repo, **opts):
         ui.write(_('update: %d new changesets, %d branch heads (merge)\n') %
                  (new, len(bheads)))
 
+    cmdutil.summaryhooks(ui, repo)
+
     if opts.get('remote'):
         t = []
         source, branches = hg.parseurl(ui.expandpath('default'))
diff --git a/mercurial/util.py b/mercurial/util.py
--- a/mercurial/util.py
+++ b/mercurial/util.py
@@ -1946,3 +1946,19 @@  def sizetoint(s):
         return int(t)
     except ValueError:
         raise error.ParseError(_("couldn't parse size: %s") % s)
+
+class hooks(object):
+    '''A collection of hook functions that can be used to extend a
+    function's behaviour. Hooks are called in lexicographic order,
+    based on the names of their sources.'''
+
+    def __init__(self):
+        self._hooks = []
+
+    def add(self, source, hook):
+        self._hooks.append((source, hook))
+
+    def __call__(self, *args):
+        self._hooks.sort(key=lambda x: x[0])
+        for source, hook in self._hooks:
+            hook(*args)