From 0007a43198670a1716bc5ff2d0a659daa4c7cf63 Mon Sep 17 00:00:00 2001 From: Denis Cornehl Date: Fri, 16 May 2014 15:40:57 +0200 Subject: [PATCH] [1.7.X] Fixed #22557 -- ManifestStaticFilesStorage did not cleanup deleted files. When using ManifestStaticFilesStorage, deleted static files would be correctly cleaned up by "collectstatic --clear", but the manifest file would still contain the stale entries. Thanks to tedtieken for the report Backport of 3bec38888f6f4ee9245b004fcb9fe15b35cef469 from master. --- django/contrib/staticfiles/storage.py | 4 +++ tests/staticfiles_tests/tests.py | 44 +++++++++++++++++++++++++-- 2 files changed, 45 insertions(+), 3 deletions(-) diff --git a/django/contrib/staticfiles/storage.py b/django/contrib/staticfiles/storage.py index fd114e45d5..fbf5df2314 100644 --- a/django/contrib/staticfiles/storage.py +++ b/django/contrib/staticfiles/storage.py @@ -312,10 +312,14 @@ class ManifestFilesMixin(HashedFilesMixin): (self.manifest_name, self.manifest_version)) def post_process(self, *args, **kwargs): + self.hashed_files = OrderedDict() all_post_processed = super(ManifestFilesMixin, self).post_process(*args, **kwargs) for post_processed in all_post_processed: yield post_processed + self.save_manifest() + + def save_manifest(self): payload = {'paths': self.hashed_files, 'version': self.manifest_version} if self.exists(self.manifest_name): self.delete(self.manifest_name) diff --git a/tests/staticfiles_tests/tests.py b/tests/staticfiles_tests/tests.py index dec38e239d..764ffcf48c 100644 --- a/tests/staticfiles_tests/tests.py +++ b/tests/staticfiles_tests/tests.py @@ -59,15 +59,15 @@ class BaseStaticFilesTestCase(object): # run and pick up changes in settings.STATICFILES_DIRS. finders.get_finder.cache_clear() - testfiles_path = os.path.join(TEST_ROOT, 'apps', 'test', 'static', 'test') + self.testfiles_path = os.path.join(TEST_ROOT, 'apps', 'test', 'static', 'test') # To make sure SVN doesn't hangs itself with the non-ASCII characters # during checkout, we actually create one file dynamically. - self._nonascii_filepath = os.path.join(testfiles_path, '\u2297.txt') + self._nonascii_filepath = os.path.join(self.testfiles_path, '\u2297.txt') with codecs.open(self._nonascii_filepath, 'w', 'utf-8') as f: f.write("\u2297 in the app dir") # And also create the stupid hidden file to dwarf the setup.py's # package data handling. - self._hidden_filepath = os.path.join(testfiles_path, '.hidden') + self._hidden_filepath = os.path.join(self.testfiles_path, '.hidden') with codecs.open(self._hidden_filepath, 'w', 'utf-8') as f: f.write("should be ignored") self._backup_filepath = os.path.join( @@ -652,6 +652,19 @@ class TestCollectionManifestStorage(TestHashedFiles, BaseCollectionTestCase, """ Tests for the Cache busting storage """ + + def setUp(self): + super(TestCollectionManifestStorage, self).setUp() + + self._clear_filename = os.path.join(self.testfiles_path, 'cleared.txt') + with open(self._clear_filename, 'w') as f: + f.write('to be deleted in one test') + + def tearDown(self): + super(TestCollectionManifestStorage, self).tearDown() + if os.path.exists(self._clear_filename): + os.unlink(self._clear_filename) + def test_manifest_exists(self): filename = storage.staticfiles_storage.manifest_name path = storage.staticfiles_storage.path(filename) @@ -669,6 +682,31 @@ class TestCollectionManifestStorage(TestHashedFiles, BaseCollectionTestCase, manifest = storage.staticfiles_storage.load_manifest() self.assertEqual(hashed_files, manifest) + def test_clear_empties_manifest(self): + # collect the additional file + self.run_collectstatic() + + hashed_files = storage.staticfiles_storage.hashed_files + self.assertIn('test/cleared.txt', hashed_files) + + manifest_content = storage.staticfiles_storage.load_manifest() + self.assertIn('test/cleared.txt', manifest_content) + + original_path = storage.staticfiles_storage.path('test/cleared.txt') + self.assertTrue(os.path.exists(original_path)) + + # delete the original file form the app, collect with clear + os.unlink(self._clear_filename) + self.run_collectstatic(clear=True) + + self.assertFileNotFound(original_path) + + hashed_files = storage.staticfiles_storage.hashed_files + self.assertNotIn('test/cleared.txt', hashed_files) + + manifest_content = storage.staticfiles_storage.load_manifest() + self.assertNotIn('test/cleared.txt', manifest_content) + # we set DEBUG to False here since the template tag wouldn't work otherwise @override_settings(**dict(