Rev 6257: Try a ini-file format for features, proof-of-concept-ish but pasing the in file:///home/vila/src/bzr/reviews/feature-flags/

Vincent Ladeuil v.ladeuil+lp at free.fr
Fri Dec 16 12:41:56 UTC 2011


At file:///home/vila/src/bzr/reviews/feature-flags/

------------------------------------------------------------
revno: 6257
revision-id: v.ladeuil+lp at free.fr-20111216124156-0u6i2by1w14rwcmr
parent: jelmer at samba.org-20111214183219-psb0o3exfsnhpemq
committer: Vincent Ladeuil <v.ladeuil+lp at free.fr>
branch nick: feature-flags
timestamp: Fri 2011-12-16 13:41:56 +0100
message:
  Try a ini-file format for features, proof-of-concept-ish but pasing the
  whole test suite nevertheless.
-------------- next part --------------
=== modified file 'bzrlib/branch.py'
--- a/bzrlib/branch.py	2011-12-11 03:49:52 +0000
+++ b/bzrlib/branch.py	2011-12-16 12:41:56 +0000
@@ -2097,11 +2097,12 @@
         return True
 
     def check_support_status(self, allow_unsupported, recommend_upgrade=True,
-            basedir=None):
-        BranchFormat.check_support_status(self,
-            allow_unsupported=allow_unsupported, recommend_upgrade=recommend_upgrade,
-            basedir=basedir)
-        bzrdir.BzrFormat.check_support_status(self, allow_unsupported=allow_unsupported,
+                             basedir=None):
+        BranchFormat.check_support_status(
+            self, allow_unsupported=allow_unsupported,
+            recommend_upgrade=recommend_upgrade, basedir=basedir)
+        bzrdir.BzrFormat.check_support_status(
+            self, allow_unsupported=allow_unsupported,
             recommend_upgrade=recommend_upgrade, basedir=basedir)
 
 

