Rev 5767: Complete location config helpers with basic tests. in file:///home/vila/src/bzr/experimental/config/
Vincent Ladeuil
v.ladeuil+lp at free.fr
Thu Apr 7 17:13:07 UTC 2011
At file:///home/vila/src/bzr/experimental/config/
------------------------------------------------------------
revno: 5767
revision-id: v.ladeuil+lp at free.fr-20110407171307-8oaze02li95rpvat
parent: v.ladeuil+lp at free.fr-20110407152504-3ue5euqteffxc5ma
committer: Vincent Ladeuil <v.ladeuil+lp at free.fr>
branch nick: config-section-matchers
timestamp: Thu 2011-04-07 19:13:07 +0200
message:
Complete location config helpers with basic tests.
-------------- next part --------------
=== modified file 'bzrlib/config.py'
--- a/bzrlib/config.py 2011-04-07 15:25:04 +0000
+++ b/bzrlib/config.py 2011-04-07 17:13:07 +0000
@@ -2331,6 +2331,7 @@
# This is where we requires loading the store so we can see all defined
# sections.
sections = self.store.get_sections()
+ # Walk the revisions in the order provided
for s in sections:
if self.match(s):
yield s
@@ -2339,14 +2340,50 @@
raise NotImplementedError(self.match)
+class LocationSection(ReadOnlySection):
+
+ def __init__(self, section, length, extra_path):
+ super(LocationSection, self).__init__(section.id, section.options)
+ self.length = length
+ self.extra_path = extra_path
+
+ def get(self, name, default=None):
+ value = super(LocationSection, self).get(name, default)
+ if value is not None:
+ policy_name = self.get(name + ':policy', None)
+ policy = _policy_value.get(policy_name, POLICY_NONE)
+ if policy == POLICY_APPENDPATH:
+ value = urlutils.join(value, self.extra_path)
+ return value
+
+
class LocationMatcher(SectionMatcher):
- def __init__(self, store, location=None):
+ def __init__(self, store, location):
super(LocationMatcher, self).__init__(store)
self.location = location
- def match(self):
- return True
+ def get_sections(self):
+ # Override the default implementation as we want to change the order
+ sections = []
+ for section in self.store.get_sections():
+ match = _match_section_by_parts(section.id, self.location)
+ if match is not None:
+ length, extra_path = match
+ sections.append(LocationSection(section, length, extra_path))
+ # We want the longest (aka more specific) locations first
+ sections = sorted(sections, key=lambda section: section.length,
+ reverse=True)
+ # Sections mentioning 'ignore_parents' restrict the selection
+ for section in sections:
+ # FIXME: We really want to use as_bool below -- vila 2011-04-07
+ ignore = section.get('ignore_parents', None)
+ if ignore is not None:
+ ignore = ui.bool_from_string(ignore)
+ if ignore:
+ break
+ # Finally, we have a valid section
+ yield section
class cmd_config(commands.Command):
=== modified file 'bzrlib/tests/test_config.py'
--- a/bzrlib/tests/test_config.py 2011-04-07 10:30:46 +0000
+++ b/bzrlib/tests/test_config.py 2011-04-07 17:13:07 +0000
@@ -1967,6 +1967,7 @@
scenarios = [('configobj', {'_get_store': get_ConfigObjStore})]
def get_store(self, file_name, content=None):
+ # Overriden to get a writable transport
return self._get_store(
self.get_transport(), file_name, content=content)
@@ -2109,9 +2110,60 @@
def test_no_matches_for_empty_stores(self):
store = self.get_store('foo.conf', '')
- matcher = self.matcher(store)
+ matcher = self.matcher(store, '/bar')
self.assertEquals([], list(matcher.get_sections()))
+ def test_build_doesnt_load_store(self):
+ store = self.get_store('foo.conf', '')
+ matcher = self.matcher(store, '/bar')
+ self.assertFalse(store.loaded)
+
+
+class TestLocationSection(tests.TestCase):
+
+ def get_section(self, options, extra_path):
+ section = config.ReadOnlySection('foo', options)
+ # We don't care about the length so we use '0'
+ return config.LocationSection(section, 0, extra_path)
+
+ def test_simple_option(self):
+ section = self.get_section({'foo': 'bar'}, '')
+ self.assertEquals('bar', section.get('foo'))
+
+ def test_option_with_extra_path(self):
+ section = self.get_section({'foo': 'bar', 'foo:policy': 'appendpath'},
+ 'baz')
+ self.assertEquals('bar/baz', section.get('foo'))
+
+ def test_invalid_policy(self):
+ section = self.get_section({'foo': 'bar', 'foo:policy': 'die'},
+ 'baz')
+ # invalid policies are ignored
+ self.assertEquals('bar', section.get('foo'))
+
+
+class TestLocationMatcher(TestStore):
+
+ def test_more_specific_sections_first(self):
+ store = config.ConfigObjStore.from_string(
+ '''
+[/foo]
+section=/foo
+[/foo/bar]
+section=/foo/bar
+''',
+ self.get_readonly_transport(), 'foo.conf', )
+ self.assertEquals(['/foo', '/foo/bar'],
+ [section.id for section in store.get_sections()])
+ matcher = config.LocationMatcher(store, '/foo/bar/baz')
+ sections = list(matcher.get_sections())
+ self.assertEquals([3, 2],
+ [section.length for section in sections])
+ self.assertEquals(['/foo/bar', '/foo'],
+ [section.id for section in sections])
+ self.assertEquals(['baz', 'bar/baz'],
+ [section.extra_path for section in sections])
+
class TestConfigGetOptions(tests.TestCaseWithTransport, TestOptionsMixin):
@@ -2119,7 +2171,6 @@
super(TestConfigGetOptions, self).setUp()
create_configs(self)
- # One variable in none of the above
def test_no_variable(self):
# Using branch should query branch, locations and bazaar
self.assertOptions([], self.branch_config)
More information about the bazaar-commits
mailing list