Rev 6127: Introduce a stack factory registry and use it instead of the *Stack classses (now deleted). in file:///home/vila/src/bzr/bugs/832036-stack-registry/
Vincent Ladeuil
v.ladeuil+lp at free.fr
Tue Sep 6 16:02:02 UTC 2011
At file:///home/vila/src/bzr/bugs/832036-stack-registry/
------------------------------------------------------------
revno: 6127
revision-id: v.ladeuil+lp at free.fr-20110906160201-9qss61wdp7rzykbl
parent: v.ladeuil+lp at free.fr-20110905160446-9aihwyfudsplk7xm
committer: Vincent Ladeuil <v.ladeuil+lp at free.fr>
branch nick: 832036-stack-registry
timestamp: Tue 2011-09-06 18:02:01 +0200
message:
Introduce a stack factory registry and use it instead of the *Stack classses (now deleted).
-------------- next part --------------
=== modified file 'bzrlib/bzrdir.py'
--- a/bzrlib/bzrdir.py 2011-08-17 09:27:29 +0000
+++ b/bzrlib/bzrdir.py 2011-09-06 16:02:01 +0000
@@ -2288,7 +2288,7 @@
help='Same as 2a.')
# The current format that is made on 'bzr init'.
-format_name = config.GlobalStack().get('default_format')
+format_name = config.stacks.get('bazaar')().get('default_format')
controldir.format_registry.set_default(format_name)
# XXX 2010-08-20 JRV: There is still a lot of code relying on
=== modified file 'bzrlib/config.py'
--- a/bzrlib/config.py 2011-09-05 16:04:46 +0000
+++ b/bzrlib/config.py 2011-09-06 16:02:01 +0000
@@ -414,7 +414,7 @@
# add) the final ','
l = [l]
return l
-
+
def get_user_option_as_int_from_SI(self, option_name, default=None):
"""Get a generic option from a human readable size in SI units, e.g 10MB
@@ -452,7 +452,6 @@
except TypeError:
val = default
return val
-
def gpg_signing_command(self):
"""What program should be used to sign signatures?"""
@@ -2454,8 +2453,7 @@
:param option: The option to register. Its name is used as the key.
"""
- super(OptionRegistry, self).register(option.name, option,
- help=option.help)
+ super(OptionRegistry, self).register(option.name, option)
def register_lazy(self, key, module_name, member_name):
"""Register a new option to be loaded on request.
@@ -3247,71 +3245,105 @@
self.store.save()
-class GlobalStack(_CompatibleStack):
- """Global options only stack."""
-
- def __init__(self):
- # Get a GlobalStore
- gstore = GlobalStore()
- super(GlobalStack, self).__init__([gstore.get_sections], gstore)
-
-
-class LocationStack(_CompatibleStack):
- """Per-location options falling back to global options stack."""
-
- def __init__(self, location):
- """Make a new stack for a location and global configuration.
-
- :param location: A URL prefix to """
- lstore = LocationStore()
- matcher = LocationMatcher(lstore, location)
- gstore = GlobalStore()
- super(LocationStack, self).__init__(
- [matcher.get_sections, gstore.get_sections], lstore)
-
-
-class BranchStack(_CompatibleStack):
- """Per-location options falling back to branch then global options stack."""
-
- def __init__(self, branch):
- bstore = BranchStore(branch)
- lstore = LocationStore()
- matcher = LocationMatcher(lstore, branch.base)
- gstore = GlobalStore()
- super(BranchStack, self).__init__(
- [matcher.get_sections, bstore.get_sections, gstore.get_sections],
- bstore)
- self.branch = branch
-
-
-class RemoteControlStack(_CompatibleStack):
- """Remote control-only options stack."""
-
- def __init__(self, bzrdir):
- cstore = ControlStore(bzrdir)
- super(RemoteControlStack, self).__init__(
+def global_stack():
+ """Create a stack for the global options."""
+ # Get a GlobalStore
+ gstore = GlobalStore()
+ stack = _CompatibleStack([gstore.get_sections], gstore)
+ return stack
+
+
+def location_stack(location):
+ """Create a stack for the options applying to a location.
+
+ This includes the matching sections from LocationStore and falls back to
+ the section in the GlobalStore.
+
+ :param location: A URL prefix to match sections from the LocationStore.
+ """
+ lstore = LocationStore()
+ matcher = LocationMatcher(lstore, location)
+ gstore = GlobalStore()
+ stack = _CompatibleStack([matcher.get_sections, gstore.get_sections],
+ lstore)
+ return stack
+
+
+def branch_stack(branch):
+ """Create a stack for the branch options.
+
+ This includes the section in the BranchStore, falls back the sections in
+ LocationStore (using the branch URL) and finally to the section in the
+ GlobalStore.
+
+ :param branch: The related branch object.
+ """
+ bstore = BranchStore(branch)
+ lstore = LocationStore()
+ matcher = LocationMatcher(lstore, branch.base)
+ gstore = GlobalStore()
+ stack = _CompatibleStack(
+ [matcher.get_sections, bstore.get_sections, gstore.get_sections],
+ bstore)
+ return stack
+
+# Neeed for 'default_stack_on location' which is the only option defined in
+# 'control.conf'. This stack is not yet used in bzrdir.py -- vila 2011-09-06
+def control_only_stack(bzrdir):
+ """Create a stack for the control options *only*.
+
+ This includes only the section in the ControlStore.
+
+ :param bzrdir: The related bzrdir object.
+ """
+ cstore = ControlStore(bzrdir)
+ stack = _CompatibleStack(
[cstore.get_sections],
cstore)
- self.bzrdir = bzrdir
-
-
-class RemoteBranchStack(_CompatibleStack):
- """Remote branch-only options stack."""
-
- def __init__(self, branch):
- bstore = BranchStore(branch)
- super(RemoteBranchStack, self).__init__(
+ return stack
+
+
+# Needed for 'stacked_on_location' only which use a hack that could be removed
+# when each config file is read only once. This stack is not yet used in
+# branch.py -- vila 2011-09-06
+def branch_only_stack(branch):
+ """Create a stack for the branch options *only*.
+
+ This includes only the section in the BranchStore.
+
+ :param branch: The related branch object.
+ """
+ bstore = BranchStore(branch)
+ stack = _CompatibleStack(
[bstore.get_sections],
bstore)
- self.branch = branch
-
-
-class _StackRegistry(registry.Registry):
+ return stack
+
+
+class StackRegistry(registry.Registry):
"""Registry of Stack factories.
This registry is queried for a given key and provides a factory that accept
a context and build the appropriate Stack for this context.
"""
+ def get_help(self, key=None):
+ """Get the help text associated with the given key"""
+ factory = self.get(key)
+ the_help = factory.__doc__
+ if callable(the_help):
+ return the_help(self, key)
+ return the_help
+
+
+stacks = StackRegistry()
+stacks.register('bazaar', global_stack)
+stacks.register('locations', location_stack)
+stacks.register('branch', branch_stack)
+
+# Not used yet, may change in the future, don't use -- vila 2011-09-06
+stacks.register('control-only', control_only_stack)
+stacks.register('branch-only', branch_only_stack)
+
class cmd_config(commands.Command):
__doc__ = """Display, set or remove a configuration option.
=== modified file 'bzrlib/debug.py'
--- a/bzrlib/debug.py 2011-08-20 07:49:15 +0000
+++ b/bzrlib/debug.py 2011-09-06 16:02:01 +0000
@@ -32,7 +32,7 @@
from bzrlib import config
- c = config.GlobalStack()
+ c = config.stacks.get('bazaar')()
for f in c.get('debug_flags'):
debug_flags.add(f)
=== modified file 'bzrlib/dirstate.py'
--- a/bzrlib/dirstate.py 2011-07-25 07:11:56 +0000
+++ b/bzrlib/dirstate.py 2011-09-06 16:02:01 +0000
@@ -450,12 +450,11 @@
self._known_hash_changes = set()
# How many hash changed entries can we have without saving
self._worth_saving_limit = worth_saving_limit
- self._config_stack = config.LocationStack(urlutils.local_path_to_url(
- path))
+ self._config_stack = config.stacks.get(
+ 'locations')(urlutils.local_path_to_url(path))
def __repr__(self):
- return "%s(%r)" % \
- (self.__class__.__name__, self._filename)
+ return "%s(%r)" % (self.__class__.__name__, self._filename)
def _mark_modified(self, hash_changed_entries=None, header_modified=False):
"""Mark this dirstate as modified.
=== modified file 'bzrlib/i18n.py'
--- a/bzrlib/i18n.py 2011-08-31 10:56:58 +0000
+++ b/bzrlib/i18n.py 2011-09-06 16:02:01 +0000
@@ -136,7 +136,7 @@
def _get_current_locale():
if not os.environ.get('LANGUAGE'):
from bzrlib import config
- lang = config.GlobalStack().get('language')
+ lang = config.stacks.get('bazaar')().get('language')
if lang:
os.environ['LANGUAGE'] = lang
return lang
=== modified file 'bzrlib/lockdir.py'
--- a/bzrlib/lockdir.py 2011-08-12 12:11:44 +0000
+++ b/bzrlib/lockdir.py 2011-09-06 16:02:01 +0000
@@ -708,7 +708,7 @@
# XXX: This really should also use the locationconfig at least, but
# that seems a bit hard to hook up at the moment. -- mbp 20110329
# FIXME: The above is still true ;) -- vila 20110811
- return config.GlobalStack()
+ return config.stacks.get('bazaar')()
class LockHeldInfo(object):
=== modified file 'bzrlib/msgeditor.py'
--- a/bzrlib/msgeditor.py 2011-07-23 16:33:38 +0000
+++ b/bzrlib/msgeditor.py 2011-09-06 16:02:01 +0000
@@ -41,7 +41,7 @@
except KeyError:
pass
- e = config.GlobalStack().get('editor')
+ e = config.stacks.get('bazaar')().get('editor')
if e is not None:
yield e, config.config_filename()
=== modified file 'bzrlib/osutils.py'
--- a/bzrlib/osutils.py 2011-08-24 23:55:03 +0000
+++ b/bzrlib/osutils.py 2011-09-06 16:02:01 +0000
@@ -986,7 +986,7 @@
def report_extension_load_failures():
if not _extension_load_failures:
return
- if config.GlobalStack().get('ignore_missing_extensions'):
+ if config.stacks.get('bazaar')().get('ignore_missing_extensions'):
return
# the warnings framework should by default show this only once
from bzrlib.trace import warning
=== modified file 'bzrlib/repofmt/pack_repo.py'
--- a/bzrlib/repofmt/pack_repo.py 2011-07-25 07:51:35 +0000
+++ b/bzrlib/repofmt/pack_repo.py 2011-09-06 16:02:01 +0000
@@ -831,7 +831,7 @@
set(all_combined).difference([combined_idx]))
# resumed packs
self._resumed_packs = []
- self.config_stack = config.LocationStack(self.transport.base)
+ self.config_stack = config.stacks.get('locations')(self.transport.base)
def __repr__(self):
return '%s(%r)' % (self.__class__.__name__, self.repo)
=== modified file 'bzrlib/tests/per_workingtree/test_workingtree.py'
--- a/bzrlib/tests/per_workingtree/test_workingtree.py 2011-08-31 22:52:43 +0000
+++ b/bzrlib/tests/per_workingtree/test_workingtree.py 2011-09-06 16:02:01 +0000
@@ -1161,7 +1161,7 @@
def test_set_in_branch(self):
wt = self.make_wt_with_worth_saving_limit()
- conf = config.BranchStack(wt.branch)
+ conf = config.stacks.get('branch')(wt.branch)
conf.set('bzr.workingtree.worth_saving_limit', '20')
self.assertEqual(20, wt._worth_saving_limit())
ds = wt.current_dirstate()
@@ -1169,7 +1169,7 @@
def test_invalid(self):
wt = self.make_wt_with_worth_saving_limit()
- conf = config.BranchStack(wt.branch)
+ conf = config.stacks.get('branch')(wt.branch)
conf.set('bzr.workingtree.worth_saving_limit', 'a')
# If the config entry is invalid, default to 10
warnings = []
=== modified file 'bzrlib/tests/test_config.py'
--- a/bzrlib/tests/test_config.py 2011-09-05 16:04:46 +0000
+++ b/bzrlib/tests/test_config.py 2011-09-06 16:02:01 +0000
@@ -132,15 +132,15 @@
config.test_stack_builder_registry.register(
- 'bazaar', lambda test: config.GlobalStack())
+ 'bazaar', lambda test: config.stacks.get('bazaar')())
config.test_stack_builder_registry.register(
- 'location', lambda test: config.LocationStack('.'))
+ 'location', lambda test: config.stacks.get('locations')('.'))
def build_branch_stack(test):
build_backing_branch(test, 'branch')
b = branch.Branch.open('branch')
- return config.BranchStack(b)
+ return config.stacks.get('branch')(b)
config.test_stack_builder_registry.register('branch', build_branch_stack)
@@ -151,7 +151,7 @@
server_class) = transport_remote.get_test_permutations()[0]
build_backing_branch(test, 'branch', transport_class, server_class)
b = branch.Branch.open(test.get_url('branch'))
- return config.RemoteBranchStack(b)
+ return config.stacks.get('branch')(b)
config.test_stack_builder_registry.register('remote_branch',
build_remote_branch_stack)
@@ -164,7 +164,7 @@
# creating a dedicated helper to create only the bzrdir
build_backing_branch(test, 'branch', transport_class, server_class)
b = branch.Branch.open(test.get_url('branch'))
- return config.RemoteControlStack(b.bzrdir)
+ return config.stacks.get('control-only')(b.bzrdir)
config.test_stack_builder_registry.register('remote_control',
build_remote_control_stack)
@@ -2530,7 +2530,6 @@
def test_help_is_set(self):
option_help = self.registry.get_help(self.option_name)
- self.assertNotEquals(None, option_help)
# Come on, think about the user, he really wants to know what the
# option is about
self.assertIsNot(None, option_help)
@@ -3184,7 +3183,7 @@
def setUp(self):
super(TestStackRegistry, self).setUp()
- self.registry = config._StackRegistry()
+ self.registry = config.StackRegistry()
def test_register_remove(self):
self.registry.register('test', config.Stack)
@@ -3208,8 +3207,25 @@
self.assertIs(self.lazy_stack, self.registry.get('test'))
-# register override
-# get_all
+class TestRegisteredStacks(tests.TestCase):
+
+ scenarios = [(key, {'stack_name': key, 'stack_factory': factory})
+ for key, factory in config.stacks.iteritems()]
+
+ def setUp(self):
+ super(TestRegisteredStacks, self).setUp()
+ self.registry = config.stacks
+
+ def test_factory_callable(self):
+ self.assertTrue(callable(self.stack_factory))
+
+ def test_help_is_set(self):
+ stack_help = self.registry.get_help(self.stack_name)
+ # Come on, think about the user, he really wants to know what the
+ # stack is about
+ self.assertIsNot(None, stack_help)
+ self.assertNotEquals('', stack_help)
+
class TestStackGet(tests.TestCase):
@@ -3520,7 +3536,7 @@
string = ''
# Since we don't save the config we won't strictly require to inherit
# from TestCaseInTempDir, but an error occurs so quickly...
- c = config.LocationStack(location)
+ c = config.stacks.get('locations')(location)
c.store._load_from_string(string)
return c
=== modified file 'bzrlib/tests/test_debug.py'
--- a/bzrlib/tests/test_debug.py 2011-08-12 16:25:56 +0000
+++ b/bzrlib/tests/test_debug.py 2011-09-06 16:02:01 +0000
@@ -33,7 +33,7 @@
self.assertDebugFlags(['hpss'], 'debug_flags = hpss\n')
def assertDebugFlags(self, expected_flags, conf_bytes):
- conf = config.GlobalStack()
+ conf = config.stacks.get('bazaar')()
conf.store._load_from_string(conf_bytes)
conf.store.save()
self.overrideAttr(debug, 'debug_flags', set())
=== modified file 'bzrlib/ui/__init__.py'
--- a/bzrlib/ui/__init__.py 2011-08-08 15:57:57 +0000
+++ b/bzrlib/ui/__init__.py 2011-09-06 16:02:01 +0000
@@ -248,7 +248,7 @@
"""
# XXX: is the caller supposed to close the resulting object?
if encoding is None:
- encoding = config.GlobalStack().get('output_encoding')
+ encoding = config.stacks.get('bazaar')().get('output_encoding')
if encoding is None:
encoding = osutils.get_terminal_encoding(trace=True)
if encoding_type is None:
=== modified file 'bzrlib/workingtree_4.py'
--- a/bzrlib/workingtree_4.py 2011-08-12 14:47:42 +0000
+++ b/bzrlib/workingtree_4.py 2011-09-06 16:02:01 +0000
@@ -251,7 +251,7 @@
:return: an integer. -1 means never save.
"""
# FIXME: We want a WorkingTreeStack here -- vila 20110812
- conf = config.BranchStack(self.branch)
+ conf = config.stacks.get('branch')(self.branch)
return conf.get('bzr.workingtree.worth_saving_limit')
def filter_unversioned_files(self, paths):
More information about the bazaar-commits
mailing list