summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJannis Leidel <jannis@leidel.info>2010-12-31 14:22:55 +0000
committerJannis Leidel <jannis@leidel.info>2010-12-31 14:22:55 +0000
commitd18d37ce291e8dae4c9444afa5ab59f99bd45ecc (patch)
treeeb30da382697f8f4d574e783ddcde07814637d72
parent0de63c96f2a230d8e768ea876b6eb4bc3c8f80dd (diff)
Added our own rmtree error handler to make sure we can delete correctly delete .svn directories when running the tests on Windows which are read-only for some reason.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@15120 bcc190cf-cafb-0310-a4f2-bffc1f526a37
-rw-r--r--django/utils/_os.py20
-rw-r--r--tests/regressiontests/staticfiles_tests/tests.py5
2 files changed, 24 insertions, 1 deletions
diff --git a/django/utils/_os.py b/django/utils/_os.py
index 7ec5ce114b..706268a74d 100644
--- a/django/utils/_os.py
+++ b/django/utils/_os.py
@@ -44,3 +44,23 @@ def safe_join(base, *paths):
raise ValueError('The joined path (%s) is located outside of the base '
'path component (%s)' % (final_path, base_path))
return final_path
+
+def rmtree_errorhandler(func, path, exc_info):
+ """
+ On Windows, some files are read-only (e.g. in in .svn dirs), so when
+ rmtree() tries to remove them, an exception is thrown.
+ We catch that here, remove the read-only attribute, and hopefully
+ continue without problems.
+ """
+ exctype, value = exc_info[:2]
+ # lookin for a windows error
+ if exctype is not WindowsError or 'Access is denied' not in str(value):
+ raise
+ # file type should currently be read only
+ if ((os.stat(path).st_mode & stat.S_IREAD) != stat.S_IREAD):
+ raise
+ # convert to read/write
+ os.chmod(path, stat.S_IWRITE)
+ # use the original function to repeat the operation
+ func(path)
+
diff --git a/tests/regressiontests/staticfiles_tests/tests.py b/tests/regressiontests/staticfiles_tests/tests.py
index 35ee74393b..cf532bb414 100644
--- a/tests/regressiontests/staticfiles_tests/tests.py
+++ b/tests/regressiontests/staticfiles_tests/tests.py
@@ -13,6 +13,7 @@ from django.core.management import call_command
from django.db.models.loading import load_app
from django.template import Template, Context
from django.test import TestCase
+from django.utils._os import rmtree_errorhandler
TEST_ROOT = os.path.normcase(os.path.dirname(__file__))
@@ -97,7 +98,9 @@ class BuildStaticTestCase(StaticFilesTestCase):
self.run_collectstatic()
def tearDown(self):
- shutil.rmtree(settings.STATIC_ROOT)
+ # Use our own error handler that can handle .svn dirs on Windows
+ shutil.rmtree(settings.STATIC_ROOT, ignore_errors=True,
+ onerror=rmtree_errorhandler)
settings.STATIC_ROOT = self.old_root
super(BuildStaticTestCase, self).tearDown()