Loading django/contrib/staticfiles/management/commands/collectstatic.py +14 −8 Original line number Diff line number Diff line from __future__ import unicode_literals import os import sys from collections import OrderedDict from optparse import make_option Loading Loading @@ -82,11 +81,7 @@ class Command(NoArgsCommand): Split off from handle_noargs() to facilitate testing. """ if self.symlink: if sys.platform == 'win32': raise CommandError("Symlinking is not supported by this " "platform (%s)." % sys.platform) if not self.local: if self.symlink and not self.local: raise CommandError("Can't symlink to a remote destination.") if self.clear: Loading Loading @@ -279,7 +274,18 @@ class Command(NoArgsCommand): os.makedirs(os.path.dirname(full_path)) except OSError: pass try: os.symlink(source_path, full_path) except AttributeError: import platform raise CommandError("Symlinking is not supported by Python %s." % platform.python_version()) except NotImplementedError: import platform raise CommandError("Symlinking is not supported in this " "platform (%s)." % platform.platform()) except OSError as e: raise CommandError(e) if prefixed_path not in self.symlinked_files: self.symlinked_files.append(prefixed_path) Loading django/utils/_os.py +22 −0 Original line number Diff line number Diff line import os import stat import sys import tempfile from os.path import join, normcase, normpath, abspath, isabs, sep, dirname from django.utils.encoding import force_text Loading Loading @@ -99,3 +100,24 @@ def rmtree_errorhandler(func, path, exc_info): os.chmod(path, stat.S_IWRITE) # use the original function to repeat the operation func(path) def symlinks_supported(): """ A function to check if creating symlinks are supported in the host platform and/or if they are allowed to be created (e.g. on Windows it requires admin permissions). """ tmpdir = tempfile.mkdtemp() original_path = os.path.join(tmpdir, 'original') symlink_path = os.path.join(tmpdir, 'symlink') os.makedirs(original_path) try: os.symlink(original_path, symlink_path) supported = True except (OSError, NotImplementedError, AttributeError): supported = False else: os.remove(symlink_path) finally: return supported docs/releases/1.7.txt +3 −0 Original line number Diff line number Diff line Loading @@ -565,6 +565,9 @@ Management Commands * Management commands can now produce syntax colored output under Windows if the ANSICON third-party tool is installed and active. * :djadmin:`collectstatic` command with symlink option is now supported on Windows NT 6 (Windows Vista and newer). Models ^^^^^^ Loading tests/staticfiles_tests/tests.py +17 −16 Original line number Diff line number Diff line Loading @@ -17,7 +17,7 @@ from django.core.management import call_command from django.test import TestCase, override_settings from django.utils.encoding import force_text from django.utils.functional import empty from django.utils._os import rmtree_errorhandler, upath from django.utils._os import rmtree_errorhandler, upath, symlinks_supported from django.utils import six from django.contrib.staticfiles import finders, storage Loading Loading @@ -645,8 +645,9 @@ class TestCollectionSimpleCachedStorage(BaseCollectionTestCase, self.assertNotIn(b"cached/other.css", content) self.assertIn(b"other.deploy12345.css", content) if sys.platform != 'win32': @unittest.skipUnless(symlinks_supported(), "Must be able to symlink to run this test.") class TestCollectionLinks(CollectionTestCase, TestDefaults): """ Test ``--link`` option for ``collectstatic`` management command. Loading Loading
django/contrib/staticfiles/management/commands/collectstatic.py +14 −8 Original line number Diff line number Diff line from __future__ import unicode_literals import os import sys from collections import OrderedDict from optparse import make_option Loading Loading @@ -82,11 +81,7 @@ class Command(NoArgsCommand): Split off from handle_noargs() to facilitate testing. """ if self.symlink: if sys.platform == 'win32': raise CommandError("Symlinking is not supported by this " "platform (%s)." % sys.platform) if not self.local: if self.symlink and not self.local: raise CommandError("Can't symlink to a remote destination.") if self.clear: Loading Loading @@ -279,7 +274,18 @@ class Command(NoArgsCommand): os.makedirs(os.path.dirname(full_path)) except OSError: pass try: os.symlink(source_path, full_path) except AttributeError: import platform raise CommandError("Symlinking is not supported by Python %s." % platform.python_version()) except NotImplementedError: import platform raise CommandError("Symlinking is not supported in this " "platform (%s)." % platform.platform()) except OSError as e: raise CommandError(e) if prefixed_path not in self.symlinked_files: self.symlinked_files.append(prefixed_path) Loading
django/utils/_os.py +22 −0 Original line number Diff line number Diff line import os import stat import sys import tempfile from os.path import join, normcase, normpath, abspath, isabs, sep, dirname from django.utils.encoding import force_text Loading Loading @@ -99,3 +100,24 @@ def rmtree_errorhandler(func, path, exc_info): os.chmod(path, stat.S_IWRITE) # use the original function to repeat the operation func(path) def symlinks_supported(): """ A function to check if creating symlinks are supported in the host platform and/or if they are allowed to be created (e.g. on Windows it requires admin permissions). """ tmpdir = tempfile.mkdtemp() original_path = os.path.join(tmpdir, 'original') symlink_path = os.path.join(tmpdir, 'symlink') os.makedirs(original_path) try: os.symlink(original_path, symlink_path) supported = True except (OSError, NotImplementedError, AttributeError): supported = False else: os.remove(symlink_path) finally: return supported
docs/releases/1.7.txt +3 −0 Original line number Diff line number Diff line Loading @@ -565,6 +565,9 @@ Management Commands * Management commands can now produce syntax colored output under Windows if the ANSICON third-party tool is installed and active. * :djadmin:`collectstatic` command with symlink option is now supported on Windows NT 6 (Windows Vista and newer). Models ^^^^^^ Loading
tests/staticfiles_tests/tests.py +17 −16 Original line number Diff line number Diff line Loading @@ -17,7 +17,7 @@ from django.core.management import call_command from django.test import TestCase, override_settings from django.utils.encoding import force_text from django.utils.functional import empty from django.utils._os import rmtree_errorhandler, upath from django.utils._os import rmtree_errorhandler, upath, symlinks_supported from django.utils import six from django.contrib.staticfiles import finders, storage Loading Loading @@ -645,8 +645,9 @@ class TestCollectionSimpleCachedStorage(BaseCollectionTestCase, self.assertNotIn(b"cached/other.css", content) self.assertIn(b"other.deploy12345.css", content) if sys.platform != 'win32': @unittest.skipUnless(symlinks_supported(), "Must be able to symlink to run this test.") class TestCollectionLinks(CollectionTestCase, TestDefaults): """ Test ``--link`` option for ``collectstatic`` management command. Loading