1
# Copyright (C) 2007-2011 Canonical Ltd
1
# Copyright (C) 2007-2010 Canonical Ltd
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
73
72
('bzrlib.branch', 'Branch.hooks', 'BranchHooks'),
74
73
('bzrlib.bzrdir', 'BzrDir.hooks', 'BzrDirHooks'),
75
74
('bzrlib.commands', 'Command.hooks', 'CommandHooks'),
76
('bzrlib.config', 'ConfigHooks', '_ConfigHooks'),
77
75
('bzrlib.info', 'hooks', 'InfoHooks'),
78
76
('bzrlib.lock', 'Lock.hooks', 'LockHooks'),
79
77
('bzrlib.merge', 'Merger.hooks', 'MergeHooks'),
117
115
FOO hook is triggered.
120
def __init__(self, module=None, member_name=None):
121
"""Create a new hooks dictionary.
123
:param module: The module from which this hooks dictionary should be loaded
124
(used for lazy hooks)
125
:param member_name: Name under which this hooks dictionary should be loaded.
126
(used for lazy hooks)
128
119
dict.__init__(self)
129
120
self._callable_names = {}
130
self._module = module
131
self._member_name = member_name
133
def add_hook(self, name, doc, introduced, deprecated=None):
134
"""Add a hook point to this dictionary.
136
:param name: The name of the hook, for clients to use when registering.
137
:param doc: The docs for the hook.
138
:param introduced: When the hook was introduced (e.g. (0, 15)).
139
:param deprecated: When the hook was deprecated, None for
143
raise errors.DuplicateKey(name)
145
callbacks = _lazy_hooks.setdefault(
146
(self._module, self._member_name, name), [])
149
hookpoint = HookPoint(name=name, doc=doc, introduced=introduced,
150
deprecated=deprecated, callbacks=callbacks)
151
self[name] = hookpoint
153
@symbol_versioning.deprecated_method(symbol_versioning.deprecated_in((2, 4)))
154
122
def create_hook(self, hook):
155
123
"""Create a hook which can have callbacks registered for it.
199
167
return self._callable_names.get(a_callable, "No hook name")
201
def install_named_hook_lazy(self, hook_name, callable_module,
202
callable_member, name):
203
"""Install a_callable in to the hook hook_name lazily, and label it.
205
:param hook_name: A hook name. See the __init__ method for the complete
207
:param callable_module: Name of the module in which the callable is
209
:param callable_member: Member name of the callable.
210
:param name: A name to associate the callable with, to show users what
214
hook = self[hook_name]
216
raise errors.UnknownHook(self.__class__.__name__, hook_name)
218
hook_lazy = getattr(hook, "hook_lazy")
219
except AttributeError:
220
raise errors.UnsupportedOperation(self.install_named_hook_lazy,
223
hook_lazy(callable_module, callable_member, name)
225
169
def install_named_hook(self, hook_name, a_callable, name):
226
170
"""Install a_callable in to the hook hook_name, and label it name.
228
:param hook_name: A hook name. See the __init__ method for the complete
172
:param hook_name: A hook name. See the __init__ method of BranchHooks
173
for the complete list of hooks.
230
174
:param a_callable: The callable to be invoked when the hook triggers.
231
175
The exact signature will depend on the hook - see the __init__
232
method for details on each hook.
176
method of BranchHooks for details on each hook.
233
177
:param name: A name to associate a_callable with, to show users what is
245
189
if name is not None:
246
190
self.name_hook(a_callable, name)
248
def uninstall_named_hook(self, hook_name, label):
249
"""Uninstall named hooks.
251
:param hook_name: Hook point name
252
:param label: Label of the callable to uninstall
255
hook = self[hook_name]
257
raise errors.UnknownHook(self.__class__.__name__, hook_name)
259
uninstall = getattr(hook, "uninstall")
260
except AttributeError:
261
raise errors.UnsupportedOperation(self.uninstall_named_hook, self)
265
192
def name_hook(self, a_callable, name):
266
193
"""Associate name with a_callable to show users what is running."""
267
194
self._callable_names[a_callable] = name
280
207
should describe the recommended replacement hook to register for.
283
def __init__(self, name, doc, introduced, deprecated=None, callbacks=None):
210
def __init__(self, name, doc, introduced, deprecated):
284
211
"""Create a HookPoint.
286
213
:param name: The name of the hook, for clients to use when registering.
293
220
self.__doc__ = doc
294
221
self.introduced = introduced
295
222
self.deprecated = deprecated
296
if callbacks is None:
299
self._callbacks = callbacks
224
self._callback_names = {}
302
227
"""Generate the documentation for this HookPoint.
311
236
introduced_string = _format_version_tuple(self.introduced)
313
238
introduced_string = 'unknown'
314
strings.append(gettext('Introduced in: %s') % introduced_string)
239
strings.append('Introduced in: %s' % introduced_string)
315
240
if self.deprecated:
316
241
deprecated_string = _format_version_tuple(self.deprecated)
317
strings.append(gettext('Deprecated in: %s') % deprecated_string)
242
strings.append('Deprecated in: %s' % deprecated_string)
318
243
strings.append('')
319
244
strings.extend(textwrap.wrap(self.__doc__,
320
245
break_long_words=False))
322
247
return '\n'.join(strings)
324
249
def __eq__(self, other):
325
return (type(other) == type(self) and other.__dict__ == self.__dict__)
327
def hook_lazy(self, callback_module, callback_member, callback_label):
328
"""Lazily register a callback to be called when this HookPoint fires.
330
:param callback_module: Module of the callable to use when this
332
:param callback_member: Member name of the callback.
333
:param callback_label: A label to show in the UI while this callback is
336
obj_getter = registry._LazyObjectGetter(callback_module,
338
self._callbacks.append((obj_getter, callback_label))
250
return (type(other) == type(self) and
251
other.__dict__ == self.__dict__)
340
253
def hook(self, callback, callback_label):
341
254
"""Register a callback to be called when this HookPoint fires.
344
257
:param callback_label: A label to show in the UI while this callback is
347
obj_getter = registry._ObjectGetter(callback)
348
self._callbacks.append((obj_getter, callback_label))
350
def uninstall(self, label):
351
"""Uninstall the callback with the specified label.
353
:param label: Label of the entry to uninstall
355
entries_to_remove = []
356
for entry in self._callbacks:
357
(entry_callback, entry_label) = entry
358
if entry_label == label:
359
entries_to_remove.append(entry)
360
if entries_to_remove == []:
361
raise KeyError("No entry with label %r" % label)
362
for entry in entries_to_remove:
363
self._callbacks.remove(entry)
260
self._callbacks.append(callback)
261
if callback_label is not None:
262
self._callback_names[callback] = callback_label
365
264
def __iter__(self):
366
return (callback.get_obj() for callback, name in self._callbacks)
265
return iter(self._callbacks)
368
267
def __len__(self):
369
268
return len(self._callbacks)
373
272
strings.append("<%s(" % type(self).__name__)
374
273
strings.append(self.name)
375
274
strings.append("), callbacks=[")
376
callbacks = self._callbacks
377
for (callback, callback_name) in callbacks:
378
strings.append(repr(callback.get_obj()))
275
for callback in self._callbacks:
276
strings.append(repr(callback))
379
277
strings.append("(")
380
strings.append(callback_name)
278
strings.append(self._callback_names[callback])
381
279
strings.append("),")
382
if len(callbacks) == 1:
280
if len(self._callbacks) == 1:
383
281
strings[-1] = ")"
384
282
strings.append("]>")
385
283
return ''.join(strings)
424
322
hooks = known_hooks_key_to_object(hook_key)
425
323
segments.append(hooks.docs())
426
324
return '\n'.join(segments)
429
# Lazily registered hooks. Maps (module, name, hook_name) tuples
430
# to lists of tuples with objectgetters and names
434
def install_lazy_named_hook(hookpoints_module, hookpoints_name, hook_name,
436
"""Install a callable in to a hook lazily, and label it name.
438
:param hookpoints_module: Module name of the hook points.
439
:param hookpoints_name: Name of the hook points.
440
:param hook_name: A hook name.
441
:param callable: a callable to call for the hook.
442
:param name: A name to associate a_callable with, to show users what is
445
key = (hookpoints_module, hookpoints_name, hook_name)
446
obj_getter = registry._ObjectGetter(a_callable)
447
_lazy_hooks.setdefault(key, []).append((obj_getter, name))