[PATCH] cascading lookup support in LocationConfig (bug 33430)

James Henstridge james at jamesh.id.au
Fri Sep 8 05:31:16 BST 2006


Attached is a bundle to make LocationConfig._get_user_option() check
multiple config file sections rather than the most specific section.
This fixes the problem of config values getting shadowed (which can
happen when bzr adds new sections to locations.conf).

There was one test that seemed designed to make use of the shadowing
feature though: TestLocationConfig.test_location_without_username().
In this test, there is the following configuration in use:
    [http://www.example.com]
    # Top level policy
    email=Robert Collins <robertc at example.org>
    [http://www.example.com/useglobal]
    # different project, forces global lookup

It then looks up the email for http://www.example.com/useglobal to
check that the firstconfig section doesn't get seen (this test fails
with my change).  Assuming the user set up their config like this, the
intent was to ignore less specific settings when processing
http://www.example.com/useglobal.

With cascading configs, an equivalent feature would be a flag to block
checking of parent sections, which should be pretty easy to implement.
 Does anyone have an idea for a good key name for this? (given that
recursive is already taken).

James.
-------------- next part --------------
# Bazaar revision bundle v0.8
#
# message:
#   make test break again
# committer: James Henstridge <james at jamesh.id.au>
# date: Fri 2006-09-08 12:30:02.898999929 +0800

=== modified file bzrlib/config.py // last-changed:james at jamesh.id.au-200609080
... 31106-1b304673906dcf8f
--- bzrlib/config.py
+++ bzrlib/config.py
@@ -281,7 +281,7 @@
             return self._get_parser().get_value(self._get_section(),
                                                 option_name)
         except KeyError:
-            pass
+            return None
 
     def _gpg_signing_command(self):
         """See Config.gpg_signing_command."""
@@ -379,13 +379,8 @@
             location = urlutils.local_path_from_url(location)
         self.location = location
 
-    def _get_section(self):
-        """Get the section we should look in for config items.
-
-        Returns None if none exists. 
-        TODO: perhaps return a NullSection that thunks through to the 
-              global config.
-        """
+    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('/'):
@@ -423,10 +418,18 @@
                 except KeyError:
                     pass
             matches.append((len(section_names), section))
-        if not len(matches):
-            return None
         matches.sort(reverse=True)
-        return matches[0][1]
+        return [section for (length, section) in matches]
+
+    def _get_user_option(self, option_name):
+        """See Config._get_user_option."""
+        for section in self._get_matching_sections():
+            try:
+                return self._get_parser().get_value(section, option_name)
+            except KeyError:
+                pass
+        else:
+            return None
 
     def set_user_option(self, option, value):
         """Save option and its value in the configuration."""

=== modified file bzrlib/tests/test_config.py
--- bzrlib/tests/test_config.py
+++ bzrlib/tests/test_config.py
@@ -535,54 +535,64 @@
         self.failUnless(isinstance(global_config, config.GlobalConfig))
         self.failUnless(global_config is my_config._get_global_config())
 
-    def test__get_section_no_match(self):
+    def test__get_matching_sections_no_match(self):
         self.get_branch_config('/')
-        self.assertEqual(None, self.my_location_config._get_section())
+        self.assertEqual([], self.my_location_config._get_matching_sections())
         
-    def test__get_section_exact(self):
+    def test__get_matching_sections_exact(self):
         self.get_branch_config('http://www.example.com')
-        self.assertEqual('http://www.example.com',
-                         self.my_location_config._get_section())
+        self.assertEqual(['http://www.example.com'],
+                         self.my_location_config._get_matching_sections())
    
-    def test__get_section_suffix_does_not(self):
+    def test__get_matching_sections_suffix_does_not(self):
         self.get_branch_config('http://www.example.com-com')
-        self.assertEqual(None, self.my_location_config._get_section())
+        self.assertEqual([], self.my_location_config._get_matching_sections())
 
-    def test__get_section_subdir_recursive(self):
+    def test__get_matching_sections_subdir_recursive(self):
         self.get_branch_config('http://www.example.com/com')
-        self.assertEqual('http://www.example.com',
-                         self.my_location_config._get_section())
+        self.assertEqual(['http://www.example.com'],
+                         self.my_location_config._get_matching_sections())
 
-    def test__get_section_subdir_matches(self):
+    def test__get_matching_sections_subdir_matches(self):
         self.get_branch_config('http://www.example.com/useglobal')
-        self.assertEqual('http://www.example.com/useglobal',
-                         self.my_location_config._get_section())
+        self.assertEqual(['http://www.example.com/useglobal',
+                          'http://www.example.com'],
+                         self.my_location_config._get_matching_sections())
 
-    def test__get_section_subdir_nonrecursive(self):
+    def test__get_matching_sections_subdir_nonrecursive(self):
         self.get_branch_config(
             'http://www.example.com/useglobal/childbranch')
-        self.assertEqual('http://www.example.com',
-                         self.my_location_config._get_section())
+        self.assertEqual(['http://www.example.com'],
+                         self.my_location_config._get_matching_sections())
 
-    def test__get_section_subdir_trailing_slash(self):
+    def test__get_matching_sections_subdir_trailing_slash(self):
         self.get_branch_config('/b')
-        self.assertEqual('/b/', self.my_location_config._get_section())
+        self.assertEqual(['/b/'],
+                         self.my_location_config._get_matching_sections())
 
-    def test__get_section_subdir_child(self):
+    def test__get_matching_sections_subdir_child(self):
         self.get_branch_config('/a/foo')
-        self.assertEqual('/a/*', self.my_location_config._get_section())
+        self.assertEqual(['/a/*', '/a/'],
+                         self.my_location_config._get_matching_sections())
 
-    def test__get_section_subdir_child_child(self):
+    def test__get_matching_sections_subdir_child_child(self):
         self.get_branch_config('/a/foo/bar')
-        self.assertEqual('/a/', self.my_location_config._get_section())
+        self.assertEqual(['/a/'],
+                         self.my_location_config._get_matching_sections())
 
-    def test__get_section_trailing_slash_with_children(self):
+    def test__get_matching_sections_trailing_slash_with_children(self):
         self.get_branch_config('/a/')
-        self.assertEqual('/a/', self.my_location_config._get_section())
+        self.assertEqual(['/a/'],
+                         self.my_location_config._get_matching_sections())
 
-    def test__get_section_explicit_over_glob(self):
+    def test__get_matching_sections_explicit_over_glob(self):
+        # XXX: 2006-09-08 jamesh
+        # This test only passes because ord('c') > ord('*').  If there
+        # was a config section for '/a/?', it would get precedence
+        # over '/a/c'.
         self.get_branch_config('/a/c')
-        self.assertEqual('/a/c', self.my_location_config._get_section())
+        self.assertEqual(['/a/c', '/a/*', '/a/'],
+                         self.my_location_config._get_matching_sections())
 
 
     def test_location_without_username(self):

# revision id: james at jamesh.id.au-20060908043002-c7f13407e7d4109c
# sha1: 280af3599bf2ffeeae26a825da65c057faf1f400
# inventory sha1: fa00b1c04d5b16d16ec4662cc825f891452a1c45
# parent ids:
#   james at jamesh.id.au-20060908031106-1b304673906dcf8f
# base id: pqm at pqm.ubuntu.com-20060908003811-74eab872c372a895
# properties:
#   branch-nick: bzr.locationconfig

# message:
#   first go at making location config lookup recursive
# committer: James Henstridge <james at jamesh.id.au>
# date: Fri 2006-09-08 11:11:06.072000027 +0800

=== modified file bzrlib/config.py // encoding:base64
LS0tIGJ6cmxpYi9jb25maWcucHkKKysrIGJ6cmxpYi9jb25maWcucHkKQEAgLTI4MSw3ICsyODEs
NyBAQAogICAgICAgICAgICAgcmV0dXJuIHNlbGYuX2dldF9wYXJzZXIoKS5nZXRfdmFsdWUoc2Vs
Zi5fZ2V0X3NlY3Rpb24oKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgIG9wdGlvbl9uYW1lKQogICAgICAgICBleGNlcHQgS2V5RXJyb3I6Ci0gICAgICAg
ICAgICBwYXNzCisgICAgICAgICAgICByZXR1cm4gTm9uZQogCiAgICAgZGVmIF9ncGdfc2lnbmlu
Z19jb21tYW5kKHNlbGYpOgogICAgICAgICAiIiJTZWUgQ29uZmlnLmdwZ19zaWduaW5nX2NvbW1h
bmQuIiIiCkBAIC0zNzksMTMgKzM3OSw4IEBACiAgICAgICAgICAgICBsb2NhdGlvbiA9IHVybHV0
aWxzLmxvY2FsX3BhdGhfZnJvbV91cmwobG9jYXRpb24pCiAgICAgICAgIHNlbGYubG9jYXRpb24g
PSBsb2NhdGlvbgogCi0gICAgZGVmIF9nZXRfc2VjdGlvbihzZWxmKToKLSAgICAgICAgIiIiR2V0
IHRoZSBzZWN0aW9uIHdlIHNob3VsZCBsb29rIGluIGZvciBjb25maWcgaXRlbXMuCi0KLSAgICAg
ICAgUmV0dXJucyBOb25lIGlmIG5vbmUgZXhpc3RzLiAKLSAgICAgICAgVE9ETzogcGVyaGFwcyBy
ZXR1cm4gYSBOdWxsU2VjdGlvbiB0aGF0IHRodW5rcyB0aHJvdWdoIHRvIHRoZSAKLSAgICAgICAg
ICAgICAgZ2xvYmFsIGNvbmZpZy4KLSAgICAgICAgIiIiCisgICAgZGVmIF9nZXRfbWF0Y2hpbmdf
c2VjdGlvbnMoc2VsZik6CisgICAgICAgICIiIlJldHVybiBhbiBvcmRlcmVkIGxpc3Qgb2Ygc2Vj
dGlvbiBuYW1lcyBtYXRjaGluZyB0aGlzIGxvY2F0aW9uLiIiIgogICAgICAgICBzZWN0aW9ucyA9
IHNlbGYuX2dldF9wYXJzZXIoKQogICAgICAgICBsb2NhdGlvbl9uYW1lcyA9IHNlbGYubG9jYXRp
b24uc3BsaXQoJy8nKQogICAgICAgICBpZiBzZWxmLmxvY2F0aW9uLmVuZHN3aXRoKCcvJyk6CkBA
IC00MjMsMTAgKzQxOCwxOCBAQAogICAgICAgICAgICAgICAgIGV4Y2VwdCBLZXlFcnJvcjoKICAg
ICAgICAgICAgICAgICAgICAgcGFzcwogICAgICAgICAgICAgbWF0Y2hlcy5hcHBlbmQoKGxlbihz
ZWN0aW9uX25hbWVzKSwgc2VjdGlvbikpCi0gICAgICAgIGlmIG5vdCBsZW4obWF0Y2hlcyk6Ci0g
ICAgICAgICAgICByZXR1cm4gTm9uZQogICAgICAgICBtYXRjaGVzLnNvcnQocmV2ZXJzZT1UcnVl
KQotICAgICAgICByZXR1cm4gbWF0Y2hlc1swXVsxXQorICAgICAgICByZXR1cm4gW3NlY3Rpb24g
Zm9yIChsZW5ndGgsIHNlY3Rpb24pIGluIG1hdGNoZXNdCisKKyAgICBkZWYgX2dldF91c2VyX29w
dGlvbihzZWxmLCBvcHRpb25fbmFtZSk6CisgICAgICAgICIiIlNlZSBDb25maWcuX2dldF91c2Vy
X29wdGlvbi4iIiIKKyAgICAgICAgZm9yIHNlY3Rpb24gaW4gc2VsZi5fZ2V0X21hdGNoaW5nX3Nl
Y3Rpb25zKCk6CisgICAgICAgICAgICB0cnk6CisgICAgICAgICAgICAgICAgcmV0dXJuIHNlbGYu
X2dldF9wYXJzZXIoKS5nZXRfdmFsdWUoc2VjdGlvbiwgb3B0aW9uX25hbWUpCisgICAgICAgICAg
ICBleGNlcHQgS2V5RXJyb3I6CisgICAgICAgICAgICAgICAgcGFzcworICAgICAgICBlbHNlOgor
ICAgICAgICAgICAgcmV0dXJuIE5vbmUKIAogICAgIGRlZiBzZXRfdXNlcl9vcHRpb24oc2VsZiwg
b3B0aW9uLCB2YWx1ZSk6CiAgICAgICAgICIiIlNhdmUgb3B0aW9uIGFuZCBpdHMgdmFsdWUgaW4g
dGhlIGNvbmZpZ3VyYXRpb24uIiIiCgo=

=== modified file bzrlib/tests/test_config.py // encoding:base64
LS0tIGJ6cmxpYi90ZXN0cy90ZXN0X2NvbmZpZy5weQorKysgYnpybGliL3Rlc3RzL3Rlc3RfY29u
ZmlnLnB5CkBAIC01MzUsNTggKzUzNSw2OCBAQAogICAgICAgICBzZWxmLmZhaWxVbmxlc3MoaXNp
bnN0YW5jZShnbG9iYWxfY29uZmlnLCBjb25maWcuR2xvYmFsQ29uZmlnKSkKICAgICAgICAgc2Vs
Zi5mYWlsVW5sZXNzKGdsb2JhbF9jb25maWcgaXMgbXlfY29uZmlnLl9nZXRfZ2xvYmFsX2NvbmZp
ZygpKQogCi0gICAgZGVmIHRlc3RfX2dldF9zZWN0aW9uX25vX21hdGNoKHNlbGYpOgorICAgIGRl
ZiB0ZXN0X19nZXRfbWF0Y2hpbmdfc2VjdGlvbnNfbm9fbWF0Y2goc2VsZik6CiAgICAgICAgIHNl
bGYuZ2V0X2JyYW5jaF9jb25maWcoJy8nKQotICAgICAgICBzZWxmLmFzc2VydEVxdWFsKE5vbmUs
IHNlbGYubXlfbG9jYXRpb25fY29uZmlnLl9nZXRfc2VjdGlvbigpKQorICAgICAgICBzZWxmLmFz
c2VydEVxdWFsKFtdLCBzZWxmLm15X2xvY2F0aW9uX2NvbmZpZy5fZ2V0X21hdGNoaW5nX3NlY3Rp
b25zKCkpCiAgICAgICAgIAotICAgIGRlZiB0ZXN0X19nZXRfc2VjdGlvbl9leGFjdChzZWxmKToK
KyAgICBkZWYgdGVzdF9fZ2V0X21hdGNoaW5nX3NlY3Rpb25zX2V4YWN0KHNlbGYpOgogICAgICAg
ICBzZWxmLmdldF9icmFuY2hfY29uZmlnKCdodHRwOi8vd3d3LmV4YW1wbGUuY29tJykKLSAgICAg
ICAgc2VsZi5hc3NlcnRFcXVhbCgnaHR0cDovL3d3dy5leGFtcGxlLmNvbScsCi0gICAgICAgICAg
ICAgICAgICAgICAgICAgc2VsZi5teV9sb2NhdGlvbl9jb25maWcuX2dldF9zZWN0aW9uKCkpCisg
ICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwoWydodHRwOi8vd3d3LmV4YW1wbGUuY29tJ10sCisgICAg
ICAgICAgICAgICAgICAgICAgICAgc2VsZi5teV9sb2NhdGlvbl9jb25maWcuX2dldF9tYXRjaGlu
Z19zZWN0aW9ucygpKQogICAgCi0gICAgZGVmIHRlc3RfX2dldF9zZWN0aW9uX3N1ZmZpeF9kb2Vz
X25vdChzZWxmKToKKyAgICBkZWYgdGVzdF9fZ2V0X21hdGNoaW5nX3NlY3Rpb25zX3N1ZmZpeF9k
b2VzX25vdChzZWxmKToKICAgICAgICAgc2VsZi5nZXRfYnJhbmNoX2NvbmZpZygnaHR0cDovL3d3
dy5leGFtcGxlLmNvbS1jb20nKQotICAgICAgICBzZWxmLmFzc2VydEVxdWFsKE5vbmUsIHNlbGYu
bXlfbG9jYXRpb25fY29uZmlnLl9nZXRfc2VjdGlvbigpKQorICAgICAgICBzZWxmLmFzc2VydEVx
dWFsKFtdLCBzZWxmLm15X2xvY2F0aW9uX2NvbmZpZy5fZ2V0X21hdGNoaW5nX3NlY3Rpb25zKCkp
CiAKLSAgICBkZWYgdGVzdF9fZ2V0X3NlY3Rpb25fc3ViZGlyX3JlY3Vyc2l2ZShzZWxmKToKKyAg
ICBkZWYgdGVzdF9fZ2V0X21hdGNoaW5nX3NlY3Rpb25zX3N1YmRpcl9yZWN1cnNpdmUoc2VsZik6
CiAgICAgICAgIHNlbGYuZ2V0X2JyYW5jaF9jb25maWcoJ2h0dHA6Ly93d3cuZXhhbXBsZS5jb20v
Y29tJykKLSAgICAgICAgc2VsZi5hc3NlcnRFcXVhbCgnaHR0cDovL3d3dy5leGFtcGxlLmNvbScs
Ci0gICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5teV9sb2NhdGlvbl9jb25maWcuX2dldF9z
ZWN0aW9uKCkpCisgICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwoWydodHRwOi8vd3d3LmV4YW1wbGUu
Y29tJ10sCisgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5teV9sb2NhdGlvbl9jb25maWcu
X2dldF9tYXRjaGluZ19zZWN0aW9ucygpKQogCi0gICAgZGVmIHRlc3RfX2dldF9zZWN0aW9uX3N1
YmRpcl9tYXRjaGVzKHNlbGYpOgorICAgIGRlZiB0ZXN0X19nZXRfbWF0Y2hpbmdfc2VjdGlvbnNf
c3ViZGlyX21hdGNoZXMoc2VsZik6CiAgICAgICAgIHNlbGYuZ2V0X2JyYW5jaF9jb25maWcoJ2h0
dHA6Ly93d3cuZXhhbXBsZS5jb20vdXNlZ2xvYmFsJykKLSAgICAgICAgc2VsZi5hc3NlcnRFcXVh
bCgnaHR0cDovL3d3dy5leGFtcGxlLmNvbS91c2VnbG9iYWwnLAotICAgICAgICAgICAgICAgICAg
ICAgICAgIHNlbGYubXlfbG9jYXRpb25fY29uZmlnLl9nZXRfc2VjdGlvbigpKQorICAgICAgICBz
ZWxmLmFzc2VydEVxdWFsKFsnaHR0cDovL3d3dy5leGFtcGxlLmNvbS91c2VnbG9iYWwnLAorICAg
ICAgICAgICAgICAgICAgICAgICAgICAnaHR0cDovL3d3dy5leGFtcGxlLmNvbSddLAorICAgICAg
ICAgICAgICAgICAgICAgICAgIHNlbGYubXlfbG9jYXRpb25fY29uZmlnLl9nZXRfbWF0Y2hpbmdf
c2VjdGlvbnMoKSkKIAotICAgIGRlZiB0ZXN0X19nZXRfc2VjdGlvbl9zdWJkaXJfbm9ucmVjdXJz
aXZlKHNlbGYpOgorICAgIGRlZiB0ZXN0X19nZXRfbWF0Y2hpbmdfc2VjdGlvbnNfc3ViZGlyX25v
bnJlY3Vyc2l2ZShzZWxmKToKICAgICAgICAgc2VsZi5nZXRfYnJhbmNoX2NvbmZpZygKICAgICAg
ICAgICAgICdodHRwOi8vd3d3LmV4YW1wbGUuY29tL3VzZWdsb2JhbC9jaGlsZGJyYW5jaCcpCi0g
ICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwoJ2h0dHA6Ly93d3cuZXhhbXBsZS5jb20nLAotICAgICAg
ICAgICAgICAgICAgICAgICAgIHNlbGYubXlfbG9jYXRpb25fY29uZmlnLl9nZXRfc2VjdGlvbigp
KQorICAgICAgICBzZWxmLmFzc2VydEVxdWFsKFsnaHR0cDovL3d3dy5leGFtcGxlLmNvbSddLAor
ICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYubXlfbG9jYXRpb25fY29uZmlnLl9nZXRfbWF0
Y2hpbmdfc2VjdGlvbnMoKSkKIAotICAgIGRlZiB0ZXN0X19nZXRfc2VjdGlvbl9zdWJkaXJfdHJh
aWxpbmdfc2xhc2goc2VsZik6CisgICAgZGVmIHRlc3RfX2dldF9tYXRjaGluZ19zZWN0aW9uc19z
dWJkaXJfdHJhaWxpbmdfc2xhc2goc2VsZik6CiAgICAgICAgIHNlbGYuZ2V0X2JyYW5jaF9jb25m
aWcoJy9iJykKLSAgICAgICAgc2VsZi5hc3NlcnRFcXVhbCgnL2IvJywgc2VsZi5teV9sb2NhdGlv
bl9jb25maWcuX2dldF9zZWN0aW9uKCkpCisgICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwoWycvYi8n
XSwKKyAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLm15X2xvY2F0aW9uX2NvbmZpZy5fZ2V0
X21hdGNoaW5nX3NlY3Rpb25zKCkpCiAKLSAgICBkZWYgdGVzdF9fZ2V0X3NlY3Rpb25fc3ViZGly
X2NoaWxkKHNlbGYpOgorICAgIGRlZiB0ZXN0X19nZXRfbWF0Y2hpbmdfc2VjdGlvbnNfc3ViZGly
X2NoaWxkKHNlbGYpOgogICAgICAgICBzZWxmLmdldF9icmFuY2hfY29uZmlnKCcvYS9mb28nKQot
ICAgICAgICBzZWxmLmFzc2VydEVxdWFsKCcvYS8qJywgc2VsZi5teV9sb2NhdGlvbl9jb25maWcu
X2dldF9zZWN0aW9uKCkpCisgICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwoWycvYS8qJywgJy9hLydd
LAorICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYubXlfbG9jYXRpb25fY29uZmlnLl9nZXRf
bWF0Y2hpbmdfc2VjdGlvbnMoKSkKIAotICAgIGRlZiB0ZXN0X19nZXRfc2VjdGlvbl9zdWJkaXJf
Y2hpbGRfY2hpbGQoc2VsZik6CisgICAgZGVmIHRlc3RfX2dldF9tYXRjaGluZ19zZWN0aW9uc19z
dWJkaXJfY2hpbGRfY2hpbGQoc2VsZik6CiAgICAgICAgIHNlbGYuZ2V0X2JyYW5jaF9jb25maWco
Jy9hL2Zvby9iYXInKQotICAgICAgICBzZWxmLmFzc2VydEVxdWFsKCcvYS8nLCBzZWxmLm15X2xv
Y2F0aW9uX2NvbmZpZy5fZ2V0X3NlY3Rpb24oKSkKKyAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChb
Jy9hLyddLAorICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYubXlfbG9jYXRpb25fY29uZmln
Ll9nZXRfbWF0Y2hpbmdfc2VjdGlvbnMoKSkKIAotICAgIGRlZiB0ZXN0X19nZXRfc2VjdGlvbl90
cmFpbGluZ19zbGFzaF93aXRoX2NoaWxkcmVuKHNlbGYpOgorICAgIGRlZiB0ZXN0X19nZXRfbWF0
Y2hpbmdfc2VjdGlvbnNfdHJhaWxpbmdfc2xhc2hfd2l0aF9jaGlsZHJlbihzZWxmKToKICAgICAg
ICAgc2VsZi5nZXRfYnJhbmNoX2NvbmZpZygnL2EvJykKLSAgICAgICAgc2VsZi5hc3NlcnRFcXVh
bCgnL2EvJywgc2VsZi5teV9sb2NhdGlvbl9jb25maWcuX2dldF9zZWN0aW9uKCkpCisgICAgICAg
IHNlbGYuYXNzZXJ0RXF1YWwoWycvYS8nXSwKKyAgICAgICAgICAgICAgICAgICAgICAgICBzZWxm
Lm15X2xvY2F0aW9uX2NvbmZpZy5fZ2V0X21hdGNoaW5nX3NlY3Rpb25zKCkpCiAKLSAgICBkZWYg
dGVzdF9fZ2V0X3NlY3Rpb25fZXhwbGljaXRfb3Zlcl9nbG9iKHNlbGYpOgorICAgIGRlZiB0ZXN0
X19nZXRfbWF0Y2hpbmdfc2VjdGlvbnNfZXhwbGljaXRfb3Zlcl9nbG9iKHNlbGYpOgorICAgICAg
ICAjIFhYWDogMjAwNi0wOS0wOCBqYW1lc2gKKyAgICAgICAgIyBUaGlzIHRlc3Qgb25seSBwYXNz
ZXMgYmVjYXVzZSBvcmQoJ2MnKSA+IG9yZCgnKicpLiAgSWYgdGhlcmUKKyAgICAgICAgIyB3YXMg
YSBjb25maWcgc2VjdGlvbiBmb3IgJy9hLz8nLCBpdCB3b3VsZCBnZXQgcHJlY2VkZW5jZQorICAg
ICAgICAjIG92ZXIgJy9hL2MnLgogICAgICAgICBzZWxmLmdldF9icmFuY2hfY29uZmlnKCcvYS9j
JykKLSAgICAgICAgc2VsZi5hc3NlcnRFcXVhbCgnL2EvYycsIHNlbGYubXlfbG9jYXRpb25fY29u
ZmlnLl9nZXRfc2VjdGlvbigpKQorICAgICAgICBzZWxmLmFzc2VydEVxdWFsKFsnL2EvYycsICcv
YS8qJywgJy9hLyddLAorICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYubXlfbG9jYXRpb25f
Y29uZmlnLl9nZXRfbWF0Y2hpbmdfc2VjdGlvbnMoKSkKIAogCiAgICAgZGVmIHRlc3RfbG9jYXRp
b25fd2l0aG91dF91c2VybmFtZShzZWxmKToKLSAgICAgICAgc2VsZi5nZXRfYnJhbmNoX2NvbmZp
ZygnaHR0cDovL3d3dy5leGFtcGxlLmNvbS91c2VnbG9iYWwnKQorICAgICAgICBzZWxmLmdldF9i
cmFuY2hfY29uZmlnKCcvYi8nKQogICAgICAgICBzZWxmLmFzc2VydEVxdWFsKHUnRXJpayBCXHUw
MGU1Z2ZvcnMgPGVyaWtAYmFnZm9ycy5udT4nLAogICAgICAgICAgICAgICAgICAgICAgICAgIHNl
bGYubXlfY29uZmlnLnVzZXJuYW1lKCkpCiAKCg==

# revision id: james at jamesh.id.au-20060908031106-1b304673906dcf8f
# sha1: 8c8c290f4c1bae0d712d1718e7b5c09426f56e04
# inventory sha1: ac8be32a9018b3706d1a84cd327403aea9104d2d
# parent ids:
#   pqm at pqm.ubuntu.com-20060908003811-74eab872c372a895
# properties:
#   branch-nick: bzr.locationconfig


More information about the bazaar mailing list