Rev 5789: Add hooks for config stacks. in file:///home/vila/src/bzr/experimental/config/
Vincent Ladeuil
v.ladeuil+lp at free.fr
Wed Jun 8 16:29:36 UTC 2011
At file:///home/vila/src/bzr/experimental/config/
------------------------------------------------------------
revno: 5789
revision-id: v.ladeuil+lp at free.fr-20110608162936-nglond8qgcsvyth0
parent: v.ladeuil+lp at free.fr-20110608095148-r0rvo0qvvoebxesu
committer: Vincent Ladeuil <v.ladeuil+lp at free.fr>
branch nick: config-test-stats
timestamp: Wed 2011-06-08 18:29:36 +0200
message:
Add hooks for config stacks.
-------------- next part --------------
=== modified file 'bzrlib/config.py'
--- a/bzrlib/config.py 2011-06-01 12:31:04 +0000
+++ b/bzrlib/config.py 2011-06-08 16:29:36 +0000
@@ -65,9 +65,8 @@
import os
import string
import sys
-import weakref
-
-from bzrlib import commands
+
+
from bzrlib.decorators import needs_write_lock
from bzrlib.lazy_import import lazy_import
lazy_import(globals(), """
@@ -95,6 +94,8 @@
from bzrlib.util.configobj import configobj
""")
from bzrlib import (
+ commands,
+ hooks,
registry,
)
from bzrlib.symbol_versioning import (
@@ -159,7 +160,7 @@
return self[section][name]
-# FIXME: Until we can guarantee that each config file is loaded once and and
+# FIXME: Until we can guarantee that each config file is loaded once and
# only once for a given bzrlib session, we don't want to re-read the file every
# time we query for an option so we cache the value (bad ! watch out for tests
# needing to restore the proper value).This shouldn't be part of 2.4.0 final,
@@ -2587,6 +2588,8 @@
opt = None
if opt is not None:
value = opt.get_default()
+ for hook in Stack.hooks['get']:
+ hook(self, name, value)
return value
def _get_mutable_section(self):
@@ -2604,17 +2607,49 @@
"""Set a new value for the option."""
section = self._get_mutable_section()
section.set(name, value)
+ for hook in Stack.hooks['set']:
+ hook(self, name, value)
def remove(self, name):
"""Remove an existing option."""
section = self._get_mutable_section()
section.remove(name)
+ for hook in Stack.hooks['remove']:
+ hook(self, name)
def __repr__(self):
# Mostly for debugging use
return "<config.%s(%s)>" % (self.__class__.__name__, id(self))
+class StackHooks(hooks.Hooks):
+ """A dict mapping hook names and a list of callables for config stacks.
+ """
+
+ def __init__(self):
+ """Create the default hooks.
+
+ These are all empty initially, because by default nothing should get
+ notified.
+ """
+ super(StackHooks, self).__init__('bzrlib.config', 'Stack.hooks')
+ self.add_hook('get',
+ 'Invoked when a config option is read.'
+ ' The signature is (stack, name, value).',
+ (2, 4))
+ self.add_hook('set',
+ 'Invoked when a config option is set.'
+ ' The signature is (stack, name, value).',
+ (2, 4))
+ self.add_hook('remove',
+ 'Invoked when a config option is removed.'
+ ' The signature is (stack, name).',
+ (2, 4))
+
+# install the default hooks into the Stack class.
+Stack.hooks = StackHooks()
+
+
class _CompatibleStack(Stack):
"""Place holder for compatibility with previous design.
=== modified file 'bzrlib/hooks.py'
--- a/bzrlib/hooks.py 2011-04-07 10:36:24 +0000
+++ b/bzrlib/hooks.py 2011-06-08 16:29:36 +0000
@@ -72,6 +72,7 @@
('bzrlib.branch', 'Branch.hooks', 'BranchHooks'),
('bzrlib.bzrdir', 'BzrDir.hooks', 'BzrDirHooks'),
('bzrlib.commands', 'Command.hooks', 'CommandHooks'),
+ ('bzrlib.config', 'Stack.hooks', 'StackHooks'),
('bzrlib.info', 'hooks', 'InfoHooks'),
('bzrlib.lock', 'Lock.hooks', 'LockHooks'),
('bzrlib.merge', 'Merger.hooks', 'MergeHooks'),
=== modified file 'bzrlib/tests/test_config.py'
--- a/bzrlib/tests/test_config.py 2011-06-01 12:31:04 +0000
+++ b/bzrlib/tests/test_config.py 2011-06-08 16:29:36 +0000
@@ -2494,10 +2494,6 @@
conf_stack = config.Stack([conf1, conf2])
self.assertEquals('baz', conf_stack.get('foo'))
- def test_get_for_empty_stack(self):
- conf_stack = config.Stack([])
- self.assertEquals(None, conf_stack.get('foo'))
-
def test_get_for_empty_section_callable(self):
conf_stack = config.Stack([lambda : []])
self.assertEquals(None, conf_stack.get('foo'))
@@ -2521,6 +2517,26 @@
stack = self.get_stack(self)
+class TestStackGet(TestStackWithTransport):
+
+ def test_get_for_empty_stack(self):
+ conf = self.get_stack(self)
+ self.assertEquals(None, conf.get('foo'))
+
+ def test_get_hook(self):
+ calls = []
+ def hook(*args):
+ calls.append(args)
+ config.Stack.hooks.install_named_hook('get', hook, None)
+ self.assertLength(0, calls)
+ conf = self.get_stack(self)
+ conf.store._load_from_string('foo=bar')
+ value = conf.get('foo')
+ self.assertEquals('bar', value)
+ self.assertLength(1, calls)
+ self.assertEquals((conf, 'foo', 'bar'), calls[0])
+
+
class TestStackSet(TestStackWithTransport):
def test_simple_set(self):
@@ -2536,6 +2552,17 @@
conf.set('foo', 'baz')
self.assertEquals, 'baz', conf.get('foo')
+ def test_set_hook(self):
+ calls = []
+ def hook(*args):
+ calls.append(args)
+ config.Stack.hooks.install_named_hook('set', hook, None)
+ self.assertLength(0, calls)
+ conf = self.get_stack(self)
+ conf.set('foo', 'bar')
+ self.assertLength(1, calls)
+ self.assertEquals((conf, 'foo', 'bar'), calls[0])
+
class TestStackRemove(TestStackWithTransport):
@@ -2551,6 +2578,18 @@
conf = self.get_stack(self)
self.assertRaises(KeyError, conf.remove, 'I_do_not_exist')
+ def test_remove_hook(self):
+ calls = []
+ def hook(*args):
+ calls.append(args)
+ config.Stack.hooks.install_named_hook('remove', hook, None)
+ self.assertLength(0, calls)
+ conf = self.get_stack(self)
+ conf.store._load_from_string('foo=bar')
+ conf.remove('foo')
+ self.assertLength(1, calls)
+ self.assertEquals((conf, 'foo'), calls[0])
+
class TestConfigGetOptions(tests.TestCaseWithTransport, TestOptionsMixin):
=== modified file 'doc/en/release-notes/bzr-2.4.txt'
--- a/doc/en/release-notes/bzr-2.4.txt 2011-06-07 18:39:38 +0000
+++ b/doc/en/release-notes/bzr-2.4.txt 2011-06-08 16:29:36 +0000
@@ -20,9 +20,14 @@
.. New commands, options, etc that users may wish to try out.
+* Hooks added for config stacks: ``get``, ``set`` and ``remove`` are called
+ when an option is repsectively read, modified or deleted.
+ (Vincent Ladeuil)
+
* New hook server_exception in bzrlib.smart.server to catch any
- exception caused while running bzr serve. (Jonathan Riddell,
- #274578)
+ exception caused while running bzr serve.
+ (Jonathan Riddell, #274578)
+
Improvements
************
More information about the bazaar-commits
mailing list