=== modified file 'bzrlib/bzrdir.py'
--- a/bzrlib/bzrdir.py	2011-12-14 18:32:19 +0000
+++ b/bzrlib/bzrdir.py	2011-12-16 12:41:56 +0000
@@ -29,6 +29,8 @@
 
 from bzrlib.lazy_import import lazy_import
 lazy_import(globals(), """
+from cStringIO import StringIO
+
 import bzrlib
 from bzrlib import (
     branch as _mod_branch,
@@ -1168,23 +1170,39 @@
     def from_string(cls, text):
         format_string = cls.get_format_string()
         if not text.startswith(format_string):
-            raise ValueError("Invalid format header %r" % text)
-        lines = text[len(format_string):].splitlines()
+            raise ValueError("Invalid format header %r" % (text,))
+        rest = text[len(format_string):]
+        if not rest:
+            # Just a bare format string
+            return cls()
+
+        try:
+            # list_values=True (default) means we get values as lists
+            # automagically
+            conf = config.ConfigObj(StringIO(rest), encoding='utf-8')
+        except config.configobj.ConfigObjError, e:
+            raise ValueError("Invalid format content %r" % (rest,))
+        except UnicodeDecodeError:
+            raise ValueError("Non-utf8 format content %r" % (rest,))
+        try:
+            fdict = conf['features']
+        except KeyError:
+            raise ValueError("Invalid features %r" % (rest,))
         ret = cls()
-        for lineno, line in enumerate(lines):
-            (necessity, command, feature) = line.split(" ")
-            if command != "feature":
-                raise ValueError("Invalid command %r on line %d" %
-                    (command, lineno))
-            ret.features[feature] = necessity
+        for name, value in fdict.iteritems():
+            if not value in ('required', 'optional', 'necessity'):
+                raise ValueError("Invalid feature kind %r" % (value,))
+            ret.features[name] = value
         return ret
 
     def as_string(self):
         """Return the string representation of this format.
         """
         lines = [self.get_format_string()]
-        lines.extend([("%s feature %s\n" % (item[1], item[0])) for item in
-            self.features.iteritems()])
+        if self.features:
+            lines.append('[features]\n')
+            lines.extend([("%s = %s\n" % (k, v)) for k,v in
+                          self.features.iteritems()])
         return "".join(lines)
 
     @classmethod

=== modified file 'bzrlib/tests/test_branch.py'
--- a/bzrlib/tests/test_branch.py	2011-12-11 03:49:52 +0000
+++ b/bzrlib/tests/test_branch.py	2011-12-16 12:41:56 +0000
@@ -221,7 +221,7 @@
         tree = self.make_branch_and_tree('.', format='2a')
         tree.branch.control_transport.put_bytes('format',
             tree.branch._format.get_format_string() +
-            "optional feature name\n")
+            "[features]\n name = optional\n")
         found_format = _mod_branch.BranchFormatMetadir.find_format(tree.bzrdir)
         self.assertIsInstance(found_format, _mod_branch.BranchFormatMetadir)
         self.assertEquals(found_format.features.get("name"), "optional")

=== modified file 'bzrlib/tests/test_bzrdir.py'
--- a/bzrlib/tests/test_bzrdir.py	2011-12-14 18:32:19 +0000
+++ b/bzrlib/tests/test_bzrdir.py	2011-12-16 12:41:56 +0000
@@ -1029,7 +1029,8 @@
         tree = self.make_branch_and_tree('tree', format='2a')
         tree.bzrdir.control_transport.put_bytes(
             'branch-format',
-            tree.bzrdir._format.get_format_string() + "required feature bar\n")
+            (tree.bzrdir._format.get_format_string()
+             + "[features]\nbar = required\n"))
         self.assertRaises(errors.MissingFeature, bzrdir.BzrDir.open, 'tree')
         bzrdir.BzrDirMetaFormat1.register_feature('bar')
         dir = bzrdir.BzrDir.open('tree')
@@ -1459,36 +1460,45 @@
     def test_as_string(self):
         format = SampleBzrFormat()
         format.features = {"foo": "required"}
-        self.assertEquals(format.as_string(),
-            "First line\n"
-            "required feature foo\n")
+        self.assertEquals(format.as_string(), '''First line
+[features]
+foo = required
+''')
         format.features["another"] = "optional"
-        self.assertEquals(format.as_string(),
-            "First line\n"
-            "required feature foo\n"
-            "optional feature another\n")
+        self.assertEquals(format.as_string(), '''First line
+[features]
+foo = required
+another = optional
+''')
 
     def test_network_name(self):
         # The network string should include the feature info
         format = SampleBzrFormat()
         format.features = {"foo": "required"}
         self.assertEquals(
-            "First line\nrequired feature foo\n",
+            "First line\n[features]\nfoo = required\n",
             format.network_name())
 
-    def test_from_string(self):
+    def test_valid_from_string(self):
         format = SampleBzrFormat.from_string(
-            "First line\nrequired feature foo\n")
+            "First line\n[features]\nfoo=required\n")
         self.assertEquals("required", format.features.get("foo"))
-        self.assertRaises(ValueError, SampleBzrFormat.from_string,
-            "Second line\nrequired feature foo\n")
-        self.assertRaises(ValueError, SampleBzrFormat.from_string,
-            "First line\nrequired bla foo\n")
+
+    def test_invalid_format_line(self):
+        self.assertRaises(ValueError, SampleBzrFormat.from_string,
+            "Second line\n[features]\nfoo=required\n")
+
+    def test_unknown_kind_feature(self):
+        self.assertRaises(ValueError, SampleBzrFormat.from_string,
+            "First line\n[features]\nfoo=bla\n")
+
+    def test_invalid_content(self):
         self.assertRaises(ValueError, SampleBzrFormat.from_string,
             "First line\nfoo\n")
 
     def test_eq(self):
         format1 = SampleBzrFormat()
+        # Huh ? spaces allowed in feature names ?? Madness ! :)
         format1.features = {"nested trees": "optional"}
         format2 = SampleBzrFormat()
         format2.features = {"nested trees": "optional"}

=== modified file 'bzrlib/tests/test_repository.py'
--- a/bzrlib/tests/test_repository.py	2011-12-11 03:49:52 +0000
+++ b/bzrlib/tests/test_repository.py	2011-12-16 12:41:56 +0000
@@ -168,7 +168,7 @@
         tree = self.make_branch_and_tree('.', format='2a')
         tree.branch.repository.control_transport.put_bytes('format',
             tree.branch.repository._format.get_format_string() +
-            "necessity feature name\n")
+            "[features]\nname = necessity\n")
         found_format = repository.RepositoryFormatMetaDir.find_format(tree.bzrdir)
         self.assertIsInstance(found_format, repository.RepositoryFormatMetaDir)
         self.assertEquals(found_format.features.get("name"), "necessity")

=== modified file 'bzrlib/tests/test_workingtree.py'
--- a/bzrlib/tests/test_workingtree.py	2011-12-11 03:49:52 +0000
+++ b/bzrlib/tests/test_workingtree.py	2011-12-16 12:41:56 +0000
@@ -146,10 +146,6 @@
         t.put_bytes('format', self.get_format_string())
         return 'A tree'
 
-    @classmethod
-    def from_string(cls, format_string):
-        return cls()
-
     def is_supported(self):
         return False
 
@@ -250,7 +246,7 @@
     def test_find_format_with_features(self):
         tree = self.make_branch_and_tree('.', format='2a')
         tree.control_transport.put_bytes('format',
-            tree._format.get_format_string() + "necessity feature name\n")
+            tree._format.get_format_string() + "[features]\nname = necessity\n")
         found_format = workingtree.WorkingTreeFormatMetaDir.find_format(
             tree.bzrdir)
         self.assertIsInstance(found_format, workingtree.WorkingTreeFormat)



More information about the bazaar-commits mailing list