From c2bfb6dc7b52688eaf503806bc68f80bcebcac2a Mon Sep 17 00:00:00 2001 From: Bruno Trindade Date: Wed, 25 Oct 2023 10:26:08 -0500 Subject: [PATCH 1/3] refactor: update SassFileStorage setup --- README.md | 26 +++++++++++++++----------- sass_processor/storage.py | 16 ++++++++++------ 2 files changed, 25 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 778b3da..65e4d8a 100644 --- a/README.md +++ b/README.md @@ -80,7 +80,7 @@ INSTALLED_APPS = [ ``` **django-sass-processor** is shipped with a special finder, to locate the generated `*.css` files -in the directory referred by `SASS_PROCESSOR_ROOT` (or, if unset `STATIC_ROOT`). Just add it to +in the directory referred by `STORAGES['sass_processor']['ROOT']` (or, if unset `STATIC_ROOT`). Just add it to your `settings.py`. If there is no `STATICFILES_FINDERS` in your `settings.py` don't forget to include the **Django** [default finders](https://docs.djangoproject.com/en/stable/ref/settings/#std:setting-STATICFILES_FINDERS). @@ -129,7 +129,7 @@ letter or number are intended to be included by the HTML tag ``. During development, or when `SASS_PROCESSOR_ENABLED = True`, the compiled file is placed into the -folder referenced by `SASS_PROCESSOR_ROOT` (if unset, this setting defaults to `STATIC_ROOT`). +folder referenced by `STORAGES['sass_processor']['ROOT']` (if unset, this setting defaults to `STATIC_ROOT`). Having a location outside of the working directory prevents to pollute your local `static/css/...` directories with auto-generated files. Therefore assure, that this directory is writable by the Django runserver. @@ -311,7 +311,7 @@ above command: This will remove all occurrences of previously generated `*.css` files. -Or you may compile results to the `SASS_PROCESSOR_ROOT` directory directy (if not specified - to +Or you may compile results to the `STORAGES['sass_processor']['ROOT']` directory directy (if not specified - to `STATIC_ROOT`): ```shell @@ -424,21 +424,23 @@ to the Django logger. ## Using other storage backends for compiled CSS files -Under the hood, SASS processor will use any storage configured in your settings as `STATICFILES_STORAGE`. +Under the hood, SASS processor will use any storage configured in your settings as `STORAGES['staticfiles']`. This means you can use anything you normally use for serving static files, e.g. S3. A custom Storage class can be used if your deployment needs to serve generated CSS files from elsewhere, e.g. when your static files storage is not writable at runtime and you nede to re-compile CSS -in production. To use a custom storage, configure it in `SASS_PROCESSOR_STORAGE`. You can also +in production. To use a custom storage, configure it in `STORAGES['sass_processor']['BACKEND']`. You can also configure a dictionary with options that will be passed to the storage class as keyword arguments -in `SASS_PROCESSOR_STORAGE_OPTIONS` (e.g. if you want to use `FileSystemStorage`, but with +in `STORAGES['sass_processor']['OPTIONS']` (e.g. if you want to use `FileSystemStorage`, but with a different `location` or `base_url`: ```python -SASS_PROCESSOR_STORAGE = 'django.core.files.storage.FileSystemStorage' -SASS_PROCESSOR_STORAGE_OPTIONS = { - 'location': '/srv/media/generated', - 'base_url': 'https://media.myapp.example.com/generated' +STORAGES['sass_processor'] = { + 'BACKEND': 'django.core.files.storage.FileSystemStorage', + 'OPTIONS': { + 'location': '/srv/media/generated', + 'base_url': 'https://media.myapp.example.com/generated' + } } ``` @@ -449,7 +451,9 @@ Using the S3 storage backend from [django-storages](https://django-storages.read with its regular configuration (if you do not otherwise use it for service static files): ```python -SASS_PROCESSOR_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage' +STORAGES['sass_processor'] = { + 'BACKEND': 'storages.backends.s3boto3.S3Boto3Storage' +} ``` diff --git a/sass_processor/storage.py b/sass_processor/storage.py index 8c13def..a4df7ba 100644 --- a/sass_processor/storage.py +++ b/sass_processor/storage.py @@ -1,17 +1,21 @@ from django.conf import settings from django.contrib.staticfiles.finders import get_finders -from django.core.files.storage import FileSystemStorage, get_storage_class +from django.core.files.storage import FileSystemStorage from django.utils.functional import LazyObject +from django.utils.module_loading import import_string class SassFileStorage(LazyObject): def _setup(self): - storage_path = getattr(settings, 'SASS_PROCESSOR_STORAGE', settings.STATICFILES_STORAGE) - storage_options = getattr(settings, 'SASS_PROCESSOR_STORAGE_OPTIONS', {}) - storage_class = get_storage_class(storage_path) + staticfiles_storage_backend = settings.STORAGES.get("staticfiles", {}).get("BACKEND") + sass_processor_storage = settings.STORAGES.get("sass_processor", {}) - if storage_path == settings.STATICFILES_STORAGE and issubclass(storage_class, FileSystemStorage): - storage_options['location'] = getattr(settings, 'SASS_PROCESSOR_ROOT', settings.STATIC_ROOT) + storage_path = sass_processor_storage.get("BACKEND") or staticfiles_storage_backend + storage_options = sass_processor_storage.get("OPTIONS") or {} + storage_class = import_string(storage_path) + + if storage_path == staticfiles_storage_backend and issubclass(storage_class, FileSystemStorage): + storage_options['location'] = storage_options.get("ROOT") or settings.STATIC_ROOT storage_options['base_url'] = settings.STATIC_URL self._wrapped = storage_class(**storage_options) From 1e4416f33d243f294e0f9527cf04cc516625180e Mon Sep 17 00:00:00 2001 From: Bruno Trindade Date: Wed, 25 Oct 2023 15:29:02 -0500 Subject: [PATCH 2/3] feat: update github tests workflows --- .github/workflows/tests.yml | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index df8b601..76e4fe3 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -13,14 +13,7 @@ jobs: strategy: matrix: python-version: ["3.7", "3.8", "3.9", "3.10"] - django-version: ["2.2", "3.2", "4.0"] - exclude: - - python-version: 3.9 - django-version: 2.2 - - python-version: 3.10 - django-version: 2.2 - - python-version: 3.7 - django-version: 4.0 + django-version: ["4.2"] steps: - uses: actions/checkout@v3 From 20483483a2876e9ce3e18c7b2772ebbe447afc2b Mon Sep 17 00:00:00 2001 From: Bruno Trindade Date: Sat, 4 Nov 2023 00:00:40 -0500 Subject: [PATCH 3/3] feat: add retrocompatibility for Django <= 4.1.* --- .github/workflows/tests.yml | 13 ++++++++++++- README.md | 25 ++++++++++++++++++++----- sass_processor/storage.py | 24 +++++++++++++++++------- setup.cfg | 3 ++- 4 files changed, 51 insertions(+), 14 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 76e4fe3..54587e9 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -13,7 +13,18 @@ jobs: strategy: matrix: python-version: ["3.7", "3.8", "3.9", "3.10"] - django-version: ["4.2"] + django-version: ["3.2", "4.0", "4.1", "4.2"] + exclude: + - python-version: 3.9 + django-version: 2.2 + - python-version: 3.10 + django-version: 2.2 + - python-version: 3.7 + django-version: 4.0 + - python-version: 3.7 + django-version: 4.1 + - python-version: 3.7 + django-version: 4.2 steps: - uses: actions/checkout@v3 diff --git a/README.md b/README.md index 65e4d8a..5e4cb94 100644 --- a/README.md +++ b/README.md @@ -80,7 +80,8 @@ INSTALLED_APPS = [ ``` **django-sass-processor** is shipped with a special finder, to locate the generated `*.css` files -in the directory referred by `STORAGES['sass_processor']['ROOT']` (or, if unset `STATIC_ROOT`). Just add it to +in the directory referred by `STORAGES['sass_processor']['ROOT']` (for Django >= 4.2.*) or +`SASS_PROCESSOR_ROOT` (for Django <= 4.1.*), or, if unset `STATIC_ROOT`. Just add it to your `settings.py`. If there is no `STATICFILES_FINDERS` in your `settings.py` don't forget to include the **Django** [default finders](https://docs.djangoproject.com/en/stable/ref/settings/#std:setting-STATICFILES_FINDERS). @@ -129,7 +130,8 @@ letter or number are intended to be included by the HTML tag ``. During development, or when `SASS_PROCESSOR_ENABLED = True`, the compiled file is placed into the -folder referenced by `STORAGES['sass_processor']['ROOT']` (if unset, this setting defaults to `STATIC_ROOT`). +folder referenced by `STORAGES['sass_processor']['ROOT']` (for Django >= 4.2.*) or `SASS_PROCESSOR_ROOT` (for Django <= 4.1.*). +If unset, this setting defaults to `STATIC_ROOT`. Having a location outside of the working directory prevents to pollute your local `static/css/...` directories with auto-generated files. Therefore assure, that this directory is writable by the Django runserver. @@ -311,7 +313,8 @@ above command: This will remove all occurrences of previously generated `*.css` files. -Or you may compile results to the `STORAGES['sass_processor']['ROOT']` directory directy (if not specified - to +Or you may compile results to the `STORAGES['sass_processor']['ROOT']` [Django >= 4.2.*] or `SASS_PROCESSOR_ROOT` +[Django <= 4.1.*] directory directy (if not specified - to `STATIC_ROOT`): ```shell @@ -431,10 +434,11 @@ A custom Storage class can be used if your deployment needs to serve generated C e.g. when your static files storage is not writable at runtime and you nede to re-compile CSS in production. To use a custom storage, configure it in `STORAGES['sass_processor']['BACKEND']`. You can also configure a dictionary with options that will be passed to the storage class as keyword arguments -in `STORAGES['sass_processor']['OPTIONS']` (e.g. if you want to use `FileSystemStorage`, but with -a different `location` or `base_url`: +in `STORAGES['sass_processor']['OPTIONS']` [Django >= 4.2.*] or `SASS_PROCESSOR_STORAGE_OPTIONS` [Django <= 4.1.*>] +(e.g. if you want to use `FileSystemStorage`, but with a different `location` or `base_url`: ```python +# For Django >= 4.2.* STORAGES['sass_processor'] = { 'BACKEND': 'django.core.files.storage.FileSystemStorage', 'OPTIONS': { @@ -442,6 +446,13 @@ STORAGES['sass_processor'] = { 'base_url': 'https://media.myapp.example.com/generated' } } + +# For Django <= 4.1.* +SASS_PROCESSOR_STORAGE = 'django.core.files.storage.FileSystemStorage' +SASS_PROCESSOR_STORAGE_OPTIONS = { + 'location': '/srv/media/generated', + 'base_url': 'https://media.myapp.example.com/generated' +} ``` @@ -451,9 +462,13 @@ Using the S3 storage backend from [django-storages](https://django-storages.read with its regular configuration (if you do not otherwise use it for service static files): ```python +# For Django >= 4.2.* STORAGES['sass_processor'] = { 'BACKEND': 'storages.backends.s3boto3.S3Boto3Storage' } + +# For Django <= 4.1.* +SASS_PROCESSOR_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage' ``` diff --git a/sass_processor/storage.py b/sass_processor/storage.py index a4df7ba..0adbf85 100644 --- a/sass_processor/storage.py +++ b/sass_processor/storage.py @@ -1,21 +1,31 @@ +from django import VERSION from django.conf import settings from django.contrib.staticfiles.finders import get_finders -from django.core.files.storage import FileSystemStorage +from django.core.files.storage import FileSystemStorage, get_storage_class from django.utils.functional import LazyObject from django.utils.module_loading import import_string class SassFileStorage(LazyObject): def _setup(self): - staticfiles_storage_backend = settings.STORAGES.get("staticfiles", {}).get("BACKEND") - sass_processor_storage = settings.STORAGES.get("sass_processor", {}) + version_parts = VERSION[:2] + if version_parts[0] > 4 or (version_parts[0] == 4 and version_parts[1] >= 2): + staticfiles_storage_backend = settings.STORAGES.get("staticfiles", {}).get("BACKEND") + sass_processor_storage = settings.STORAGES.get("sass_processor", {}) - storage_path = sass_processor_storage.get("BACKEND") or staticfiles_storage_backend - storage_options = sass_processor_storage.get("OPTIONS") or {} - storage_class = import_string(storage_path) + storage_path = sass_processor_storage.get("BACKEND") or staticfiles_storage_backend + storage_options = sass_processor_storage.get("OPTIONS") or {} + storage_class = import_string(storage_path) + else: + staticfiles_storage_backend = settings.STATICFILES_STORAGE + storage_path = getattr(settings, 'SASS_PROCESSOR_STORAGE', staticfiles_storage_backend) + storage_options = getattr(settings, 'SASS_PROCESSOR_STORAGE_OPTIONS', {}) + storage_class = get_storage_class(storage_path) + + storage_options["ROOT"] = getattr(settings, 'SASS_PROCESSOR_ROOT', settings.STATIC_ROOT) if storage_path == staticfiles_storage_backend and issubclass(storage_class, FileSystemStorage): - storage_options['location'] = storage_options.get("ROOT") or settings.STATIC_ROOT + storage_options['location'] = storage_options.pop("ROOT", None) or settings.STATIC_ROOT storage_options['base_url'] = settings.STATIC_URL self._wrapped = storage_class(**storage_options) diff --git a/setup.cfg b/setup.cfg index ca7c44d..86e8f40 100644 --- a/setup.cfg +++ b/setup.cfg @@ -23,9 +23,10 @@ classifiers = Programming Language :: Python :: 3.8 Programming Language :: Python :: 3.9 Programming Language :: Python :: 3.10 - Framework :: Django :: 2.2 Framework :: Django :: 3.2 Framework :: Django :: 4.0 + Framework :: Django :: 4.1 + Framework :: Django :: 4.2 [options] packages = find: