Rev 6405: More tests, a real implementation and some tweaks. in file:///home/vila/src/bzr/bugs/832046-globs-store-ordered/

Vincent Ladeuil v.ladeuil+lp at free.fr
Thu Dec 22 16:29:56 UTC 2011


At file:///home/vila/src/bzr/bugs/832046-globs-store-ordered/

------------------------------------------------------------
revno: 6405
revision-id: v.ladeuil+lp at free.fr-20111222162955-92fl4zgjn17rfk9v
parent: v.ladeuil+lp at free.fr-20111222102342-4nr90uruiej3jhqy
committer: Vincent Ladeuil <v.ladeuil+lp at free.fr>
branch nick: 832046-globs-store-ordered
timestamp: Thu 2011-12-22 17:29:55 +0100
message:
  More tests, a real implementation and some tweaks.
-------------- next part --------------
=== modified file 'bzrlib/config.py'
--- a/bzrlib/config.py	2011-12-22 10:23:42 +0000
+++ b/bzrlib/config.py	2011-12-22 16:29:55 +0000
@@ -3012,10 +3012,6 @@
 class IniFileStore(Store):
     """A config Store using ConfigObj for storage.
 
-    :ivar transport: The transport object where the config file is located.
-
-    :ivar file_name: The config file basename in the transport directory.
-
     :ivar _config_obj: Private member to hold the ConfigObj instance used to
         serialize/deserialize the config file.
     """
@@ -3133,9 +3129,19 @@
             value = self._config_obj._unquote(value)
         return value
 
+    def external_url(self):
+        # Since an IniFileStore can be used without a file (at least in tests),
+        # it's better to provide something than raising a NotImplementedError.
+        # All daughter classes are supposed to provide an implementation
+        # anyway.
+        return 'In-Process Store, no URL'
 
 class TransportIniFileStore(IniFileStore):
     """IniFileStore that loads files from a transport.
+
+    :ivar transport: The transport object where the config file is located.
+
+    :ivar file_name: The config file basename in the transport directory.
     """
 
     def __init__(self, transport, file_name):
@@ -3355,8 +3361,15 @@
     def get_sections(self):
         """Get all sections matching ``location``."""
         store = self.store
-        for _, section in store.get_sections():
-            yield store, LocationSection(section, self.location)
+        sections = []
+        # Later sections are more specific, they should be returned first
+        for _, section in reversed(list(store.get_sections())):
+            section_path = section.id
+            if section_path.startswith('file://'):
+                section_path = urlutils.local_path_from_url(section)
+            if (self.location.startswith(section_path)
+                or fnmatch.fnmatch(self.location, section_path)):
+                yield store, LocationSection(section, self.location)
 
 
 class LocationMatcher(SectionMatcher):

=== modified file 'bzrlib/tests/test_config.py'
--- a/bzrlib/tests/test_config.py	2011-12-22 10:23:42 +0000
+++ b/bzrlib/tests/test_config.py	2011-12-22 16:29:55 +0000
@@ -3255,7 +3255,7 @@
                            '/quux/quux'],
                           [section.id for _, section in store.get_sections()])
         matcher = config.LocationMatcher(store, '/foo/bar/quux')
-        sections = [section for s, section in matcher.get_sections()]
+        sections = [section for _, section in matcher.get_sections()]
         self.assertEquals(['/foo/bar', '/foo'],
                           [section.id for section in sections])
         self.assertEquals(['quux', 'bar/quux'],
@@ -3272,7 +3272,7 @@
         self.assertEquals(['/foo', '/foo/bar'],
                           [section.id for _, section in store.get_sections()])
         matcher = config.LocationMatcher(store, '/foo/bar/baz')
-        sections = [section for s, section in matcher.get_sections()]
+        sections = [section for _, section in matcher.get_sections()]
         self.assertEquals(['/foo/bar', '/foo'],
                           [section.id for section in sections])
         self.assertEquals(['baz', 'bar/baz'],
@@ -3303,6 +3303,57 @@
         self.assertEquals(expected_location, matcher.location)
 
 
+class TestGlobOrderedMatcher(TestStore):
+
+    def setUp(self):
+        super(TestGlobOrderedMatcher, self).setUp()
+        self.matcher = config.NameMatcher
+        # Any simple store is good enough
+        self.store = config.IniFileStore()
+
+    def assertSectionIDs(self, expected, location, content):
+        self.store._load_from_string(content)
+        matcher = config.GlobOrderedMatcher(self.store, location)
+        sections = list(matcher.get_sections())
+        self.assertLength(len(expected), sections)
+        self.assertEqual(expected, [section.id for _, section in sections])
+        return sections
+
+    def test_empty(self):
+        self.assertSectionIDs([], self.test_dir, '')
+
+    def test_order_reversed(self):
+        self.assertSectionIDs(['/foo/bar', '/foo'], '/foo/bar/baz', '''\
+[/foo]
+[/foo/bar]
+''')
+
+    def test_unrelated_section_excluded(self):
+        self.assertSectionIDs(['/foo/bar', '/foo'], '/foo/bar/baz', '''\
+[/foo]
+[/foo/qux]
+[/foo/bar]
+''')
+
+    def test_glob_included(self):
+        self.assertSectionIDs(['/foo/*/baz', '/foo/b*', '/foo'],
+                              '/foo/bar/baz', '''\
+[/foo]
+[/foo/qux]
+[/foo/b*]
+[/foo/*/baz]
+''')
+
+    def test_respect_order(self):
+        self.assertSectionIDs(['/foo', '/foo/b*', '/foo/*/baz'],
+                              '/foo/bar/baz', '''\
+[/foo/*/baz]
+[/foo/qux]
+[/foo/b*]
+[/foo]
+''')
+
+
 class TestNameMatcher(TestStore):
 
     def setUp(self):
@@ -3334,25 +3385,6 @@
         self.assertLength(0, sections)
 
 
-class TestGlobOrderedMatcher(TestStore):
-
-    def setUp(self):
-        super(TestGlobOrderedMatcher, self).setUp()
-        self.matcher = config.NameMatcher
-        # Any simple store is good enough
-        self.store = config.IniFileStore()
-
-    def assertSections(self, expected, location, content):
-        self.store._load_from_string(content)
-        matcher = config.GlobOrderedMatcher(self.store, location)
-        sections = list(matcher.get_sections())
-        self.assertLength(len(expected), sections)
-        self.assertEqual(expected, sections)
-
-    def test_empty(self):
-        self.assertSections([], self.test_dir, '')
-
-
 class TestBaseStackGet(tests.TestCase):
 
     def setUp(self):



More information about the bazaar-commits mailing list