[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 3bec38888f from master.
This commit is contained in:
Denis Cornehl 2014-05-16 15:40:57 +02:00 committed by Florian Apolloner
parent 3e2bb807b1
commit 0007a43198
2 changed files with 45 additions and 3 deletions

View File

@ -312,10 +312,14 @@ class ManifestFilesMixin(HashedFilesMixin):
(self.manifest_name, self.manifest_version)) (self.manifest_name, self.manifest_version))
def post_process(self, *args, **kwargs): def post_process(self, *args, **kwargs):
self.hashed_files = OrderedDict()
all_post_processed = super(ManifestFilesMixin, all_post_processed = super(ManifestFilesMixin,
self).post_process(*args, **kwargs) self).post_process(*args, **kwargs)
for post_processed in all_post_processed: for post_processed in all_post_processed:
yield post_processed yield post_processed
self.save_manifest()
def save_manifest(self):
payload = {'paths': self.hashed_files, 'version': self.manifest_version} payload = {'paths': self.hashed_files, 'version': self.manifest_version}
if self.exists(self.manifest_name): if self.exists(self.manifest_name):
self.delete(self.manifest_name) self.delete(self.manifest_name)

View File

@ -59,15 +59,15 @@ class BaseStaticFilesTestCase(object):
# run and pick up changes in settings.STATICFILES_DIRS. # run and pick up changes in settings.STATICFILES_DIRS.
finders.get_finder.cache_clear() 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 # To make sure SVN doesn't hangs itself with the non-ASCII characters
# during checkout, we actually create one file dynamically. # 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: with codecs.open(self._nonascii_filepath, 'w', 'utf-8') as f:
f.write("\u2297 in the app dir") f.write("\u2297 in the app dir")
# And also create the stupid hidden file to dwarf the setup.py's # And also create the stupid hidden file to dwarf the setup.py's
# package data handling. # 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: with codecs.open(self._hidden_filepath, 'w', 'utf-8') as f:
f.write("should be ignored") f.write("should be ignored")
self._backup_filepath = os.path.join( self._backup_filepath = os.path.join(
@ -652,6 +652,19 @@ class TestCollectionManifestStorage(TestHashedFiles, BaseCollectionTestCase,
""" """
Tests for the Cache busting storage 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): def test_manifest_exists(self):
filename = storage.staticfiles_storage.manifest_name filename = storage.staticfiles_storage.manifest_name
path = storage.staticfiles_storage.path(filename) path = storage.staticfiles_storage.path(filename)
@ -669,6 +682,31 @@ class TestCollectionManifestStorage(TestHashedFiles, BaseCollectionTestCase,
manifest = storage.staticfiles_storage.load_manifest() manifest = storage.staticfiles_storage.load_manifest()
self.assertEqual(hashed_files, 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 # we set DEBUG to False here since the template tag wouldn't work otherwise
@override_settings(**dict( @override_settings(**dict(