From 5ab06bd117a08388e3102fc590e909d59e9a187b Mon Sep 17 00:00:00 2001 From: Gregory Szorc Date: Tue, 3 Sep 2013 19:38:07 -0700 Subject: [PATCH] Bug 911362 - FileCopier support for not removing unreferenced files; r=glandium --- python/mozbuild/mozpack/copier.py | 27 ++++++++++++--------- python/mozbuild/mozpack/test/test_copier.py | 16 ++++++++++++ 2 files changed, 31 insertions(+), 12 deletions(-) diff --git a/python/mozbuild/mozpack/copier.py b/python/mozbuild/mozpack/copier.py index f7023aa4870f..1db15ce70e0b 100644 --- a/python/mozbuild/mozpack/copier.py +++ b/python/mozbuild/mozpack/copier.py @@ -164,15 +164,17 @@ class FileCopier(FileRegistry): FileRegistry with the ability to copy the registered files to a separate directory. ''' - def copy(self, destination, skip_if_older=True): + def copy(self, destination, skip_if_older=True, remove_unaccounted=True): ''' Copy all registered files to the given destination path. The given destination can be an existing directory, or not exist at all. It can't be e.g. a file. The copy process acts a bit like rsync: files are not copied when they - don't need to (see mozpack.files for details on file.copy), and files - existing in the destination directory that aren't registered are - removed. + don't need to (see mozpack.files for details on file.copy). + + By default, files in the destination directory that aren't registered + are removed and empty directories are deleted. To disable removing of + unregistered files, pass remove_unaccounted=False. Returns a FileCopyResult that details what changed. ''' @@ -195,15 +197,16 @@ class FileCopier(FileRegistry): for f in files: actual_dest_files.add(os.path.normpath(os.path.join(root, f))) - for f in actual_dest_files - dest_files: - # Windows requires write access to remove files. - if os.name == 'nt' and not os.access(f, os.W_OK): - # It doesn't matter what we set the permissions to since we - # will remove this file shortly. - os.chmod(f, 0600) + if remove_unaccounted: + for f in actual_dest_files - dest_files: + # Windows requires write access to remove files. + if os.name == 'nt' and not os.access(f, os.W_OK): + # It doesn't matter what we set the permissions to since we + # will remove this file shortly. + os.chmod(f, 0600) - os.remove(f) - result.removed_files.add(f) + os.remove(f) + result.removed_files.add(f) for root, dirs, files in os.walk(destination): if files or dirs: diff --git a/python/mozbuild/mozpack/test/test_copier.py b/python/mozbuild/mozpack/test/test_copier.py index e8b81d102e98..f9fdbf24e393 100644 --- a/python/mozbuild/mozpack/test/test_copier.py +++ b/python/mozbuild/mozpack/test/test_copier.py @@ -155,6 +155,22 @@ class TestFileCopier(TestWithTmpDir): self.assertEqual(result.removed_files_count, 1) self.assertFalse(os.path.exists(p)) + def test_no_remove(self): + copier = FileCopier() + copier.add('foo', GeneratedFile('foo')) + + with open(self.tmppath('bar'), 'a'): + pass + + os.mkdir(self.tmppath('emptydir')) + + result = copier.copy(self.tmpdir, remove_unaccounted=False) + + self.assertEqual(self.all_files(self.tmpdir), set(['foo', 'bar'])) + self.assertEqual(result.removed_files, set()) + self.assertEqual(result.removed_directories, + set([self.tmppath('emptydir')])) + class TestFilePurger(TestWithTmpDir): def test_file_purger(self):