Rev 2604: Handle basic node adds. in http://people.ubuntu.com/~robertc/baz2.0/repository

Robert Collins robertc at robertcollins.net
Thu Jul 12 17:50:04 BST 2007


At http://people.ubuntu.com/~robertc/baz2.0/repository

------------------------------------------------------------
revno: 2604
revision-id: robertc at robertcollins.net-20070712164954-gtnnmqd5oyfob20t
parent: robertc at robertcollins.net-20070712155119-zmcbukds65jw3tou
committer: Robert Collins <robertc at robertcollins.net>
branch nick: repository
timestamp: Fri 2007-07-13 02:49:54 +1000
message:
  Handle basic node adds.
modified:
  bzrlib/errors.py               errors.py-20050309040759-20512168c4e14fbd
  bzrlib/index.py                index.py-20070712131115-lolkarso50vjr64s-1
  bzrlib/tests/test_errors.py    test_errors.py-20060210110251-41aba2deddf936a8
  bzrlib/tests/test_index.py     test_index.py-20070712131115-lolkarso50vjr64s-2
=== modified file 'bzrlib/errors.py'
--- a/bzrlib/errors.py	2007-07-12 15:51:19 +0000
+++ b/bzrlib/errors.py	2007-07-12 16:49:54 +0000
@@ -362,6 +362,15 @@
         self.value = value
 
 
+class BadIndexKey(BzrError):
+
+    _fmt = "The key '%(key)s' is not a valid key."
+
+    def __init__(self, key):
+        BzrError.__init__(self)
+        self.key = key
+
+
 class BadIndexOptions(BzrError):
 
     _fmt = "Could not parse options for index %(value)s."
@@ -371,6 +380,15 @@
         self.value = value
 
 
+class BadIndexValue(BzrError):
+
+    _fmt = "The value '%(value)s' is not a valid value."
+
+    def __init__(self, value):
+        BzrError.__init__(self)
+        self.value = value
+
+
 class BadOptionValue(BzrError):
 
     _fmt = """Bad value "%(value)s" for option "%(name)s"."""

=== modified file 'bzrlib/index.py'
--- a/bzrlib/index.py	2007-07-12 15:51:19 +0000
+++ b/bzrlib/index.py	2007-07-12 16:49:54 +0000
@@ -17,6 +17,7 @@
 """Indexing facilities."""
 
 from cStringIO import StringIO
+import re
 
 from bzrlib import errors
 
@@ -24,6 +25,10 @@
 _SIGNATURE = "Bazaar Graph Index 1\n"
 
 
+_whitespace_re = re.compile('[\t\n\x0b\x0c\r ]')
+_newline_null_re = re.compile('[\n\0]')
+
+
 class GraphIndexBuilder(object):
     """A builder that can build a GraphIndex."""
 
@@ -34,10 +39,29 @@
             entry.
         """
         self.reference_lists = reference_lists
+        self._nodes = []
+
+    def add_node(self, key, references, value):
+        """Add a node to the index.
+
+        :param key: The key. keys must be whitespace free utf8.
+        :param references: An iterable of iterables of keys. Each is a
+            reference to another key.
+        :param value: The value to associate with the key. It may be any
+            bytes as long as it does not contain \0 or \n.
+        """
+        if _whitespace_re.search(key) is not None:
+            raise errors.BadIndexKey(key)
+        if _newline_null_re.search(value) is not None:
+            raise errors.BadIndexValue(value)
+        self._nodes.append((key, references, value))
 
     def finish(self):
         lines = [_SIGNATURE]
         lines.append(_OPTION_NODE_REFS + str(self.reference_lists) + '\n')
+        for key, references, value in self._nodes:
+            flattened_references = ''
+            lines.append("%s\0%s\0%s\n" % (key, flattened_references, value))
         lines.append('\n')
         return StringIO(''.join(lines))
 
@@ -48,7 +72,7 @@
     The index maps keys to a list of key reference lists, and a value.
     Each node has the same number of key reference lists. Each key reference
     list can be empty or an arbitrary length. The value is an opaque NULL
-    terminated string.
+    terminated string without any newlines.
     """
 
     def __init__(self, transport, name):

=== modified file 'bzrlib/tests/test_errors.py'
--- a/bzrlib/tests/test_errors.py	2007-07-12 15:51:19 +0000
+++ b/bzrlib/tests/test_errors.py	2007-07-12 16:49:54 +0000
@@ -193,11 +193,21 @@
         self.assertEqual("Error in data for index foo.",
             str(error))
 
+    def test_bad_index_key(self):
+        error = errors.BadIndexKey("foo")
+        self.assertEqual("The key 'foo' is not a valid key.",
+            str(error))
+
     def test_bad_index_options(self):
         error = errors.BadIndexOptions("foo")
         self.assertEqual("Could not parse options for index foo.",
             str(error))
 
+    def test_bad_index_value(self):
+        error = errors.BadIndexValue("foo")
+        self.assertEqual("The value 'foo' is not a valid value.",
+            str(error))
+
     def test_bzrnewerror_is_deprecated(self):
         class DeprecatedError(errors.BzrNewError):
             pass

=== modified file 'bzrlib/tests/test_index.py'
--- a/bzrlib/tests/test_index.py	2007-07-12 15:51:19 +0000
+++ b/bzrlib/tests/test_index.py	2007-07-12 16:49:54 +0000
@@ -41,11 +41,33 @@
         contents = stream.read()
         self.assertEqual("Bazaar Graph Index 1\nnode_ref_lists=2\n\n", contents)
 
+    def test_build_index_one_node(self):
+        builder = GraphIndexBuilder()
+        builder.add_node('akey', (), 'data')
+        stream = builder.finish()
+        contents = stream.read()
+        self.assertEqual("Bazaar Graph Index 1\nnode_ref_lists=0\n"
+            "akey\0\0data\n\n", contents)
+
+    def test_build_index_bad_key(self):
+        builder = GraphIndexBuilder()
+        self.assertRaises(errors.BadIndexKey, builder.add_node, 'a key',
+            (), 'data')
+
+    def test_build_index_bad_data(self):
+        builder = GraphIndexBuilder()
+        self.assertRaises(errors.BadIndexValue, builder.add_node, 'akey',
+            (), 'data\naa')
+        self.assertRaises(errors.BadIndexValue, builder.add_node, 'akey',
+            (), 'data\0aa')
+
 
 class TestGraphIndex(TestCaseWithMemoryTransport):
 
-    def make_index(self, ref_lists=0):
+    def make_index(self, ref_lists=0, nodes=[]):
         builder = GraphIndexBuilder()
+        for node, references, value in nodes:
+            builder.add_node(node, references, value)
         stream = builder.finish()
         trans = self.get_transport()
         trans.put_file('index', stream)
@@ -94,3 +116,7 @@
     def test_validate_empty(self):
         index = self.make_index()
         index.validate()
+
+    def test_validate_no_refs_content(self):
+        index = self.make_index(nodes=[('key', (), 'value')])
+        index.validate()




More information about the bazaar-commits mailing list