Rev 5834: (vila) Enable exporting all Tree types. (Aaron Bentley) in file:///home/pqm/archives/thelove/bzr/%2Btrunk/
Canonical.com Patch Queue Manager
pqm at pqm.ubuntu.com
Thu May 5 19:22:39 UTC 2011
At file:///home/pqm/archives/thelove/bzr/%2Btrunk/
------------------------------------------------------------
revno: 5834 [merge]
revision-id: pqm at pqm.ubuntu.com-20110505192233-6916128few7exzsh
parent: pqm at pqm.ubuntu.com-20110505180506-ddz84ffyd1kzt6r1
parent: v.ladeuil+lp at free.fr-20110505152626-xreg7hdju5l79ctk
committer: Canonical.com Patch Queue Manager <pqm at pqm.ubuntu.com>
branch nick: +trunk
timestamp: Thu 2011-05-05 19:22:33 +0000
message:
(vila) Enable exporting all Tree types. (Aaron Bentley)
added:
bzrlib/tests/per_tree/test_export.py test_export.py-20110428022357-nl4utfmq3fuwnjee-1
modified:
bzrlib/export/__init__.py __init__.py-20051114235828-1ba62cb4062304e6
bzrlib/export/zip_exporter.py zip_exporter.py-20051114235828-8f57f954fba6497e
bzrlib/tests/per_tree/__init__.py __init__.py-20060717075546-420s7b0bj9hzeowi-2
bzrlib/tests/test_export.py test_export.py-20090220201010-tpbxssdnezsvu9pk-1
bzrlib/tests/test_transform.py test_transaction.py-20060105172520-b3ffb3946550e6c4
bzrlib/transform.py transform.py-20060105172343-dd99e54394d91687
doc/en/release-notes/bzr-2.4.txt bzr2.4.txt-20110114053217-k7ym9jfz243fddjm-1
=== modified file 'bzrlib/export/__init__.py'
--- a/bzrlib/export/__init__.py 2011-03-14 12:18:38 +0000
+++ b/bzrlib/export/__init__.py 2011-04-28 06:45:01 +0000
@@ -1,4 +1,4 @@
-# Copyright (C) 2005-2010 Canonical Ltd
+# Copyright (C) 2005-2011 Canonical Ltd
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -143,35 +143,31 @@
:param subdir: None or the path of an entry to start exporting from.
:param skip_special: Whether to skip .bzr files.
"""
- inv = tree.inventory
- if subdir is None:
- subdir_object = None
- else:
- subdir_id = inv.path2id(subdir)
- if subdir_id is not None:
- subdir_object = inv[subdir_id]
- # XXX: subdir is path not an id, so NoSuchId isn't proper error
- else:
- raise errors.NoSuchId(tree, subdir)
- if subdir_object is not None and subdir_object.kind != 'directory':
- yield subdir_object.name, subdir_object
- return
- else:
- entries = inv.iter_entries(subdir_object)
- if subdir is None:
- entries.next() # skip root
- for entry in entries:
+ if subdir == '':
+ subdir = None
+ if subdir is not None:
+ subdir = subdir.rstrip('/')
+ entries = tree.iter_entries_by_dir()
+ entries.next() # skip root
+ for path, entry in entries:
# The .bzr* namespace is reserved for "magic" files like
# .bzrignore and .bzrrules - do not export these
- if skip_special and entry[0].startswith(".bzr"):
+ if skip_special and path.startswith(".bzr"):
continue
- if subdir is None:
- if not tree.has_filename(entry[0]):
+ if path == subdir:
+ if entry.kind == 'directory':
+ continue
+ final_path = entry.name
+ elif subdir is not None:
+ if path.startswith(subdir + '/'):
+ final_path = path[len(subdir) + 1:]
+ else:
continue
else:
- if not tree.has_filename(os.path.join(subdir, entry[0])):
- continue
- yield entry
+ final_path = path
+ if not tree.has_filename(path):
+ continue
+ yield final_path, entry
register_lazy_exporter(None, [], 'bzrlib.export.dir_exporter', 'dir_exporter')
=== modified file 'bzrlib/export/zip_exporter.py'
--- a/bzrlib/export/zip_exporter.py 2011-03-13 21:30:33 +0000
+++ b/bzrlib/export/zip_exporter.py 2011-04-30 00:08:00 +0000
@@ -99,7 +99,7 @@
date_time=date_time)
zinfo.compress_type = compression
zinfo.external_attr = _FILE_ATTR
- zipf.writestr(zinfo, ie.symlink_target)
+ zipf.writestr(zinfo, tree.get_symlink_target(file_id))
zipf.close()
=== modified file 'bzrlib/tests/per_tree/__init__.py'
--- a/bzrlib/tests/per_tree/__init__.py 2011-02-24 16:45:27 +0000
+++ b/bzrlib/tests/per_tree/__init__.py 2011-04-28 05:30:49 +0000
@@ -374,6 +374,7 @@
def load_tests(standard_tests, module, loader):
per_tree_mod_names = [
'annotate_iter',
+ 'export',
'get_file_mtime',
'get_file_with_stat',
'get_root_id',
=== added file 'bzrlib/tests/per_tree/test_export.py'
--- a/bzrlib/tests/per_tree/test_export.py 1970-01-01 00:00:00 +0000
+++ b/bzrlib/tests/per_tree/test_export.py 2011-05-05 15:24:56 +0000
@@ -0,0 +1,95 @@
+# Copyright (C) 2011 Canonical Ltd
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import os
+import tarfile
+import zipfile
+
+from bzrlib.export import export
+from bzrlib import osutils
+from bzrlib import tests
+from bzrlib.tests.per_tree import TestCaseWithTree
+
+
+class ExportTest(object):
+
+ def prepare_export(self):
+ work_a = self.make_branch_and_tree('wta')
+ self.build_tree_contents(
+ [('wta/file', 'a\nb\nc\nd\n'), ('wta/dir', '')])
+ work_a.add('file', 'file-id')
+ work_a.add('dir', 'dir-id')
+ work_a.commit('add file')
+ tree_a = self.workingtree_to_test_tree(work_a)
+ export(tree_a, 'output', self.exporter)
+
+ def prepare_symlink_export(self):
+ self.requireFeature(tests.SymlinkFeature)
+ work_a = self.make_branch_and_tree('wta')
+ os.symlink('target', 'wta/link')
+ work_a.add('link', 'link-id')
+ work_a.commit('add link')
+ tree_a = self.workingtree_to_test_tree(work_a)
+ export(tree_a, 'output', self.exporter)
+
+ def test_export(self):
+ self.prepare_export()
+ names = self.get_export_names()
+ self.assertIn('output/file', names)
+ self.assertIn('output/dir', names)
+
+ def test_export_symlink(self):
+ self.prepare_symlink_export()
+ names = self.get_export_names()
+ self.assertIn('output/link', names)
+
+
+class TestTar(ExportTest, TestCaseWithTree):
+
+ exporter = 'tar'
+
+ def get_export_names(self):
+ tf = tarfile.open('output')
+ try:
+ return tf.getnames()
+ finally:
+ tf.close()
+
+
+class TestZip(ExportTest, TestCaseWithTree):
+
+ exporter = 'zip'
+
+ def get_export_names(self):
+ zf = zipfile.ZipFile('output')
+ try:
+ return zf.namelist()
+ finally:
+ zf.close()
+
+ def test_export_symlink(self):
+ self.prepare_symlink_export()
+ names = self.get_export_names()
+ self.assertIn('output/link.lnk', names)
+
+
+class TestDir(ExportTest, TestCaseWithTree):
+
+ exporter = 'dir'
+
+ def get_export_names(self):
+ return [osutils.pathjoin('output', name)
+ for name in os.listdir('output')]
=== modified file 'bzrlib/tests/test_export.py'
--- a/bzrlib/tests/test_export.py 2011-04-15 07:01:22 +0000
+++ b/bzrlib/tests/test_export.py 2011-04-28 05:30:49 +0000
@@ -67,6 +67,17 @@
self.assertPathExists('target/b')
self.assertPathExists('target/b/c')
+ def test_empty_subdir(self):
+ self.build_tree(['source/', 'source/a', 'source/b/', 'source/b/c'])
+ wt = self.make_branch_and_tree('source')
+ wt.add(['a', 'b', 'b/c'])
+ wt.commit('1')
+ self.build_tree(['target/'])
+ export.export(wt, 'target', format="dir", subdir='')
+ self.assertPathExists('target/a')
+ self.assertPathExists('target/b')
+ self.assertPathExists('target/b/c')
+
def test_to_existing_nonempty_dir_fail(self):
self.build_tree(['source/', 'source/a', 'source/b/', 'source/b/c'])
wt = self.make_branch_and_tree('source')
=== modified file 'bzrlib/tests/test_transform.py'
--- a/bzrlib/tests/test_transform.py 2011-04-15 07:01:22 +0000
+++ b/bzrlib/tests/test_transform.py 2011-04-29 18:23:18 +0000
@@ -2651,6 +2651,18 @@
preview_mtime = preview_tree.get_file_mtime('file-id', 'renamed')
work_mtime = work_tree.get_file_mtime('file-id', 'file')
+ def test_get_file_size(self):
+ work_tree = self.make_branch_and_tree('tree')
+ self.build_tree_contents([('tree/old', 'old')])
+ work_tree.add('old', 'old-id')
+ preview = TransformPreview(work_tree)
+ self.addCleanup(preview.finalize)
+ new_id = preview.new_file('name', preview.root, 'contents', 'new-id',
+ 'executable')
+ tree = preview.get_preview_tree()
+ self.assertEqual(len('old'), tree.get_file_size('old-id'))
+ self.assertEqual(len('contents'), tree.get_file_size('new-id'))
+
def test_get_file(self):
preview = self.get_empty_preview()
preview.new_file('file', preview.root, 'contents', 'file-id')
@@ -3068,6 +3080,24 @@
merger.merge_type = Merge3Merger
merger.do_merge()
+ def test_has_filename(self):
+ wt = self.make_branch_and_tree('tree')
+ self.build_tree(['tree/unmodified', 'tree/removed', 'tree/modified'])
+ tt = TransformPreview(wt)
+ removed_id = tt.trans_id_tree_path('removed')
+ tt.delete_contents(removed_id)
+ tt.new_file('new', tt.root, 'contents')
+ modified_id = tt.trans_id_tree_path('modified')
+ tt.delete_contents(modified_id)
+ tt.create_file('modified-contents', modified_id)
+ self.addCleanup(tt.finalize)
+ tree = tt.get_preview_tree()
+ self.assertTrue(tree.has_filename('unmodified'))
+ self.assertFalse(tree.has_filename('not-present'))
+ self.assertFalse(tree.has_filename('removed'))
+ self.assertTrue(tree.has_filename('new'))
+ self.assertTrue(tree.has_filename('modified'))
+
def test_is_executable(self):
tree = self.make_branch_and_tree('tree')
preview = TransformPreview(tree)
=== modified file 'bzrlib/transform.py'
--- a/bzrlib/transform.py 2011-04-17 23:06:22 +0000
+++ b/bzrlib/transform.py 2011-04-29 23:11:10 +0000
@@ -1898,11 +1898,10 @@
path = self._tree_id_paths.get(trans_id)
if path is None:
return None
- file_id = self._tree.path2id(path)
- try:
- return self._tree.kind(file_id)
- except errors.NoSuchFile:
- return None
+ kind = self._tree.path_content_summary(path)[0]
+ if kind == 'missing':
+ kind = None
+ return kind
def _set_mode(self, trans_id, mode_id, typefunc):
"""Set the mode of new file contents.
@@ -1977,8 +1976,9 @@
vf.fallback_versionedfiles.append(base_vf)
return tree_revision
- def _stat_limbo_file(self, file_id):
- trans_id = self._transform.trans_id_file_id(file_id)
+ def _stat_limbo_file(self, file_id=None, trans_id=None):
+ if trans_id is None:
+ trans_id = self._transform.trans_id_file_id(file_id)
name = self._transform._limbo_name(trans_id)
return os.lstat(name)
@@ -2199,6 +2199,12 @@
def get_file_size(self, file_id):
"""See Tree.get_file_size"""
+ trans_id = self._transform.trans_id_file_id(file_id)
+ kind = self._transform.final_kind(trans_id)
+ if kind != 'file':
+ return None
+ if trans_id in self._transform._new_contents:
+ return self._stat_limbo_file(trans_id=trans_id).st_size
if self.kind(file_id) == 'file':
return self._transform._tree.get_file_size(file_id)
else:
@@ -2232,6 +2238,15 @@
except errors.NoSuchId:
return False
+ def has_filename(self, path):
+ trans_id = self._path2trans_id(path)
+ if trans_id in self._transform._new_contents:
+ return True
+ elif trans_id in self._transform._removed_contents:
+ return False
+ else:
+ return self._transform._tree.has_filename(path)
+
def path_content_summary(self, path):
trans_id = self._path2trans_id(path)
tt = self._transform
=== modified file 'doc/en/release-notes/bzr-2.4.txt'
--- a/doc/en/release-notes/bzr-2.4.txt 2011-05-05 06:11:43 +0000
+++ b/doc/en/release-notes/bzr-2.4.txt 2011-05-05 15:26:26 +0000
@@ -35,6 +35,9 @@
.. Fixes for situations where bzr would previously crash or give incorrect
or undesirable results.
+* All Tree types can now be exported as tar.*, zip or directories.
+ (Aaron Bentley)
+
Documentation
*************
More information about the bazaar-commits
mailing list