diff --git a/django/contrib/staticfiles/management/commands/collectstatic.py b/django/contrib/staticfiles/management/commands/collectstatic.py index db29ff73cc9..ef3bb67d7e4 100644 --- a/django/contrib/staticfiles/management/commands/collectstatic.py +++ b/django/contrib/staticfiles/management/commands/collectstatic.py @@ -173,22 +173,28 @@ class Command(BaseCommand): if self.is_local_storage() and self.storage.location: destination_path = self.storage.location message.append(':\n\n %s\n\n' % destination_path) + should_warn_user = ( + self.storage.exists(destination_path) and + any(self.storage.listdir(destination_path)) + ) else: destination_path = None message.append('.\n\n') + # Destination files existence not checked; play it safe and warn. + should_warn_user = True - if self.clear: - message.append('This will DELETE ALL FILES in this location!\n') - else: - message.append('This will overwrite existing files!\n') + if self.interactive and should_warn_user: + if self.clear: + message.append('This will DELETE ALL FILES in this location!\n') + else: + message.append('This will overwrite existing files!\n') - message.append( - 'Are you sure you want to do this?\n\n' - "Type 'yes' to continue, or 'no' to cancel: " - ) - - if self.interactive and input(''.join(message)) != 'yes': - raise CommandError("Collecting static files cancelled.") + message.append( + 'Are you sure you want to do this?\n\n' + "Type 'yes' to continue, or 'no' to cancel: " + ) + if input(''.join(message)) != 'yes': + raise CommandError("Collecting static files cancelled.") collected = self.collect() modified_count = len(collected['modified']) diff --git a/tests/staticfiles_tests/test_management.py b/tests/staticfiles_tests/test_management.py index 4cca3444909..6ac9794b34f 100644 --- a/tests/staticfiles_tests/test_management.py +++ b/tests/staticfiles_tests/test_management.py @@ -179,6 +179,7 @@ class TestCollectionClear(CollectionTestCase): class TestInteractiveMessages(CollectionTestCase): overwrite_warning_msg = "This will overwrite existing files!" delete_warning_msg = "This will DELETE ALL FILES in this location!" + files_copied_msg = "static files copied" @staticmethod def mock_input(stdout): @@ -209,6 +210,26 @@ class TestInteractiveMessages(CollectionTestCase): self.assertIn(self.overwrite_warning_msg, output) self.assertNotIn(self.delete_warning_msg, output) + def test_no_warning_when_staticdir_does_not_exist(self): + stdout = six.StringIO() + shutil.rmtree(six.text_type(settings.STATIC_ROOT)) + call_command('collectstatic', interactive=True, stdout=stdout) + output = force_text(stdout.getvalue()) + self.assertNotIn(self.overwrite_warning_msg, output) + self.assertNotIn(self.delete_warning_msg, output) + self.assertIn(self.files_copied_msg, output) + + def test_no_warning_for_empty_staticdir(self): + stdout = six.StringIO() + static_dir = tempfile.mkdtemp(prefix='collectstatic_empty_staticdir_test') + with override_settings(STATIC_ROOT=static_dir): + call_command('collectstatic', interactive=True, stdout=stdout) + shutil.rmtree(six.text_type(static_dir)) + output = force_text(stdout.getvalue()) + self.assertNotIn(self.overwrite_warning_msg, output) + self.assertNotIn(self.delete_warning_msg, output) + self.assertIn(self.files_copied_msg, output) + class TestCollectionExcludeNoDefaultIgnore(TestDefaults, CollectionTestCase): """