Rev 5768: Merge config-section into config-abstract-store in file:///home/vila/src/bzr/experimental/config/

Vincent Ladeuil v.ladeuil+lp at free.fr
Thu Apr 7 15:25:00 UTC 2011


At file:///home/vila/src/bzr/experimental/config/

------------------------------------------------------------
revno: 5768 [merge]
revision-id: v.ladeuil+lp at free.fr-20110407152500-8lhfyo34mna2s2z6
parent: v.ladeuil+lp at free.fr-20110407092835-1eorign73b8h6p0i
parent: v.ladeuil+lp at free.fr-20110407152459-bjnh4u489yfih0sd
committer: Vincent Ladeuil <v.ladeuil+lp at free.fr>
branch nick: config-abstract-store
timestamp: Thu 2011-04-07 17:25:00 +0200
message:
  Merge config-section into config-abstract-store
modified:
  bzrlib/config.py               config.py-20051011043216-070c74f4e9e338e8
-------------- next part --------------
=== modified file 'bzrlib/config.py'
--- a/bzrlib/config.py	2011-04-07 07:44:50 +0000
+++ b/bzrlib/config.py	2011-04-07 15:25:00 +0000
@@ -967,6 +967,49 @@
         super(LockableConfig, self).remove_user_option(option_name,
                                                        section_name)
 
+def _match_section_by_parts(section, location):
+    location_parts = location.rstrip('/').split('/')
+
+    # location is a local path if possible, so we need
+    # to convert 'file://' urls to local paths if necessary.
+
+    # FIXME: I don't think the above comment is still up to date,
+    # LocationConfig is always instantiated with an url -- vila 2011-04-07
+
+    # This also avoids having file:///path be a more exact
+    # match than '/path'.
+
+    # FIXME: Not sure about the above either, but since the path components are
+    # compared in sync, adding two empty components (//) is likely to trick the
+    # comparison and also trick the check on the number of components, so we
+    # *should* take only the relevant part of the url. On the other hand, this
+    # means 'file://' urls *can't* be used in sections -- vila 2011-04-07
+
+    if section.startswith('file://'):
+        section_path = urlutils.local_path_from_url(section)
+    else:
+        section_path = section
+    section_parts = section_path.rstrip('/').split('/')
+
+    matched = True
+    if len(section_parts) > len(location_parts):
+        # More path components in the section, they can't match
+        matched = False
+    else:
+        # Rely on zip truncating in length to the length of the shortest
+        # argument sequence.
+        names = zip(location_parts, section_parts)
+        for name in names:
+            if not fnmatch.fnmatch(name[0], name[1]):
+                matched = False
+                break
+    if not matched:
+        return None
+    else:
+        # build the path difference between the section and the location
+        relpath = '/'.join(location_parts[len(section_parts):])
+        return len(section_parts), relpath
+
 
 class LocationConfig(LockableConfig):
     """A configuration object that gives the policy for a location."""
@@ -1002,36 +1045,14 @@
     def _get_matching_sections(self):
         """Return an ordered list of section names matching this location."""
         sections = self._get_parser()
-        location_names = self.location.split('/')
-        if self.location.endswith('/'):
-            del location_names[-1]
-        matches=[]
+
+        matches = []
         for section in sections:
-            # location is a local path if possible, so we need
-            # to convert 'file://' urls to local paths if necessary.
-            # This also avoids having file:///path be a more exact
-            # match than '/path'.
-            if section.startswith('file://'):
-                section_path = urlutils.local_path_from_url(section)
-            else:
-                section_path = section
-            section_names = section_path.split('/')
-            if section.endswith('/'):
-                del section_names[-1]
-            names = zip(location_names, section_names)
-            matched = True
-            for name in names:
-                if not fnmatch.fnmatch(name[0], name[1]):
-                    matched = False
-                    break
-            if not matched:
-                continue
-            # so, for the common prefix they matched.
-            # if section is longer, no match.
-            if len(section_names) > len(location_names):
-                continue
-            matches.append((len(section_names), section,
-                            '/'.join(location_names[len(section_names):])))
+            match = _match_section_by_parts(section, self.location)
+            if match is None:
+                continue
+            nb_parts, relpath = match
+            matches.append((nb_parts, section, relpath))
         # put the longest (aka more specific) locations first
         matches.sort(reverse=True)
         sections = []



More information about the bazaar-commits mailing list