1
0
mirror of https://github.com/django/django.git synced 2025-07-19 17:19:12 +00:00

[1.9.x] Fixed #26297 -- Fixed collectstatic --clear crash if storage doesn't implement path().

Backport of 28bcff82c5ed4694f4761c303294ffafbd7096ce from master
This commit is contained in:
Berker Peksag 2016-03-14 05:17:05 +02:00 committed by Tim Graham
parent f49cfb76c7
commit b4bb2ad13d
4 changed files with 54 additions and 5 deletions

View File

@ -218,12 +218,16 @@ class Command(BaseCommand):
smart_text(fpath), level=1) smart_text(fpath), level=1)
else: else:
self.log("Deleting '%s'" % smart_text(fpath), level=1) self.log("Deleting '%s'" % smart_text(fpath), level=1)
full_path = self.storage.path(fpath) try:
if not os.path.exists(full_path) and os.path.lexists(full_path): full_path = self.storage.path(fpath)
# Delete broken symlinks except NotImplementedError:
os.unlink(full_path)
else:
self.storage.delete(fpath) self.storage.delete(fpath)
else:
if not os.path.exists(full_path) and os.path.lexists(full_path):
# Delete broken symlinks
os.unlink(full_path)
else:
self.storage.delete(fpath)
for d in dirs: for d in dirs:
self.clear_dir(os.path.join(path, d)) self.clear_dir(os.path.join(path, d))

View File

@ -27,3 +27,6 @@ Bugfixes
earlier versions of Django. earlier versions of Django.
* Fixed a memory leak in the cached template loader (:ticket:`26306`). * Fixed a memory leak in the cached template loader (:ticket:`26306`).
* Fixed a regression that caused ``collectstatic --clear`` to fail if the
storage doesn't implement ``path()`` (:ticket:`26297`).

View File

@ -1,5 +1,8 @@
import errno
import os
from datetime import datetime from datetime import datetime
from django.conf import settings
from django.contrib.staticfiles.storage import CachedStaticFilesStorage from django.contrib.staticfiles.storage import CachedStaticFilesStorage
from django.core.files import storage from django.core.files import storage
@ -22,6 +25,40 @@ class DummyStorage(storage.Storage):
return datetime.date(1970, 1, 1) return datetime.date(1970, 1, 1)
class PathNotImplementedStorage(storage.Storage):
def _save(self, name, content):
return 'dummy'
def _path(self, name):
return os.path.join(settings.STATIC_ROOT, name)
def exists(self, name):
return os.path.exists(self._path(name))
def listdir(self, path):
path = self._path(path)
directories, files = [], []
for entry in os.listdir(path):
if os.path.isdir(os.path.join(path, entry)):
directories.append(entry)
else:
files.append(entry)
return directories, files
def delete(self, name):
name = self._path(name)
if os.path.exists(name):
try:
os.remove(name)
except OSError as e:
if e.errno != errno.ENOENT:
raise
def path(self, name):
raise NotImplementedError
class SimpleCachedStaticFilesStorage(CachedStaticFilesStorage): class SimpleCachedStaticFilesStorage(CachedStaticFilesStorage):
def file_hash(self, name, content=None): def file_hash(self, name, content=None):

View File

@ -166,6 +166,11 @@ class TestCollectionClear(CollectionTestCase):
shutil.rmtree(six.text_type(settings.STATIC_ROOT)) shutil.rmtree(six.text_type(settings.STATIC_ROOT))
super(TestCollectionClear, self).run_collectstatic(clear=True) super(TestCollectionClear, self).run_collectstatic(clear=True)
@override_settings(STATICFILES_STORAGE='staticfiles_tests.storage.PathNotImplementedStorage')
def test_handle_path_notimplemented(self):
self.run_collectstatic()
self.assertFileNotFound('cleared.txt')
class TestCollectionExcludeNoDefaultIgnore(CollectionTestCase, TestDefaults): class TestCollectionExcludeNoDefaultIgnore(CollectionTestCase, TestDefaults):
""" """