Opened 3 years ago

Closed 3 years ago

Last modified 3 years ago

#23986 closed Bug (fixed)

Collectstatic --clear fails if the static dir doesn't exist yet

Reported by: Michael Owned by: Sztrovacsek
Component: contrib.staticfiles Version: 1.7
Severity: Normal Keywords:
Cc: Triage Stage: Ready for checkin
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: yes UI/UX: no

Description

The --clear flag on collectstatic fails if the target directory doesn't exist yet.

Traceback (most recent call last):
  File "redacted/bin/manage.py", line 16, in <module>
    execute_from_command_line(sys.argv)
  File "redacted/local/lib/python2.7/site-packages/django/core/management/__init__.py", line 385, in execute_from_command_line
    utility.execute()
  File "redacted/local/lib/python2.7/site-packages/django/core/management/__init__.py", line 377, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "redacted/local/lib/python2.7/site-packages/django/core/management/base.py", line 288, in run_from_argv
    self.execute(*args, **options.__dict__)
  File "redacted/local/lib/python2.7/site-packages/django/core/management/base.py", line 338, in execute
    output = self.handle(*args, **options)
  File "redacted/local/lib/python2.7/site-packages/django/core/management/base.py", line 533, in handle
    return self.handle_noargs(**options)
  File "redacted/local/lib/python2.7/site-packages/django/contrib/staticfiles/management/commands/collectstatic.py", line 168, in handle_noargs
    collected = self.collect()
  File "redacted/local/lib/python2.7/site-packages/django/contrib/staticfiles/management/commands/collectstatic.py", line 89, in collect
    self.clear_dir('')
  File "redacted/local/lib/python2.7/site-packages/django/contrib/staticfiles/management/commands/collectstatic.py", line 202, in clear_dir
    dirs, files = self.storage.listdir(path)
  File "redacted/local/lib/python2.7/site-packages/django/core/files/storage.py", line 270, in listdir
    for entry in os.listdir(path):
OSError: [Errno 2] No such file or directory: '/redacted/public/static/2.1.0-dev'

Adding

        if not os.path.exists(self.storage.location):
            return

In Command.clear_dir() fixes the issue

Change History (12)

comment:1 Changed 3 years ago by Tim Graham

Triage Stage: UnreviewedAccepted
Type: UncategorizedBug

comment:2 Changed 3 years ago by roebk

Owner: changed from nobody to roebk
Status: newassigned

comment:3 Changed 3 years ago by roebk

I've created a pull request for this ticket which can be viewed at https://github.com/django/django/pull/3721. I hope I've done everything to the correctly and to the required standard *fingers crossed*.

comment:4 Changed 3 years ago by Berker Peksag

Has patch: set
Needs tests: set

comment:5 Changed 3 years ago by Berker Peksag

Patch needs improvement: set

comment:6 Changed 3 years ago by roebk

For a little guidance and to ensure I implement the tests in the best possible way, what would be the best way in adding the test for a missing target directory? Should I be looking at adding a new class something along the lines of TestCollectionClearNoTargetDirectory?

For reference the current test of the --clear option is as follows:

class TestCollectionClear(CollectionTestCase):
    """
    Test the ``--clear`` option of the ``collectstatic`` management command.
    """
    def run_collectstatic(self, **kwargs):
        clear_filepath = os.path.join(settings.STATIC_ROOT, 'cleared.txt')
        with open(clear_filepath, 'w') as f:
            f.write('should be cleared')
        super(TestCollectionClear, self).run_collectstatic(clear=True)

    def test_cleared_not_found(self):
        self.assertFileNotFound('cleared.txt')

Thanks in advance :)

comment:7 Changed 3 years ago by Berker Peksag

You can just override the STATIC_ROOT setting and call self.run_collectstatic():

@override_settings(STATIC_ROOT=os.path.join(TEST_ROOT, 'project', 'site_media', 'static-does-not-exist'))
def test_empty_directory(self):
    self.run_collectstatic()

but, I think this is not the cleanest solution. You also don't need to call BaseCollectionTestCase.setUp() because it tries to create a directory if it doesn't exist: https://github.com/django/django/blob/master/tests/staticfiles_tests/tests.py#L132

I'd go with a new test case (without using BaseCollectionTestCase mixin).

comment:8 Changed 3 years ago by Sztrovacsek

Owner: changed from roebk to Sztrovacsek

comment:9 Changed 3 years ago by Sztrovacsek

Needs tests: unset

comment:10 Changed 3 years ago by Baptiste Mispelon

Patch needs improvement: unset
Triage Stage: AcceptedReady for checkin

Looks good to me, thanks!

comment:11 Changed 3 years ago by Tim Graham <timograham@…>

Resolution: fixed
Status: assignedclosed

In 87d78241a2fc85e5715fb51c554fe06e91deee58:

Fixed #23986 -- Fixed collectstatic --clear failure if STATIC_ROOT dir doesn't exist.

comment:12 Changed 3 years ago by Tim Graham <timograham@…>

In 389bacca:

Fixed staticfiles test on Windows; refs #23986.

Note: See TracTickets for help on using tickets.
Back to Top