[MERGE] Container format version 2
Andrew Bennetts
andrew at canonical.com
Tue Jul 17 06:46:12 BST 2007
Andrew Bennetts wrote:
> This primarily updates the container format to allow whitespace in record names.
[...]
Argh, ":wq<enter>y" is too ingrained in my muscle memory! (I use vim and mutt)
Here's the merge directive I forgot to attach. At some point I'll teach mutt to
complain if I try to send a [MERGE] email with no attachment...
-Andrew.
-------------- next part --------------
# Bazaar merge directive format 1
# revision_id: andrew.bennetts at canonical.com-20070717044423-\
# cetp5spep142xsr4
# target_branch: http://bazaar-vcs.org/bzr/bzr.dev
# testament_sha1: 6ddb5bed4f84527c5bae21b7837d876f03a9a087
# timestamp: 2007-07-17 15:27:30 +1000
# source_branch: http://people.ubuntu.com/~andrew/bzr/container-format
#
# Bazaar revision bundle v0.9
#
# message:
# Updates to "pack" format:
# * rename pack.py to container.py, to avoid confusion with the new "bzr pack"
# command.
# * bump format version. The only change is that all whitespace apart from
# '\n' is now allowed in record names, because it appears that file IDs can
# contain whitespace (even though bzr itself won't generate them, bzrlib will
# accept them).
# * format 1 is simply orphaned, no effort has been made to read the old format
# as to the best of my knowledge it isn't used yet. (Similarly there's no
# backwards compatibility for the module rename) I'll change this if someone
# needs it.
#
# committer: Andrew Bennetts <andrew.bennetts at canonical.com>
# date: Tue 2007-07-17 14:44:23.928999901 +1000
=== renamed file bzrlib/pack.py // bzrlib/container.py
--- bzrlib/pack.py
+++ bzrlib/container.py
@@ -24,22 +24,18 @@
from bzrlib import errors
-FORMAT_ONE = "Bazaar pack format 1 (introduced in 0.18)"
-
-
-_whitespace_re = re.compile('[\t\n\x0b\x0c\r ]')
+FORMAT_TWO = "Bazaar pack format 2 (introduced in 0.19)"
def _check_name(name):
"""Do some basic checking of 'name'.
- At the moment, this just checks that there are no whitespace characters in a
- name.
+ At the moment, this just makes sure there's no newline in name.
:raises InvalidRecordError: if name is not valid.
:seealso: _check_name_encoding
"""
- if _whitespace_re.search(name) is not None:
+ if '\n' in name:
raise errors.InvalidRecordError("%r is not a valid name." % (name,))
@@ -70,7 +66,7 @@
def begin(self):
"""Begin writing a container."""
- self.write_func(FORMAT_ONE + "\n")
+ self.write_func(FORMAT_TWO + "\n")
def end(self):
"""Finish writing a container."""
@@ -182,7 +178,7 @@
def _read_format(self):
format = self._read_line()
- if format != FORMAT_ONE:
+ if format != FORMAT_TWO:
raise errors.UnknownContainerFormatError(format)
def validate(self):
=== renamed file bzrlib/tests/test_pack.py // bzrlib/tests/test_container.py
--- bzrlib/tests/test_pack.py
+++ bzrlib/tests/test_container.py
@@ -14,12 +14,12 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-"""Tests for bzrlib.pack."""
+"""Tests for bzrlib.container."""
from cStringIO import StringIO
-from bzrlib import pack, errors, tests
+from bzrlib import container, errors, tests
class TestContainerWriter(tests.TestCase):
@@ -30,53 +30,53 @@
This uses None as the output stream to show that the constructor doesn't
try to use the output stream.
"""
- writer = pack.ContainerWriter(None)
+ writer = container.ContainerWriter(None)
def test_begin(self):
"""The begin() method writes the container format marker line."""
output = StringIO()
- writer = pack.ContainerWriter(output.write)
+ writer = container.ContainerWriter(output.write)
writer.begin()
- self.assertEqual('Bazaar pack format 1 (introduced in 0.18)\n',
+ self.assertEqual('Bazaar pack format 2 (introduced in 0.19)\n',
output.getvalue())
def test_end(self):
"""The end() method writes an End Marker record."""
output = StringIO()
- writer = pack.ContainerWriter(output.write)
+ writer = container.ContainerWriter(output.write)
writer.begin()
writer.end()
- self.assertEqual('Bazaar pack format 1 (introduced in 0.18)\nE',
+ self.assertEqual('Bazaar pack format 2 (introduced in 0.19)\nE',
output.getvalue())
def test_add_bytes_record_no_name(self):
"""Add a bytes record with no name."""
output = StringIO()
- writer = pack.ContainerWriter(output.write)
+ writer = container.ContainerWriter(output.write)
writer.begin()
writer.add_bytes_record('abc', names=[])
- self.assertEqual('Bazaar pack format 1 (introduced in 0.18)\nB3\n\nabc',
+ self.assertEqual('Bazaar pack format 2 (introduced in 0.19)\nB3\n\nabc',
output.getvalue())
def test_add_bytes_record_one_name(self):
"""Add a bytes record with one name."""
output = StringIO()
- writer = pack.ContainerWriter(output.write)
+ writer = container.ContainerWriter(output.write)
writer.begin()
writer.add_bytes_record('abc', names=['name1'])
self.assertEqual(
- 'Bazaar pack format 1 (introduced in 0.18)\n'
+ 'Bazaar pack format 2 (introduced in 0.19)\n'
'B3\nname1\n\nabc',
output.getvalue())
def test_add_bytes_record_two_names(self):
"""Add a bytes record with two names."""
output = StringIO()
- writer = pack.ContainerWriter(output.write)
+ writer = container.ContainerWriter(output.write)
writer.begin()
writer.add_bytes_record('abc', names=['name1', 'name2'])
self.assertEqual(
- 'Bazaar pack format 1 (introduced in 0.18)\n'
+ 'Bazaar pack format 2 (introduced in 0.19)\n'
'B3\nname1\nname2\n\nabc',
output.getvalue())
@@ -85,18 +85,18 @@
InvalidRecordError.
"""
output = StringIO()
- writer = pack.ContainerWriter(output.write)
+ writer = container.ContainerWriter(output.write)
writer.begin()
self.assertRaises(
errors.InvalidRecordError,
- writer.add_bytes_record, 'abc', names=['bad name'])
+ writer.add_bytes_record, 'abc', names=['name with \n char'])
class TestContainerReader(tests.TestCase):
def get_reader_for(self, bytes):
stream = StringIO(bytes)
- reader = pack.ContainerReader(stream)
+ reader = container.ContainerReader(stream)
return reader
def test_construct(self):
@@ -105,12 +105,12 @@
This uses None as the output stream to show that the constructor doesn't
try to use the input stream.
"""
- reader = pack.ContainerReader(None)
+ reader = container.ContainerReader(None)
def test_empty_container(self):
"""Read an empty container."""
reader = self.get_reader_for(
- "Bazaar pack format 1 (introduced in 0.18)\nE")
+ "Bazaar pack format 2 (introduced in 0.19)\nE")
self.assertEqual([], list(reader.iter_records()))
def test_unknown_format(self):
@@ -124,7 +124,7 @@
UnexpectedEndOfContainerError to be raised.
"""
reader = self.get_reader_for(
- "Bazaar pack format 1 (introduced in 0.18)\n")
+ "Bazaar pack format 2 (introduced in 0.19)\n")
iterator = reader.iter_records()
self.assertRaises(
errors.UnexpectedEndOfContainerError, iterator.next)
@@ -132,7 +132,7 @@
def test_unknown_record_type(self):
"""Unknown record types cause UnknownRecordTypeError to be raised."""
reader = self.get_reader_for(
- "Bazaar pack format 1 (introduced in 0.18)\nX")
+ "Bazaar pack format 2 (introduced in 0.19)\nX")
iterator = reader.iter_records()
self.assertRaises(
errors.UnknownRecordTypeError, iterator.next)
@@ -145,7 +145,7 @@
ContainerReader's integration with BytesRecordReader is working.
"""
reader = self.get_reader_for(
- "Bazaar pack format 1 (introduced in 0.18)\nB5\n\naaaaaE")
+ "Bazaar pack format 2 (introduced in 0.19)\nB5\n\naaaaaE")
expected_records = [([], 'aaaaa')]
self.assertEqual(
expected_records,
@@ -154,7 +154,7 @@
def test_validate_empty_container(self):
"""validate does not raise an error for a container with no records."""
- reader = self.get_reader_for("Bazaar pack format 1 (introduced in 0.18)\nE")
+ reader = self.get_reader_for("Bazaar pack format 2 (introduced in 0.19)\nE")
# No exception raised
reader.validate()
@@ -162,7 +162,7 @@
"""validate does not raise an error for a container with a valid record.
"""
reader = self.get_reader_for(
- "Bazaar pack format 1 (introduced in 0.18)\nB3\nname\n\nabcE")
+ "Bazaar pack format 2 (introduced in 0.19)\nB3\nname\n\nabcE")
# No exception raised
reader.validate()
@@ -172,7 +172,7 @@
It may raise either UnexpectedEndOfContainerError or
UnknownContainerFormatError, depending on exactly what the string is.
"""
- inputs = ["", "x", "Bazaar pack format 1 (introduced in 0.18)", "bad\n"]
+ inputs = ["", "x", "Bazaar pack format 2 (introduced in 0.19)", "bad\n"]
for input in inputs:
reader = self.get_reader_for(input)
self.assertRaises(
@@ -185,7 +185,7 @@
types.
"""
reader = self.get_reader_for(
- "Bazaar pack format 1 (introduced in 0.18)\nX")
+ "Bazaar pack format 2 (introduced in 0.19)\nX")
self.assertRaises(errors.UnknownRecordTypeError, reader.validate)
def test_validate_data_after_end_marker(self):
@@ -193,7 +193,7 @@
after the end of the container.
"""
reader = self.get_reader_for(
- "Bazaar pack format 1 (introduced in 0.18)\nEcrud")
+ "Bazaar pack format 2 (introduced in 0.19)\nEcrud")
self.assertRaises(
errors.ContainerHasExcessDataError, reader.validate)
@@ -202,7 +202,7 @@
container marker, even if the container up to this point has been valid.
"""
reader = self.get_reader_for(
- "Bazaar pack format 1 (introduced in 0.18)\n")
+ "Bazaar pack format 2 (introduced in 0.19)\n")
self.assertRaises(
errors.UnexpectedEndOfContainerError, reader.validate)
@@ -211,7 +211,7 @@
multiple times in the container.
"""
reader = self.get_reader_for(
- "Bazaar pack format 1 (introduced in 0.18)\n"
+ "Bazaar pack format 2 (introduced in 0.19)\n"
"B0\nname\n\n"
"B0\nname\n\n"
"E")
@@ -220,7 +220,7 @@
def test_validate_undecodeable_name(self):
"""Names that aren't valid UTF-8 cause validate to fail."""
reader = self.get_reader_for(
- "Bazaar pack format 1 (introduced in 0.18)\nB0\n\xcc\n\nE")
+ "Bazaar pack format 2 (introduced in 0.19)\nB0\n\xcc\n\nE")
self.assertRaises(errors.InvalidRecordError, reader.validate)
@@ -229,7 +229,7 @@
def get_reader_for(self, bytes):
stream = StringIO(bytes)
- reader = pack.BytesRecordReader(stream)
+ reader = container.BytesRecordReader(stream)
return reader
def test_record_with_no_name(self):
@@ -306,25 +306,6 @@
reader = self.get_reader_for("123\nname")
self.assertRaises(errors.UnexpectedEndOfContainerError, reader.read)
- def test_read_invalid_name_whitespace(self):
- """Names must have no whitespace."""
- # A name with a space.
- reader = self.get_reader_for("0\nbad name\n\n")
- self.assertRaises(errors.InvalidRecordError, reader.read)
-
- # A name with a tab.
- reader = self.get_reader_for("0\nbad\tname\n\n")
- self.assertRaises(errors.InvalidRecordError, reader.read)
-
- # A name with a vertical tab.
- reader = self.get_reader_for("0\nbad\vname\n\n")
- self.assertRaises(errors.InvalidRecordError, reader.read)
-
- def test_validate_whitespace_in_name(self):
- """Names must have no whitespace."""
- reader = self.get_reader_for("0\nbad name\n\n")
- self.assertRaises(errors.InvalidRecordError, reader.validate)
-
def test_validate_interrupted_prelude(self):
"""EOF during reading a record's prelude causes validate to fail."""
reader = self.get_reader_for("")
=== modified file bzrlib/tests/__init__.py
--- bzrlib/tests/__init__.py
+++ bzrlib/tests/__init__.py
@@ -2260,7 +2260,7 @@
'bzrlib.tests.test_commit_merge',
'bzrlib.tests.test_config',
'bzrlib.tests.test_conflicts',
- 'bzrlib.tests.test_pack',
+ 'bzrlib.tests.test_container',
'bzrlib.tests.test_counted_lock',
'bzrlib.tests.test_decorators',
'bzrlib.tests.test_delta',
=== modified directory // last-changed:andrew.bennetts at canonical.com-200707170
... 44423-cetp5spep142xsr4
# revision id: andrew.bennetts at canonical.com-20070717044423-cetp5spep142xsr4
# sha1: 6ddb5bed4f84527c5bae21b7837d876f03a9a087
# inventory sha1: 0d2ce96fbef2f0a80a0e65e46940aa919be6f4ec
# parent ids:
# pqm at pqm.ubuntu.com-20070716205413-42lqws7bkld2gbju
# base id: pqm at pqm.ubuntu.com-20070716205413-42lqws7bkld2gbju
# properties:
# branch-nick: container-format
More information about the bazaar
mailing list