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