mirror of
https://github.com/django/django.git
synced 2025-08-21 01:09:13 +00:00
Fixed #26583 -- Silenced individual clashing name warnings in collectstatic's default verbosity.
Made collectstatic report individual destination conflicts only at verbosity 2+. Made verbosity level 1 report a summary count of skipped files.
This commit is contained in:
parent
6537732585
commit
6142e3f347
@ -25,6 +25,7 @@ class Command(BaseCommand):
|
|||||||
self.symlinked_files = []
|
self.symlinked_files = []
|
||||||
self.unmodified_files = []
|
self.unmodified_files = []
|
||||||
self.post_processed_files = []
|
self.post_processed_files = []
|
||||||
|
self.skipped_files = []
|
||||||
self.storage = staticfiles_storage
|
self.storage = staticfiles_storage
|
||||||
self.style = no_style()
|
self.style = no_style()
|
||||||
|
|
||||||
@ -134,12 +135,13 @@ class Command(BaseCommand):
|
|||||||
found_files[prefixed_path] = (storage, path)
|
found_files[prefixed_path] = (storage, path)
|
||||||
handler(path, prefixed_path, storage)
|
handler(path, prefixed_path, storage)
|
||||||
else:
|
else:
|
||||||
|
self.skipped_files.append(prefixed_path)
|
||||||
self.log(
|
self.log(
|
||||||
"Found another file with the destination path '%s'. It "
|
"Found another file with the destination path '%s'. It "
|
||||||
"will be ignored since only the first encountered file "
|
"will be ignored since only the first encountered file "
|
||||||
"is collected. If this is not what you want, make sure "
|
"is collected. If this is not what you want, make sure "
|
||||||
"every static file has a unique path." % prefixed_path,
|
"every static file has a unique path." % prefixed_path,
|
||||||
level=1,
|
level=2,
|
||||||
)
|
)
|
||||||
|
|
||||||
# Storage backends may define a post_process() method.
|
# Storage backends may define a post_process() method.
|
||||||
@ -165,6 +167,7 @@ class Command(BaseCommand):
|
|||||||
"modified": self.copied_files + self.symlinked_files,
|
"modified": self.copied_files + self.symlinked_files,
|
||||||
"unmodified": self.unmodified_files,
|
"unmodified": self.unmodified_files,
|
||||||
"post_processed": self.post_processed_files,
|
"post_processed": self.post_processed_files,
|
||||||
|
"skipped": self.skipped_files,
|
||||||
}
|
}
|
||||||
|
|
||||||
def handle(self, **options):
|
def handle(self, **options):
|
||||||
@ -212,9 +215,10 @@ class Command(BaseCommand):
|
|||||||
modified_count = len(collected["modified"])
|
modified_count = len(collected["modified"])
|
||||||
unmodified_count = len(collected["unmodified"])
|
unmodified_count = len(collected["unmodified"])
|
||||||
post_processed_count = len(collected["post_processed"])
|
post_processed_count = len(collected["post_processed"])
|
||||||
|
skipped_count = len(collected["skipped"])
|
||||||
return (
|
return (
|
||||||
"\n%(modified_count)s %(identifier)s %(action)s"
|
"\n%(modified_count)s %(identifier)s %(action)s"
|
||||||
"%(destination)s%(unmodified)s%(post_processed)s."
|
"%(destination)s%(unmodified)s%(post_processed)s%(skipped)s."
|
||||||
) % {
|
) % {
|
||||||
"modified_count": modified_count,
|
"modified_count": modified_count,
|
||||||
"identifier": "static file" + ("" if modified_count == 1 else "s"),
|
"identifier": "static file" + ("" if modified_count == 1 else "s"),
|
||||||
@ -232,6 +236,11 @@ class Command(BaseCommand):
|
|||||||
and ", %s post-processed" % post_processed_count
|
and ", %s post-processed" % post_processed_count
|
||||||
or ""
|
or ""
|
||||||
),
|
),
|
||||||
|
"skipped": (
|
||||||
|
", %s skipped due to conflict" % skipped_count
|
||||||
|
if collected["skipped"]
|
||||||
|
else ""
|
||||||
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
def log(self, msg, level=2):
|
def log(self, msg, level=2):
|
||||||
|
@ -470,6 +470,10 @@ Miscellaneous
|
|||||||
* The minimum supported version of ``asgiref`` is increased from 3.8.1 to
|
* The minimum supported version of ``asgiref`` is increased from 3.8.1 to
|
||||||
3.9.1.
|
3.9.1.
|
||||||
|
|
||||||
|
* The :djadmin:`collectstatic` command now reports only a summary of skipped
|
||||||
|
files due to conflicts when ``--verbosity`` is 1. To see warnings for each
|
||||||
|
conflicting destination path, set the ``--verbosity`` flag to 2 or higher.
|
||||||
|
|
||||||
.. _deprecated-features-6.0:
|
.. _deprecated-features-6.0:
|
||||||
|
|
||||||
Features deprecated in 6.0
|
Features deprecated in 6.0
|
||||||
|
@ -508,15 +508,17 @@ class TestCollectionOverwriteWarning(CollectionTestCase):
|
|||||||
# looking for was emitted.
|
# looking for was emitted.
|
||||||
warning_string = "Found another file"
|
warning_string = "Found another file"
|
||||||
|
|
||||||
def _collectstatic_output(self, **kwargs):
|
def _collectstatic_output(self, verbosity=3, **kwargs):
|
||||||
"""
|
"""
|
||||||
Run collectstatic, and capture and return the output. We want to run
|
Run collectstatic, and capture and return the output.
|
||||||
the command at highest verbosity, which is why we can't
|
|
||||||
just call e.g. BaseCollectionTestCase.run_collectstatic()
|
|
||||||
"""
|
"""
|
||||||
out = StringIO()
|
out = StringIO()
|
||||||
call_command(
|
call_command(
|
||||||
"collectstatic", interactive=False, verbosity=3, stdout=out, **kwargs
|
"collectstatic",
|
||||||
|
interactive=False,
|
||||||
|
verbosity=verbosity,
|
||||||
|
stdout=out,
|
||||||
|
**kwargs,
|
||||||
)
|
)
|
||||||
return out.getvalue()
|
return out.getvalue()
|
||||||
|
|
||||||
@ -527,9 +529,10 @@ class TestCollectionOverwriteWarning(CollectionTestCase):
|
|||||||
output = self._collectstatic_output(clear=True)
|
output = self._collectstatic_output(clear=True)
|
||||||
self.assertNotIn(self.warning_string, output)
|
self.assertNotIn(self.warning_string, output)
|
||||||
|
|
||||||
def test_warning(self):
|
def test_warning_at_verbosity_2(self):
|
||||||
"""
|
"""
|
||||||
There is a warning when there are duplicate destinations.
|
There is a warning when there are duplicate destinations at verbosity
|
||||||
|
2+.
|
||||||
"""
|
"""
|
||||||
with tempfile.TemporaryDirectory() as static_dir:
|
with tempfile.TemporaryDirectory() as static_dir:
|
||||||
duplicate = os.path.join(static_dir, "test", "file.txt")
|
duplicate = os.path.join(static_dir, "test", "file.txt")
|
||||||
@ -538,15 +541,42 @@ class TestCollectionOverwriteWarning(CollectionTestCase):
|
|||||||
f.write("duplicate of file.txt")
|
f.write("duplicate of file.txt")
|
||||||
|
|
||||||
with self.settings(STATICFILES_DIRS=[static_dir]):
|
with self.settings(STATICFILES_DIRS=[static_dir]):
|
||||||
output = self._collectstatic_output(clear=True)
|
output = self._collectstatic_output(clear=True, verbosity=2)
|
||||||
self.assertIn(self.warning_string, output)
|
self.assertIn(self.warning_string, output)
|
||||||
|
|
||||||
os.remove(duplicate)
|
def test_no_warning_at_verbosity_1(self):
|
||||||
|
"""
|
||||||
|
There is no individual warning at verbosity 1, but summary is shown.
|
||||||
|
"""
|
||||||
|
with tempfile.TemporaryDirectory() as static_dir:
|
||||||
|
duplicate = os.path.join(static_dir, "test", "file.txt")
|
||||||
|
os.mkdir(os.path.dirname(duplicate))
|
||||||
|
with open(duplicate, "w+") as f:
|
||||||
|
f.write("duplicate of file.txt")
|
||||||
|
|
||||||
# Make sure the warning went away again.
|
|
||||||
with self.settings(STATICFILES_DIRS=[static_dir]):
|
with self.settings(STATICFILES_DIRS=[static_dir]):
|
||||||
output = self._collectstatic_output(clear=True)
|
output = self._collectstatic_output(clear=True, verbosity=1)
|
||||||
self.assertNotIn(self.warning_string, output)
|
self.assertNotIn(self.warning_string, output)
|
||||||
|
self.assertIn("1 skipped due to conflict", output)
|
||||||
|
|
||||||
|
def test_summary_multiple_conflicts(self):
|
||||||
|
"""
|
||||||
|
Summary shows correct count for multiple conflicts.
|
||||||
|
"""
|
||||||
|
with tempfile.TemporaryDirectory() as static_dir:
|
||||||
|
duplicate1 = os.path.join(static_dir, "test", "file.txt")
|
||||||
|
os.makedirs(os.path.dirname(duplicate1))
|
||||||
|
with open(duplicate1, "w+") as f:
|
||||||
|
f.write("duplicate of file.txt")
|
||||||
|
duplicate2 = os.path.join(static_dir, "test", "file1.txt")
|
||||||
|
with open(duplicate2, "w+") as f:
|
||||||
|
f.write("duplicate of file1.txt")
|
||||||
|
duplicate3 = os.path.join(static_dir, "test", "nonascii.css")
|
||||||
|
shutil.copy2(duplicate1, duplicate3)
|
||||||
|
|
||||||
|
with self.settings(STATICFILES_DIRS=[static_dir]):
|
||||||
|
output = self._collectstatic_output(clear=True, verbosity=1)
|
||||||
|
self.assertIn("3 skipped due to conflict", output)
|
||||||
|
|
||||||
|
|
||||||
@override_settings(
|
@override_settings(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user