diff --git a/.github/CONTRIBUTORS-template.md b/.github/CONTRIBUTORS-template.md index d8ba28c63..bc0928478 100644 --- a/.github/CONTRIBUTORS-template.md +++ b/.github/CONTRIBUTORS-template.md @@ -22,8 +22,8 @@ accept and merge pull requests. {%- endfor %} -*Audrey is also the creator of Cookiecutter. Audrey and Daniel are on -the Cookiecutter core team.* +_Audrey is also the creator of Cookiecutter. Audrey and Daniel are on +the Cookiecutter core team._ ## Other Contributors @@ -51,6 +51,6 @@ Listed in alphabetical order. The following haven't provided code directly, but have provided guidance and advice. -- Jannis Leidel -- Nate Aune -- Barry Morrison +- Jannis Leidel +- Nate Aune +- Barry Morrison diff --git a/.github/ISSUE_TEMPLATE/bug.md b/.github/ISSUE_TEMPLATE/bug.md index e984493d8..0e5ec12c4 100644 --- a/.github/ISSUE_TEMPLATE/bug.md +++ b/.github/ISSUE_TEMPLATE/bug.md @@ -12,41 +12,47 @@ labels: bug -* Host system configuration: - * Version of cookiecutter CLI (get it with `cookiecutter --version`): - * OS name and version: +- Host system configuration: - On Linux, run - ```bash - lsb_release -a 2> /dev/null || cat /etc/redhat-release 2> /dev/null || cat /etc/*-release 2> /dev/null || cat /etc/issue 2> /dev/null - ``` + - Version of cookiecutter CLI (get it with `cookiecutter --version`): + - OS name and version: - On MacOs, run - ```bash - sw_vers - ``` + On Linux, run - On Windows, via CMD, run - ``` - systeminfo | findstr /B /C:"OS Name" /C:"OS Version" - ``` - - - ```bash - # Insert here the OS name and version - - ``` - - * Python version, run `python3 -V`: - * Docker version (if using Docker), run `docker --version`: - * docker-compose version (if using Docker), run `docker-compose --version`: - * ... -* Options selected and/or [replay file](https://cookiecutter.readthedocs.io/en/latest/advanced/replay.html): - On Linux and MacOS: `cat ${HOME}/.cookiecutter_replay/cookiecutter-django.json` - (Please, take care to remove sensitive information) - ```json - # Insert here the replay file content + ```bash + lsb_release -a 2> /dev/null || cat /etc/redhat-release 2> /dev/null || cat /etc/*-release 2> /dev/null || cat /etc/issue 2> /dev/null ``` + + On MacOs, run + + ```bash + sw_vers + ``` + + On Windows, via CMD, run + + ``` + systeminfo | findstr /B /C:"OS Name" /C:"OS Version" + ``` + + ```bash + # Insert here the OS name and version + + ``` + + - Python version, run `python3 -V`: + - Docker version (if using Docker), run `docker --version`: + - docker-compose version (if using Docker), run `docker-compose --version`: + - ... + +- Options selected and/or [replay file](https://cookiecutter.readthedocs.io/en/latest/advanced/replay.html): + On Linux and macOS: `cat ${HOME}/.cookiecutter_replay/cookiecutter-django.json` + (Please, take care to remove sensitive information) + +```json + +``` + Logs:
diff --git a/.github/ISSUE_TEMPLATE/paid-support.md b/.github/ISSUE_TEMPLATE/paid-support.md index 9f997a8c8..f4e7578a8 100644 --- a/.github/ISSUE_TEMPLATE/paid-support.md +++ b/.github/ISSUE_TEMPLATE/paid-support.md @@ -5,8 +5,8 @@ about: Ask Core Team members to help you out Provided your question goes beyond [regular support](https://github.com/cookiecutter/cookiecutter-django/issues/new?template=question.md), and/or the task at hand is of timely/high priority nature use the below information to reach out for contributors directly. -* Daniel Roy Greenfeld, Project Lead ([GitHub](https://github.com/pydanny), [Patreon](https://www.patreon.com/danielroygreenfeld)): expertise in Django and AWS ELB. +- Bruno Alla, Core Developer ([GitHub](https://github.com/sponsors/browniebroke)). -* Nikita Shupeyko, Core Developer ([GitHub](https://github.com/webyneter)): expertise in Python/Django, hands-on DevOps and frontend experience. +- Daniel Roy Greenfeld, Project Lead ([GitHub](https://github.com/pydanny), [Patreon](https://www.patreon.com/danielroygreenfeld)): expertise in Django and AWS ELB. -* Bruno Alla, Core Developer ([GitHub](https://github.com/sponsors/browniebroke)). +- Nikita Shupeyko, Core Developer ([GitHub](https://github.com/webyneter)): expertise in Python/Django, hands-on DevOps and frontend experience. diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 10b66e266..2b197873f 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,6 +1,5 @@ - ## Description diff --git a/.github/changelog-template.md b/.github/changelog-template.md index 50aab38e1..64bb71790 100644 --- a/.github/changelog-template.md +++ b/.github/changelog-template.md @@ -1,8 +1,11 @@ {%- for change_type, pulls in grouped_pulls.items() %} {%- if pulls %} + ### {{ change_type }} + {%- for pull_request in pulls %} + - {{ pull_request.title }} ([#{{ pull_request.number }}]({{ pull_request.html_url }})) -{%- endfor -%} -{% endif -%} -{% endfor -%} + {%- endfor -%} + {% endif -%} + {% endfor -%} diff --git a/.github/contributors.json b/.github/contributors.json index c15476cc3..ca5762fe8 100644 --- a/.github/contributors.json +++ b/.github/contributors.json @@ -1377,5 +1377,15 @@ "name": "Arkadiusz Michał Ryś", "github_login": "arrys", "twitter_username": "" + }, + { + "name": "mpsantos", + "github_login": "mpsantos", + "twitter_username": "" + }, + { + "name": "Morten Kaae", + "github_login": "MortenKaae", + "twitter_username": "" } ] \ No newline at end of file diff --git a/.github/dependabot.yml b/.github/dependabot.yml index d95192f33..7642a3f2d 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -27,6 +27,11 @@ updates: directory: "{{cookiecutter.project_slug}}/compose/local/django/" schedule: interval: "daily" + ignore: + - dependency-name: "*" + update-types: + - "version-update:semver-major" + - "version-update:semver-minor" labels: - "update" @@ -34,6 +39,11 @@ updates: directory: "{{cookiecutter.project_slug}}/compose/local/docs/" schedule: interval: "daily" + ignore: + - dependency-name: "*" + update-types: + - "version-update:semver-major" + - "version-update:semver-minor" labels: - "update" @@ -55,6 +65,11 @@ updates: directory: "{{cookiecutter.project_slug}}/compose/production/django/" schedule: interval: "daily" + ignore: + - dependency-name: "*" + update-types: + - "version-update:semver-major" + - "version-update:semver-minor" labels: - "update" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c31be1b7a..c7cdda633 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -2,7 +2,7 @@ name: CI on: push: - branches: [ "master", "main" ] + branches: ["master", "main"] pull_request: concurrency: @@ -25,7 +25,7 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-python@v4 with: - python-version: "3.10" + python-version: "3.11" cache: pip - name: Install dependencies run: pip install -r requirements.txt @@ -38,7 +38,7 @@ jobs: matrix: script: - name: Basic - args: "" + args: "ci_tool=Gitlab" - name: Celery & DRF args: "use_celery=y use_drf=y" - name: Gulp @@ -56,7 +56,7 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-python@v4 with: - python-version: "3.10" + python-version: "3.11" cache: pip - name: Install dependencies run: pip install -r requirements.txt @@ -73,7 +73,9 @@ jobs: - name: Gulp args: "frontend_pipeline=Gulp" - name: Webpack - args: "frontend_pipeline=Webpack" + args: "frontend_pipeline=Webpack use_heroku=y" + - name: Email Username + args: "username_type=email ci_tool=Github" name: "Bare metal ${{ matrix.script.name }}" runs-on: ubuntu-latest @@ -98,7 +100,7 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-python@v4 with: - python-version: "3.10" + python-version: "3.11" cache: pip cache-dependency-path: | requirements.txt diff --git a/.github/workflows/django-issue-checker.yml b/.github/workflows/django-issue-checker.yml index fd250604f..cbfea922d 100644 --- a/.github/workflows/django-issue-checker.yml +++ b/.github/workflows/django-issue-checker.yml @@ -19,7 +19,7 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-python@v4 with: - python-version: "3.10" + python-version: "3.11" - name: Install dependencies run: | python -m pip install --upgrade pip diff --git a/.github/workflows/pre-commit-autoupdate.yml b/.github/workflows/pre-commit-autoupdate.yml index 1708e8b82..75bfe0a20 100644 --- a/.github/workflows/pre-commit-autoupdate.yml +++ b/.github/workflows/pre-commit-autoupdate.yml @@ -16,15 +16,15 @@ jobs: # Disables this workflow from running in a repository that is not part of the indicated organization/user if: github.repository_owner == 'cookiecutter' permissions: - contents: write # for peter-evans/create-pull-request to create branch - pull-requests: write # for peter-evans/create-pull-request to create a PR + contents: write # for peter-evans/create-pull-request to create branch + pull-requests: write # for peter-evans/create-pull-request to create a PR runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - uses: actions/setup-python@v4 with: - python-version: "3.10" + python-version: "3.11" - name: Install pre-commit run: pip install pre-commit @@ -37,7 +37,7 @@ jobs: run: pre-commit autoupdate - name: Create Pull Request - uses: peter-evans/create-pull-request@v4 + uses: peter-evans/create-pull-request@v5 with: token: ${{ secrets.GITHUB_TOKEN }} branch: update/pre-commit-autoupdate diff --git a/.github/workflows/update-changelog.yml b/.github/workflows/update-changelog.yml index 27113a89f..f48f297aa 100644 --- a/.github/workflows/update-changelog.yml +++ b/.github/workflows/update-changelog.yml @@ -19,7 +19,7 @@ jobs: - name: Set up Python uses: actions/setup-python@v4 with: - python-version: "3.10" + python-version: "3.11" - name: Install dependencies run: | python -m pip install --upgrade pip diff --git a/.github/workflows/update-contributors.yml b/.github/workflows/update-contributors.yml index 83c651a46..78d72c241 100644 --- a/.github/workflows/update-contributors.yml +++ b/.github/workflows/update-contributors.yml @@ -13,7 +13,7 @@ jobs: # Disables this workflow from running in a repository that is not part of the indicated organization/user if: github.repository_owner == 'cookiecutter' permissions: - contents: write # for stefanzweifel/git-auto-commit-action to push code in repo + contents: write # for stefanzweifel/git-auto-commit-action to push code in repo runs-on: ubuntu-latest steps: @@ -22,7 +22,7 @@ jobs: - name: Set up Python uses: actions/setup-python@v4 with: - python-version: "3.10" + python-version: "3.11" - name: Install dependencies run: | python -m pip install --upgrade pip diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 438de52b4..930465a57 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,4 +1,4 @@ -exclude: "{{cookiecutter.project_slug}}" +exclude: "{{cookiecutter.project_slug}}|.github/contributors.json|CHANGELOG.md|CONTRIBUTORS.md" default_stages: [commit] repos: @@ -6,17 +6,31 @@ repos: rev: v4.4.0 hooks: - id: trailing-whitespace + - id: end-of-file-fixer + - id: check-json + - id: check-toml + - id: check-xml - id: check-yaml + - id: debug-statements + - id: check-builtin-literals + - id: check-case-conflict + - id: detect-private-key + + - repo: https://github.com/pre-commit/mirrors-prettier + rev: "v3.0.0-alpha.6" + hooks: + - id: prettier + args: ["--tab-width", "2"] - repo: https://github.com/asottile/pyupgrade rev: v3.3.1 hooks: - id: pyupgrade - args: [--py310-plus] + args: [--py311-plus] exclude: hooks/ - repo: https://github.com/psf/black - rev: 23.1.0 + rev: 23.3.0 hooks: - id: black diff --git a/CHANGELOG.md b/CHANGELOG.md index c06100e04..415b29a2e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,145 @@ All enhancements and patches to Cookiecutter Django will be documented in this f +## 2023.04.13 + +### Updated +- Update tox to 4.4.12 ([#4271](https://github.com/cookiecutter/cookiecutter-django/pull/4271)) + +## 2023.04.10 + +### Updated +- Update pytest-sugar to 0.9.7 ([#4269](https://github.com/cookiecutter/cookiecutter-django/pull/4269)) +- Update pytest to 7.3.0 ([#4268](https://github.com/cookiecutter/cookiecutter-django/pull/4268)) + +## 2023.04.07 + +### Updated +- Upgrade traefik to 2.9.10 ([#4267](https://github.com/cookiecutter/cookiecutter-django/pull/4267)) + +## 2023.04.05 + +### Changed +- Update indent for nginx config file ([#4260](https://github.com/cookiecutter/cookiecutter-django/pull/4260)) +### Updated +- Update tox to 4.4.11 ([#4262](https://github.com/cookiecutter/cookiecutter-django/pull/4262)) +- Update django to 4.1.8 ([#4258](https://github.com/cookiecutter/cookiecutter-django/pull/4258)) +- Update pre-commit to 3.2.2 ([#4259](https://github.com/cookiecutter/cookiecutter-django/pull/4259)) + +## 2023.04.04 + +### Changed +- Upgrade to Django 4.1 ([#4028](https://github.com/cookiecutter/cookiecutter-django/pull/4028)) +- Remove deprecated security setting ([#4247](https://github.com/cookiecutter/cookiecutter-django/pull/4247)) +### Fixed +- Replace `runserver_plus` with `runserver` ([#4255](https://github.com/cookiecutter/cookiecutter-django/pull/4255)) +- Fix traefik rule priority for media router ([#4244](https://github.com/cookiecutter/cookiecutter-django/pull/4244)) +### Updated +- Update sentry-sdk to 1.19.0 ([#4254](https://github.com/cookiecutter/cookiecutter-django/pull/4254)) +- Update django-debug-toolbar to 4.0.0 ([#4251](https://github.com/cookiecutter/cookiecutter-django/pull/4251)) + +## 2023.04.03 + +### Changed +- fix: Syntax for ignoring specific noqa errors ([#4250](https://github.com/cookiecutter/cookiecutter-django/pull/4250)) +### Updated +- Update psycopg2-binary to 2.9.6 ([#4249](https://github.com/cookiecutter/cookiecutter-django/pull/4249)) +- Update psycopg2 to 2.9.6 ([#4248](https://github.com/cookiecutter/cookiecutter-django/pull/4248)) + +## 2023.04.01 + +### Updated +- Update pytest-instafail to 0.5.0 ([#4240](https://github.com/cookiecutter/cookiecutter-django/pull/4240)) +- Update pillow to 9.5.0 ([#4242](https://github.com/cookiecutter/cookiecutter-django/pull/4242)) +- Update django-allauth to 0.54.0 ([#4241](https://github.com/cookiecutter/cookiecutter-django/pull/4241)) + +## 2023.03.29 + +### Updated +- Update redis to 4.5.4 ([#4239](https://github.com/cookiecutter/cookiecutter-django/pull/4239)) +- Update pytz to 2023.3 ([#4238](https://github.com/cookiecutter/cookiecutter-django/pull/4238)) +- Update black to 23.3.0 ([#4236](https://github.com/cookiecutter/cookiecutter-django/pull/4236)) + +## 2023.03.27 + +### Updated +- Update watchfiles to 0.19.0 ([#4232](https://github.com/cookiecutter/cookiecutter-django/pull/4232)) + +## 2023.03.26 + +### Updated +- Update pre-commit to 3.2.1 ([#4229](https://github.com/cookiecutter/cookiecutter-django/pull/4229)) + +## 2023.03.25 + +### Updated +- Update pytz to 2023.2 ([#4228](https://github.com/cookiecutter/cookiecutter-django/pull/4228)) + +## 2023.03.23 + +### Updated +- Bump traefik from 2.9.8 to 2.9.9 ([#4225](https://github.com/cookiecutter/cookiecutter-django/pull/4225)) + +## 2023.03.22 + +### Updated +- Update redis to 4.5.3 ([#4227](https://github.com/cookiecutter/cookiecutter-django/pull/4227)) + +## 2023.03.20 + +### Updated +- Update django-allauth to 0.53.1 ([#4223](https://github.com/cookiecutter/cookiecutter-django/pull/4223)) +- Update redis to 4.5.2 ([#4222](https://github.com/cookiecutter/cookiecutter-django/pull/4222)) + +## 2023.03.18 + +### Updated +- Update drf-spectacular to 0.26.1 ([#4221](https://github.com/cookiecutter/cookiecutter-django/pull/4221)) +- Update pygithub to 1.58.1 ([#4220](https://github.com/cookiecutter/cookiecutter-django/pull/4220)) +- Update pre-commit to 3.2.0 ([#4219](https://github.com/cookiecutter/cookiecutter-django/pull/4219)) + +## 2023.03.16 + +### Changed +- Pin base Python Docker images to bugfix ([#4194](https://github.com/cookiecutter/cookiecutter-django/pull/4194)) +### Fixed +- Trim leading and trailing space in `domain_name` and `email` ([#4163](https://github.com/cookiecutter/cookiecutter-django/pull/4163)) +### Updated +- Update djangorestframework-stubs to 1.10.0 ([#4217](https://github.com/cookiecutter/cookiecutter-django/pull/4217)) +- Update django-stubs to 1.16.0 ([#4216](https://github.com/cookiecutter/cookiecutter-django/pull/4216)) +- Update coverage to 7.2.2 ([#4218](https://github.com/cookiecutter/cookiecutter-django/pull/4218)) +- Update sentry-sdk to 1.17.0 ([#4215](https://github.com/cookiecutter/cookiecutter-django/pull/4215)) +- Bump Docker python image from 3.10.9 to 3.10.10 on production Django ([#4214](https://github.com/cookiecutter/cookiecutter-django/pull/4214)) +- Bump Docker python image from 3.10.9-slim-bullseye to 3.10.10-slim-bullseye for docs ([#4213](https://github.com/cookiecutter/cookiecutter-django/pull/4213)) +- Bump Docker python image from 3.10.9-slim-bullseye to 3.10.10-slim-bullseye for local Django service ([#4212](https://github.com/cookiecutter/cookiecutter-django/pull/4212)) +- Update uvicorn to 0.21.1 ([#4211](https://github.com/cookiecutter/cookiecutter-django/pull/4211)) +- Update django-allauth to 0.53.0 ([#4210](https://github.com/cookiecutter/cookiecutter-django/pull/4210)) + +## 2023.03.14 + +### Updated +- Update django-celery-beat to 2.5.0 ([#4208](https://github.com/cookiecutter/cookiecutter-django/pull/4208)) + +## 2023.03.13 + +### Updated +- Update uvicorn to 0.21.0 ([#4203](https://github.com/cookiecutter/cookiecutter-django/pull/4203)) +- Update django-anymail to 9.1 ([#4206](https://github.com/cookiecutter/cookiecutter-django/pull/4206)) +- Update tox to 4.4.7 ([#4207](https://github.com/cookiecutter/cookiecutter-django/pull/4207)) + +## 2023.03.09 + +### Fixed +- Fix the omit configuration for coverage ([#4201](https://github.com/cookiecutter/cookiecutter-django/pull/4201)) +### Updated +- Update ipdb to 0.13.13 ([#4202](https://github.com/cookiecutter/cookiecutter-django/pull/4202)) + +## 2023.03.07 + +### Updated +- Update mypy to 1.1.1 ([#4196](https://github.com/cookiecutter/cookiecutter-django/pull/4196)) +- Update django-environ to 0.10.0 ([#4195](https://github.com/cookiecutter/cookiecutter-django/pull/4195)) + ## 2023.03.04 ### Changed diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index 8a5fc4158..a7b21223b 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -1,3 +1,3 @@ ## Code of Conduct -Everyone who interacts in the Cookiecutter project's codebase, issue trackers, chat rooms, and mailing lists is expected to follow the [PyPA Code of Conduct](https://www.pypa.io/en/latest/code-of-conduct/). +Everyone who interacts in the Cookiecutter project's codebase, issue trackers, chat rooms, and mailing lists is expected to follow the [PSF Code of Conduct](https://www.python.org/psf/conduct/) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 69bce6f2e..94ecbdd7d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -2,41 +2,81 @@ Always happy to get issues identified and pull requests! -## Getting your pull request merged in +## General considerations -1. Keep it small. The smaller the pull request, the more likely we are to accept. -2. Pull requests that fix a current issue get priority for review. +1. Keep it small. The smaller the change, the more likely we are to accept. +2. Changes that fix a current issue get priority for review. +3. Check out [GitHub guide][submit-a-pr] if you've never created a pull request before. + +## Getting started + +1. Fork the repo +2. Clone your fork +3. Create a branch for your changes + +This last step is very important, don't start developing from master, it'll cause pain if you need to send another change later. ## Testing +You'll need to run the tests using Python 3.11. We recommend using [tox](https://tox.readthedocs.io/en/latest/) to run the tests. It will automatically create a fresh virtual environment and install our test dependencies, such as [pytest-cookies](https://pypi.python.org/pypi/pytest-cookies/) and [flake8](https://pypi.python.org/pypi/flake8/). + +We'll also run the tests on GitHub actions when you send your pull request, but it's a good idea to run them locally before you send it. + ### Installation -Please install [tox](https://tox.readthedocs.io/en/latest/), which is a generic virtualenv management and test command line tool. +First, make sure that your version of Python is 3.11: -[tox](https://tox.readthedocs.io/en/latest/) is available for download from [PyPI](https://pypi.python.org/pypi) via [pip](https://pypi.python.org/pypi/pip/): +```bash +$ python --version +Python 3.11.3 +``` - $ pip install tox +Any version that starts with 3.11 will do. If you need to install it, you can get it from [python.org](https://www.python.org/downloads/). -It will automatically create a fresh virtual environment and install our test dependencies, -such as [pytest-cookies](https://pypi.python.org/pypi/pytest-cookies/) and [flake8](https://pypi.python.org/pypi/flake8/). +Then install `tox`, if not already installed: -### Run the Tests +```bash +$ python -m pip install tox +``` -Tox uses pytest under the hood, hence it supports the same syntax for selecting tests. +### Run the template's test suite -For further information please consult the [pytest usage docs](https://pytest.org/latest/usage.html#specifying-tests-selecting-tests). +To run the tests of the template using the current Python version: -To run all tests using various versions of python in virtualenvs defined in tox.ini, just run tox.: +```bash +$ tox -e py +``` - $ tox +This uses `pytest `under the hood, and you can pass options to it after a `--`. So to run a particular test: -It is possible to test with a specific version of python. To do this, the command -is: +```bash +$ tox -e py -- -k test_default_configuration +``` - $ tox -e py310 +For further information, please consult the [pytest usage docs](https://pytest.org/en/latest/how-to/usage.html#specifying-which-tests-to-run). -This will run pytest with the python3.10 interpreter, for example. +### Run the generated project tests -To run a particular test with tox for against your current Python version: +The template tests are checking that the generated project is fully rendered and that it passes `flake8`. We also have some test scripts which generate a specific project combination, install the dependencies, run the tests of the generated project, install FE dependencies and generate the docs. They will install the template dependencies, so make sure you create and activate a virtual environment first. - $ tox -e py -- -k test_default_configuration +```bash +$ python -m venv venv +$ source venv/bin/activate +``` + +These tests are slower and can be run with or without Docker: + +- Without Docker: `scripts/test_bare.sh` (for bare metal) +- With Docker: `scripts/test_docker.sh` + +All arguments to these scripts will be passed to the `cookiecutter` CLI, letting you set options, for example: + +```bash +$ scripts/test_bare.sh use_celery=y +``` + +## Submitting a pull request + +Once you're happy with your changes and they look ok locally, push and send send [a pull request][submit-a-pr] to the main repo, which will trigger the tests on GitHub actions. If they fail, try to fix them. A maintainer should take a look at your change and give you feedback or merge it. + +[submit-a-pr]: https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index af99445d4..47ece91dc 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -76,8 +76,8 @@ accept and merge pull requests. -*Audrey is also the creator of Cookiecutter. Audrey and Daniel are on -the Cookiecutter core team.* +_Audrey is also the creator of Cookiecutter. Audrey and Daniel are on +the Cookiecutter core team._ ## Other Contributors @@ -1426,6 +1426,13 @@ Listed in alphabetical order. + + Morten Kaae + + MortenKaae + + + mozillazg @@ -1440,6 +1447,13 @@ Listed in alphabetical order. + + mpsantos + + mpsantos + + + Naveen @@ -1951,6 +1965,6 @@ Listed in alphabetical order. The following haven't provided code directly, but have provided guidance and advice. -- Jannis Leidel -- Nate Aune -- Barry Morrison \ No newline at end of file +- Jannis Leidel +- Nate Aune +- Barry Morrison \ No newline at end of file diff --git a/README.md b/README.md index 0987de885..988eb970a 100644 --- a/README.md +++ b/README.md @@ -12,58 +12,58 @@ Powered by [Cookiecutter](https://github.com/cookiecutter/cookiecutter), Cookiecutter Django is a framework for jumpstarting production-ready Django projects quickly. -- Documentation: -- See [Troubleshooting](https://cookiecutter-django.readthedocs.io/en/latest/troubleshooting.html) for common errors and obstacles -- If you have problems with Cookiecutter Django, please open [issues](https://github.com/cookiecutter/cookiecutter-django/issues/new) don't send - emails to the maintainers. +- Documentation: +- See [Troubleshooting](https://cookiecutter-django.readthedocs.io/en/latest/troubleshooting.html) for common errors and obstacles +- If you have problems with Cookiecutter Django, please open [issues](https://github.com/cookiecutter/cookiecutter-django/issues/new) don't send + emails to the maintainers. ## Features -- For Django 4.0 -- Works with Python 3.10 -- Renders Django projects with 100% starting test coverage -- Twitter [Bootstrap](https://github.com/twbs/bootstrap) v5 -- [12-Factor](http://12factor.net/) based settings via [django-environ](https://github.com/joke2k/django-environ) -- Secure by default. We believe in SSL. -- Optimized development and production settings -- Registration via [django-allauth](https://github.com/pennersr/django-allauth) -- Comes with custom user model ready to go -- Optional basic ASGI setup for Websockets -- Optional custom static build using Gulp or Webpack -- Send emails via [Anymail](https://github.com/anymail/django-anymail) (using [Mailgun](http://www.mailgun.com/) by default or Amazon SES if AWS is selected cloud provider, but switchable) -- Media storage using Amazon S3, Google Cloud Storage, Azure Storage or nginx -- Docker support using [docker-compose](https://github.com/docker/compose) for development and production (using [Traefik](https://traefik.io/) with [LetsEncrypt](https://letsencrypt.org/) support) -- [Procfile](https://devcenter.heroku.com/articles/procfile) for deploying to Heroku -- Instructions for deploying to [PythonAnywhere](https://www.pythonanywhere.com/) -- Run tests with unittest or pytest -- Customizable PostgreSQL version -- Default integration with [pre-commit](https://github.com/pre-commit/pre-commit) for identifying simple issues before submission to code review +- For Django 4.1 +- Works with Python 3.11 +- Renders Django projects with 100% starting test coverage +- Twitter [Bootstrap](https://github.com/twbs/bootstrap) v5 +- [12-Factor](http://12factor.net/) based settings via [django-environ](https://github.com/joke2k/django-environ) +- Secure by default. We believe in SSL. +- Optimized development and production settings +- Registration via [django-allauth](https://github.com/pennersr/django-allauth) +- Comes with custom user model ready to go +- Optional basic ASGI setup for Websockets +- Optional custom static build using Gulp or Webpack +- Send emails via [Anymail](https://github.com/anymail/django-anymail) (using [Mailgun](http://www.mailgun.com/) by default or Amazon SES if AWS is selected cloud provider, but switchable) +- Media storage using Amazon S3, Google Cloud Storage, Azure Storage or nginx +- Docker support using [docker-compose](https://github.com/docker/compose) for development and production (using [Traefik](https://traefik.io/) with [LetsEncrypt](https://letsencrypt.org/) support) +- [Procfile](https://devcenter.heroku.com/articles/procfile) for deploying to Heroku +- Instructions for deploying to [PythonAnywhere](https://www.pythonanywhere.com/) +- Run tests with unittest or pytest +- Customizable PostgreSQL version +- Default integration with [pre-commit](https://github.com/pre-commit/pre-commit) for identifying simple issues before submission to code review ## Optional Integrations -*These features can be enabled during initial project setup.* +_These features can be enabled during initial project setup._ -- Serve static files from Amazon S3, Google Cloud Storage, Azure Storage or [Whitenoise](https://whitenoise.readthedocs.io/) -- Configuration for [Celery](https://docs.celeryq.dev) and [Flower](https://github.com/mher/flower) (the latter in Docker setup only) -- Integration with [MailHog](https://github.com/mailhog/MailHog) for local email testing -- Integration with [Sentry](https://sentry.io/welcome/) for error logging +- Serve static files from Amazon S3, Google Cloud Storage, Azure Storage or [Whitenoise](https://whitenoise.readthedocs.io/) +- Configuration for [Celery](https://docs.celeryq.dev) and [Flower](https://github.com/mher/flower) (the latter in Docker setup only) +- Integration with [MailHog](https://github.com/mailhog/MailHog) for local email testing +- Integration with [Sentry](https://sentry.io/welcome/) for error logging ## Constraints -- Only maintained 3rd party libraries are used. -- Uses PostgreSQL everywhere: 10.19 - 14.1 ([MySQL fork](https://github.com/mabdullahadeel/cookiecutter-django-mysql) also available). -- Environment variables for configuration (This won't work with Apache/mod_wsgi). +- Only maintained 3rd party libraries are used. +- Uses PostgreSQL everywhere: 10.19 - 14.1 ([MySQL fork](https://github.com/mabdullahadeel/cookiecutter-django-mysql) also available). +- Environment variables for configuration (This won't work with Apache/mod_wsgi). ## Support this Project! This project is run by volunteers. Please support them in their efforts to maintain and improve Cookiecutter Django: -- Daniel Roy Greenfeld, Project Lead ([GitHub](https://github.com/pydanny), [Patreon](https://www.patreon.com/danielroygreenfeld)): expertise in Django and AWS ELB. -- Nikita Shupeyko, Core Developer ([GitHub](https://github.com/webyneter)): expertise in Python/Django, hands-on DevOps and frontend experience. +- Daniel Roy Greenfeld, Project Lead ([GitHub](https://github.com/pydanny), [Patreon](https://www.patreon.com/danielroygreenfeld)): expertise in Django and AWS ELB. +- Nikita Shupeyko, Core Developer ([GitHub](https://github.com/webyneter)): expertise in Python/Django, hands-on DevOps and frontend experience. Projects that provide financial support to the maintainers: ------------------------------------------------------------------------- +---

@@ -118,6 +118,10 @@ Answer the prompts with your own desired [options](http://cookiecutter-django.re 4 - Apache Software License 2.0 5 - Not open source Choose from 1, 2, 3, 4, 5 [1]: 1 + Select username_type: + 1 - username + 2 - email + Choose from 1, 2 [1]: 1 timezone [UTC]: America/Los_Angeles windows [n]: n Select an editor to use. The choices are: @@ -188,14 +192,14 @@ Now take a look at your repo. Don't forget to carefully look at the generated RE For local development, see the following: -- [Developing locally](http://cookiecutter-django.readthedocs.io/en/latest/developing-locally.html) -- [Developing locally using docker](http://cookiecutter-django.readthedocs.io/en/latest/developing-locally-docker.html) +- [Developing locally](http://cookiecutter-django.readthedocs.io/en/latest/developing-locally.html) +- [Developing locally using docker](http://cookiecutter-django.readthedocs.io/en/latest/developing-locally-docker.html) ## Community -- Have questions? **Before you ask questions anywhere else**, please post your question on [Stack Overflow](http://stackoverflow.com/questions/tagged/cookiecutter-django) under the *cookiecutter-django* tag. We check there periodically for questions. -- If you think you found a bug or want to request a feature, please open an [issue](https://github.com/cookiecutter/cookiecutter-django/issues). -- For anything else, you can chat with us on [Discord](https://discord.gg/uFXweDQc5a). +- Have questions? **Before you ask questions anywhere else**, please post your question on [Stack Overflow](http://stackoverflow.com/questions/tagged/cookiecutter-django) under the _cookiecutter-django_ tag. We check there periodically for questions. +- If you think you found a bug or want to request a feature, please open an [issue](https://github.com/cookiecutter/cookiecutter-django/issues). +- For anything else, you can chat with us on [Discord](https://discord.gg/uFXweDQc5a). ## For Readers of Two Scoops of Django @@ -203,13 +207,14 @@ You may notice that some elements of this project do not exactly match what we d ## For PyUp Users -If you are using [PyUp](https://pyup.io) to keep your dependencies updated and secure, use the code *cookiecutter* during checkout to get 15% off every month. +If you are using [PyUp](https://pyup.io) to keep your dependencies updated and secure, use the code _cookiecutter_ during checkout to get 15% off every month. ## "Your Stuff" Scattered throughout the Python and HTML of this project are places marked with "your stuff". This is where third-party libraries are to be integrated with your project. ## For MySQL users + To get full MySQL support in addition to the default Postgresql, you can use this fork of the cookiecutter-django: https://github.com/mabdullahadeel/cookiecutter-django-mysql @@ -219,18 +224,18 @@ Need a stable release? You can find them at + $ python3.11 -m venv #. Activate the virtualenv you have just created: :: diff --git a/docs/generate-project-block.rst b/docs/generate-project-block.rst index 2842b551d..fca3fe1a8 100644 --- a/docs/generate-project-block.rst +++ b/docs/generate-project-block.rst @@ -4,4 +4,3 @@ Generate a new cookiecutter-django project: :: For more information refer to :ref:`Project Generation Options `. - diff --git a/docs/project-generation-options.rst b/docs/project-generation-options.rst index b35e42d3f..c1dcf82de 100644 --- a/docs/project-generation-options.rst +++ b/docs/project-generation-options.rst @@ -24,6 +24,13 @@ author_name: email: The email address you want to identify yourself in the project. +username_type: + The type of username you want to use in the project. This can be either + ``username`` or ``email``. If you choose ``username``, the ``email`` field + will be included. If you choose ``email``, the ``username`` field will be + excluded. It is best practice to always include an email field, so there is + no option for having just the ``username`` field. + domain_name: The domain name you plan to use for your project once it goes live. Note that it can be safely changed later on whenever you need to. diff --git a/docs/settings.rst b/docs/settings.rst index 4691adbbd..6dacb7404 100644 --- a/docs/settings.rst +++ b/docs/settings.rst @@ -22,7 +22,6 @@ DATABASE_URL DATABASES auto w/ Dock DJANGO_ADMIN_URL n/a 'admin/' raises error DJANGO_DEBUG DEBUG True False DJANGO_SECRET_KEY SECRET_KEY auto-generated raises error -DJANGO_SECURE_BROWSER_XSS_FILTER SECURE_BROWSER_XSS_FILTER n/a True DJANGO_SECURE_SSL_REDIRECT SECURE_SSL_REDIRECT n/a True DJANGO_SECURE_CONTENT_TYPE_NOSNIFF SECURE_CONTENT_TYPE_NOSNIFF n/a True DJANGO_SECURE_FRAME_DENY SECURE_FRAME_DENY n/a True diff --git a/hooks/post_gen_project.py b/hooks/post_gen_project.py index 0f97ae4df..d46411a51 100644 --- a/hooks/post_gen_project.py +++ b/hooks/post_gen_project.py @@ -45,6 +45,24 @@ def remove_gplv3_files(): os.remove(file_name) +def remove_custom_user_manager_files(): + os.remove( + os.path.join( + "{{cookiecutter.project_slug}}", + "users", + "managers.py", + ) + ) + os.remove( + os.path.join( + "{{cookiecutter.project_slug}}", + "users", + "tests", + "test_managers.py", + ) + ) + + def remove_pycharm_files(): idea_dir_path = ".idea" if os.path.exists(idea_dir_path): @@ -193,7 +211,7 @@ def handle_js_runner(choice, use_docker, use_async): dev_django_cmd = ( "uvicorn config.asgi:application --reload" if use_async - else "python manage.py runserver_plus" + else "python manage.py runserver" ) scripts.update( { @@ -452,6 +470,9 @@ def main(): if "{{ cookiecutter.open_source_license}}" != "GPLv3": remove_gplv3_files() + if "{{ cookiecutter.username_type }}" == "username": + remove_custom_user_manager_files() + if "{{ cookiecutter.editor }}".lower() != "PyCharm": remove_pycharm_files() @@ -461,7 +482,6 @@ def main(): else: remove_docker_files() - if ( "{{ cookiecutter.use_docker }}".lower() == "y" and "{{ cookiecutter.cloud_provider}}" != "AWS" diff --git a/hooks/pre_gen_project.py b/hooks/pre_gen_project.py index c3eef1e43..d067954db 100644 --- a/hooks/pre_gen_project.py +++ b/hooks/pre_gen_project.py @@ -17,6 +17,14 @@ INFO = "\x1b[1;33m [INFO]: " HINT = "\x1b[3;33m" SUCCESS = "\x1b[1;32m [SUCCESS]: " +# The content of this string is evaluated by Jinja, and plays an important role. +# It updates the cookiecutter context to trim leading and trailing spaces +# from domain/email values +""" +{{ cookiecutter.update({ "domain_name": cookiecutter.domain_name | trim }) }} +{{ cookiecutter.update({ "email": cookiecutter.email | trim }) }} +""" + project_slug = "{{ cookiecutter.project_slug }}" if hasattr(project_slug, "isidentifier"): assert ( @@ -36,7 +44,7 @@ if "{{ cookiecutter.use_docker }}".lower() == "n": if python_major_version == 2: print( WARNING + "You're running cookiecutter under Python 2, but the generated " - "project requires Python 3.10+. Do you want to proceed (y/n)? " + TERMINATOR + "project requires Python 3.11+. Do you want to proceed (y/n)? " + TERMINATOR ) yes_options, no_options = frozenset(["y"]), frozenset(["n"]) while True: diff --git a/requirements.txt b/requirements.txt index 5a65d6160..cc729cf64 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,26 +1,26 @@ cookiecutter==2.1.1 -sh==2.0.2; sys_platform != "win32" +sh==2.0.3; sys_platform != "win32" binaryornot==0.4.4 # Code quality # ------------------------------------------------------------------------------ -black==23.1.0 +black==23.3.0 isort==5.12.0 flake8==6.0.0 flake8-isort==6.0.0 -pre-commit==3.1.1 +pre-commit==3.2.2 # Testing # ------------------------------------------------------------------------------ -tox==4.4.6 -pytest==7.2.2 -pytest-cookies==0.6.1 -pytest-instafail==0.4.2 +tox==4.4.12 +pytest==7.3.1 +pytest-cookies==0.7.0 +pytest-instafail==0.5.0 pyyaml==6.0 # Scripting # ------------------------------------------------------------------------------ -PyGithub==1.58.0 +PyGithub==1.58.1 gitpython==3.1.31 jinja2==3.1.2 requests==2.28.2 diff --git a/setup.py b/setup.py index cd6170bb5..3f20e29ca 100644 --- a/setup.py +++ b/setup.py @@ -5,7 +5,7 @@ except ImportError: from distutils.core import setup # We use calendar versioning -version = "2023.03.04" +version = "2023.04.13" with open("README.rst") as readme_file: long_description = readme_file.read() @@ -27,13 +27,13 @@ setup( classifiers=[ "Development Status :: 4 - Beta", "Environment :: Console", - "Framework :: Django :: 4.0", + "Framework :: Django :: 4.1", "Intended Audience :: Developers", "Natural Language :: English", "License :: OSI Approved :: BSD License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", "Programming Language :: Python :: Implementation :: CPython", "Topic :: Software Development", ], diff --git a/tests/test_bare.sh b/tests/test_bare.sh index afd12fec8..5dc175ebd 100755 --- a/tests/test_bare.sh +++ b/tests/test_bare.sh @@ -20,12 +20,6 @@ sudo utility/install_os_dependencies.sh install # Install Python deps pip install -r requirements/local.txt -# Lint by running pre-commit on all files -# Needs a git repo to find the project root -git init -git add . -pre-commit run --show-diff-on-failure -a - # run the project's tests pytest diff --git a/tests/test_cookiecutter_generation.py b/tests/test_cookiecutter_generation.py index c5486e5c9..114ede095 100755 --- a/tests/test_cookiecutter_generation.py +++ b/tests/test_cookiecutter_generation.py @@ -20,6 +20,11 @@ if sys.platform.startswith("win"): elif sys.platform.startswith("darwin") and os.getenv("CI"): pytest.skip("skipping slow macOS tests on CI", allow_module_level=True) +# Run auto-fixable styles checks - skipped on CI by default. These can be fixed +# automatically by running pre-commit after generation however they are tedious +# to fix in the template, so we don't insist too much in fixing them. +AUTOFIXABLE_STYLES = os.getenv("AUTOFIXABLE_STYLES") == 1 + @pytest.fixture def context(): @@ -36,6 +41,8 @@ def context(): SUPPORTED_COMBINATIONS = [ + {"username_type": "username"}, + {"username_type": "email"}, {"open_source_license": "MIT"}, {"open_source_license": "BSD"}, {"open_source_license": "GPLv3"}, @@ -183,9 +190,10 @@ def test_flake8_passes(cookies, context_override): pytest.fail(e.stdout.decode()) +@pytest.mark.skipif(not AUTOFIXABLE_STYLES, reason="Black is auto-fixable") @pytest.mark.parametrize("context_override", SUPPORTED_COMBINATIONS, ids=_fixture_id) def test_black_passes(cookies, context_override): - """Generated project should pass black.""" + """Check whether generated project passes black style.""" result = cookies.bake(extra_context=context_override) try: @@ -321,10 +329,29 @@ def test_error_if_incompatible(cookies, context, invalid_context): ], ) def test_pycharm_docs_removed(cookies, context, editor, pycharm_docs_exist): - """.""" context.update({"editor": editor}) result = cookies.bake(extra_context=context) with open(f"{result.project_path}/docs/index.rst") as f: has_pycharm_docs = "pycharm/configuration" in f.read() assert has_pycharm_docs is pycharm_docs_exist + + +def test_trim_domain_email(cookies, context): + """Check that leading and trailing spaces are trimmed in domain and email.""" + context.update( + { + "use_docker": "y", + "domain_name": " example.com ", + "email": " me@example.com ", + } + ) + result = cookies.bake(extra_context=context) + + assert result.exit_code == 0 + + prod_django_env = result.project_path / ".envs" / ".production" / ".django" + assert "DJANGO_ALLOWED_HOSTS=.example.com" in prod_django_env.read_text() + + base_settings = result.project_path / "config" / "settings" / "base.py" + assert '"me@example.com"' in base_settings.read_text() diff --git a/tests/test_docker.sh b/tests/test_docker.sh index 28d232896..5c60d20d3 100755 --- a/tests/test_docker.sh +++ b/tests/test_docker.sh @@ -14,13 +14,6 @@ cd .cache/docker cookiecutter ../../ --no-input --overwrite-if-exists use_docker=y "$@" cd my_awesome_project -# Lint by running pre-commit on all files -# Needs a git repo to find the project root -# We don't have git inside Docker, so run it outside -git init -git add . -pre-commit run --show-diff-on-failure -a - # make sure all images build docker-compose -f local.yml build diff --git a/tox.ini b/tox.ini index 0400e4f91..f0c22d48e 100644 --- a/tox.ini +++ b/tox.ini @@ -1,6 +1,6 @@ [tox] skipsdist = true -envlist = py310,black-template +envlist = py311,black-template [testenv] deps = -rrequirements.txt diff --git a/{{cookiecutter.project_slug}}/.editorconfig b/{{cookiecutter.project_slug}}/.editorconfig index 6a9a5c45d..c0ce34260 100644 --- a/{{cookiecutter.project_slug}}/.editorconfig +++ b/{{cookiecutter.project_slug}}/.editorconfig @@ -22,6 +22,6 @@ trim_trailing_whitespace = false [Makefile] indent_style = tab -[nginx.conf] +[default.conf] indent_style = space indent_size = 2 diff --git a/{{cookiecutter.project_slug}}/.github/dependabot.yml b/{{cookiecutter.project_slug}}/.github/dependabot.yml index 420a63cdc..be52c68d5 100644 --- a/{{cookiecutter.project_slug}}/.github/dependabot.yml +++ b/{{cookiecutter.project_slug}}/.github/dependabot.yml @@ -4,11 +4,11 @@ version: 2 updates: # Update GitHub actions in workflows - - package-ecosystem: "github-actions" - directory: "/" - # Check for updates to GitHub Actions every weekday + - package-ecosystem: 'github-actions' + directory: '/' + # Every weekday schedule: - interval: "daily" + interval: 'daily' {%- if cookiecutter.use_docker == 'y' %} @@ -16,80 +16,92 @@ updates: # We need to specify each Dockerfile in a separate entry because Dependabot doesn't # support wildcards or recursively checking subdirectories. Check this issue for updates: # https://github.com/dependabot/dependabot-core/issues/2178 - - package-ecosystem: "docker" + - package-ecosystem: 'docker' # Look for a `Dockerfile` in the `compose/local/django` directory - directory: "compose/local/django/" - # Check for updates to GitHub Actions every weekday + directory: 'compose/local/django/' + # Every weekday schedule: - interval: "daily" + interval: 'daily' + # Ignore minor version updates (3.10 -> 3.11) but update patch versions + ignore: + - dependency-name: '*' + update-types: + - 'version-update:semver-major' + - 'version-update:semver-minor' - # Enable version updates for Docker - - package-ecosystem: "docker" + - package-ecosystem: 'docker' # Look for a `Dockerfile` in the `compose/local/docs` directory - directory: "compose/local/docs/" - # Check for updates to GitHub Actions every weekday + directory: 'compose/local/docs/' + # Every weekday schedule: - interval: "daily" + interval: 'daily' + # Ignore minor version updates (3.10 -> 3.11) but update patch versions + ignore: + - dependency-name: '*' + update-types: + - 'version-update:semver-major' + - 'version-update:semver-minor' - # Enable version updates for Docker - - package-ecosystem: "docker" + - package-ecosystem: 'docker' # Look for a `Dockerfile` in the `compose/local/node` directory - directory: "compose/local/node/" - # Check for updates to GitHub Actions every weekday + directory: 'compose/local/node/' + # Every weekday schedule: - interval: "daily" + interval: 'daily' - # Enable version updates for Docker - - package-ecosystem: "docker" + - package-ecosystem: 'docker' # Look for a `Dockerfile` in the `compose/production/aws` directory - directory: "compose/production/aws/" - # Check for updates to GitHub Actions every weekday + directory: 'compose/production/aws/' + # Every weekday schedule: - interval: "daily" + interval: 'daily' - # Enable version updates for Docker - - package-ecosystem: "docker" + - package-ecosystem: 'docker' # Look for a `Dockerfile` in the `compose/production/django` directory - directory: "compose/production/django/" - # Check for updates to GitHub Actions every weekday + directory: 'compose/production/django/' + # Every weekday schedule: - interval: "daily" + interval: 'daily' + # Ignore minor version updates (3.10 -> 3.11) but update patch versions + ignore: + - dependency-name: '*' + update-types: + - 'version-update:semver-major' + - 'version-update:semver-minor' - # Enable version updates for Docker - - package-ecosystem: "docker" + - package-ecosystem: 'docker' # Look for a `Dockerfile` in the `compose/production/postgres` directory - directory: "compose/production/postgres/" - # Check for updates to GitHub Actions every weekday + directory: 'compose/production/postgres/' + # Every weekday schedule: - interval: "daily" + interval: 'daily' - # Enable version updates for Docker - - package-ecosystem: "docker" + - package-ecosystem: 'docker' # Look for a `Dockerfile` in the `compose/production/traefik` directory - directory: "compose/production/traefik/" - # Check for updates to GitHub Actions every weekday + directory: 'compose/production/traefik/' + # Every weekday schedule: - interval: "daily" + interval: 'daily' {%- endif %} # Enable version updates for Python/Pip - Production - - package-ecosystem: "pip" + - package-ecosystem: 'pip' # Look for a `requirements.txt` in the `root` directory # also 'setup.cfg', 'runtime.txt' and 'requirements/*.txt' - directory: "/" - # Check for updates to GitHub Actions every weekday + directory: '/' + # Every weekday schedule: - interval: "daily" + interval: 'daily' {%- if cookiecutter.frontend_pipeline == 'Gulp' %} # Enable version updates for javascript/npm - - package-ecosystem: "npm" - # Look for a `packages.json' in the `root` directory - directory: "/" - # Check for updates to GitHub Actions every weekday + - package-ecosystem: 'npm' + # Look for a `packages.json` in the `root` directory + directory: '/' + # Every weekday schedule: - interval: "daily" + interval: 'daily' {%- endif %} diff --git a/{{cookiecutter.project_slug}}/.github/workflows/ci.yml b/{{cookiecutter.project_slug}}/.github/workflows/ci.yml index 89d83f257..ac231ee72 100644 --- a/{{cookiecutter.project_slug}}/.github/workflows/ci.yml +++ b/{{cookiecutter.project_slug}}/.github/workflows/ci.yml @@ -7,12 +7,12 @@ env: on: pull_request: - branches: [ "master", "main" ] - paths-ignore: [ "docs/**" ] + branches: ['master', 'main'] + paths-ignore: ['docs/**'] push: - branches: [ "master", "main" ] - paths-ignore: [ "docs/**" ] + branches: ['master', 'main'] + paths-ignore: ['docs/**'] concurrency: group: {% raw %}${{ github.head_ref || github.run_id }}{% endraw %} @@ -22,14 +22,13 @@ jobs: linter: runs-on: ubuntu-latest steps: - - name: Checkout Code Repository uses: actions/checkout@v3 - name: Set up Python uses: actions/setup-python@v4 with: - python-version: "3.10" + python-version: '3.11' {%- if cookiecutter.open_source_license != 'Not open source' %} # Consider using pre-commit.ci for open source project @@ -58,35 +57,34 @@ jobs: env: {%- if cookiecutter.use_celery == 'y' %} - CELERY_BROKER_URL: "redis://localhost:6379/0" + CELERY_BROKER_URL: 'redis://localhost:6379/0' {%- endif %} # postgres://user:password@host:port/database - DATABASE_URL: "postgres://postgres:postgres@localhost:5432/postgres" + DATABASE_URL: 'postgres://postgres:postgres@localhost:5432/postgres' {%- endif %} steps: - - name: Checkout Code Repository uses: actions/checkout@v3 {%- if cookiecutter.use_docker == 'y' %} - name: Build the Stack - run: docker-compose -f local.yml build + run: docker-compose -f local.yml build - name: Run DB Migrations - run: docker-compose -f local.yml run --rm django python manage.py migrate + run: docker-compose -f local.yml run --rm django python manage.py migrate - name: Run Django Tests - run: docker-compose -f local.yml run django pytest + run: docker-compose -f local.yml run django pytest - name: Tear down the Stack - run: docker-compose -f local.yml down + run: docker-compose -f local.yml down {%- else %} - name: Set up Python uses: actions/setup-python@v4 with: - python-version: "3.10" + python-version: '3.11' cache: pip cache-dependency-path: | requirements/base.txt @@ -98,5 +96,5 @@ jobs: pip install -r requirements/local.txt - name: Test with pytest - run: pytest + run: pytest {%- endif %} diff --git a/{{cookiecutter.project_slug}}/.gitlab-ci.yml b/{{cookiecutter.project_slug}}/.gitlab-ci.yml index 7892ad63a..a312a41ae 100644 --- a/{{cookiecutter.project_slug}}/.gitlab-ci.yml +++ b/{{cookiecutter.project_slug}}/.gitlab-ci.yml @@ -13,7 +13,7 @@ variables: precommit: stage: lint - image: python:3.10 + image: python:3.11 variables: PRE_COMMIT_HOME: ${CI_PROJECT_DIR}/.cache/pre-commit cache: @@ -40,7 +40,7 @@ pytest: script: - docker-compose -f local.yml run django pytest {%- else %} - image: python:3.10 + image: python:3.11 tags: - python services: diff --git a/{{cookiecutter.project_slug}}/.idea/runConfigurations/runserver_plus.xml b/{{cookiecutter.project_slug}}/.idea/runConfigurations/runserver_plus.xml deleted file mode 100644 index 242f861a6..000000000 --- a/{{cookiecutter.project_slug}}/.idea/runConfigurations/runserver_plus.xml +++ /dev/null @@ -1,33 +0,0 @@ - - - - - diff --git a/{{cookiecutter.project_slug}}/.pre-commit-config.yaml b/{{cookiecutter.project_slug}}/.pre-commit-config.yaml index a8cdb1357..a7c8fa583 100644 --- a/{{cookiecutter.project_slug}}/.pre-commit-config.yaml +++ b/{{cookiecutter.project_slug}}/.pre-commit-config.yaml @@ -1,4 +1,4 @@ -exclude: "^docs/|/migrations/" +exclude: '^docs/|/migrations/' default_stages: [commit] repos: @@ -7,16 +7,31 @@ repos: hooks: - id: trailing-whitespace - id: end-of-file-fixer + - id: check-json + - id: check-toml + - id: check-xml - id: check-yaml + - id: debug-statements + - id: check-builtin-literals + - id: check-case-conflict + - id: check-docstring-first + - id: detect-private-key + + - repo: https://github.com/pre-commit/mirrors-prettier + rev: v3.0.0-alpha.6 + hooks: + - id: prettier + args: ['--tab-width', '2', '--single-quote'] + exclude: {{cookiecutter.project_slug}}/templates/ - repo: https://github.com/asottile/pyupgrade rev: v3.3.1 hooks: - id: pyupgrade - args: [--py310-plus] + args: [--py311-plus] - repo: https://github.com/psf/black - rev: 23.1.0 + rev: 23.3.0 hooks: - id: black @@ -29,7 +44,7 @@ repos: rev: 6.0.0 hooks: - id: flake8 - args: ["--config=setup.cfg"] + args: ['--config=setup.cfg'] additional_dependencies: [flake8-isort] # sets up .pre-commit-ci.yaml to ensure pre-commit dependencies stay up to date diff --git a/{{cookiecutter.project_slug}}/.readthedocs.yml b/{{cookiecutter.project_slug}}/.readthedocs.yml index 08d7f9c24..d5a8ef661 100644 --- a/{{cookiecutter.project_slug}}/.readthedocs.yml +++ b/{{cookiecutter.project_slug}}/.readthedocs.yml @@ -8,7 +8,7 @@ version: 2 build: os: ubuntu-22.04 tools: - python: "3.10" + python: '3.11' # Build documentation in the docs/ directory with Sphinx sphinx: diff --git a/{{cookiecutter.project_slug}}/.travis.yml b/{{cookiecutter.project_slug}}/.travis.yml index 326d78392..5e5f92ff5 100644 --- a/{{cookiecutter.project_slug}}/.travis.yml +++ b/{{cookiecutter.project_slug}}/.travis.yml @@ -2,7 +2,7 @@ dist: focal language: python python: - - "3.10" + - "3.11" services: - {% if cookiecutter.use_docker == 'y' %}docker{% else %}postgresql{% endif %} @@ -37,7 +37,7 @@ jobs: - sudo apt-get install -qq libsqlite3-dev libxml2 libxml2-dev libssl-dev libbz2-dev wget curl llvm language: python python: - - "3.10" + - "3.11" install: - pip install -r requirements/local.txt script: diff --git a/{{cookiecutter.project_slug}}/README.md b/{{cookiecutter.project_slug}}/README.md index 83f9a7e48..56853f8f7 100644 --- a/{{cookiecutter.project_slug}}/README.md +++ b/{{cookiecutter.project_slug}}/README.md @@ -18,11 +18,11 @@ Moved to [settings](http://cookiecutter-django.readthedocs.io/en/latest/settings ### Setting Up Your Users -- To create a **normal user account**, just go to Sign Up and fill out the form. Once you submit it, you'll see a "Verify Your E-mail Address" page. Go to your console to see a simulated email verification message. Copy the link into your browser. Now the user's email should be verified and ready to go. +- To create a **normal user account**, just go to Sign Up and fill out the form. Once you submit it, you'll see a "Verify Your E-mail Address" page. Go to your console to see a simulated email verification message. Copy the link into your browser. Now the user's email should be verified and ready to go. -- To create a **superuser account**, use this command: +- To create a **superuser account**, use this command: - $ python manage.py createsuperuser + $ python manage.py createsuperuser For convenience, you can keep your normal user logged in on Chrome and your superuser logged in on Firefox (or similar), so that you can see how the site behaves for both kinds of users. @@ -56,23 +56,23 @@ This app comes with Celery. To run a celery worker: -``` bash +```bash cd {{cookiecutter.project_slug}} celery -A config.celery_app worker -l info ``` -Please note: For Celery's import magic to work, it is important *where* the celery commands are run. If you are in the same folder with *manage.py*, you should be right. +Please note: For Celery's import magic to work, it is important _where_ the celery commands are run. If you are in the same folder with _manage.py_, you should be right. To run [periodic tasks](https://docs.celeryq.dev/en/stable/userguide/periodic-tasks.html), you'll need to start the celery beat scheduler service. You can start it as a standalone process: -``` bash +```bash cd {{cookiecutter.project_slug}} celery -A config.celery_app beat ``` or you can embed the beat service inside a worker with the `-B` option (not recommended for production use): -``` bash +```bash cd {{cookiecutter.project_slug}} celery -A config.celery_app worker -B -l info ``` diff --git a/{{cookiecutter.project_slug}}/compose/local/django/Dockerfile b/{{cookiecutter.project_slug}}/compose/local/django/Dockerfile index 4f08039a6..2b9e9f7d9 100644 --- a/{{cookiecutter.project_slug}}/compose/local/django/Dockerfile +++ b/{{cookiecutter.project_slug}}/compose/local/django/Dockerfile @@ -1,7 +1,5 @@ -ARG PYTHON_VERSION=3.10-slim-bullseye - # define an alias for the specfic python version used in this file. -FROM python:${PYTHON_VERSION} as python +FROM python:3.11.3-slim-bullseye as python # Python build stage FROM python as python-build-stage diff --git a/{{cookiecutter.project_slug}}/compose/local/django/start b/{{cookiecutter.project_slug}}/compose/local/django/start index ec57dc8e4..6415d7fb4 100644 --- a/{{cookiecutter.project_slug}}/compose/local/django/start +++ b/{{cookiecutter.project_slug}}/compose/local/django/start @@ -9,5 +9,5 @@ python manage.py migrate {%- if cookiecutter.use_async == 'y' %} exec uvicorn config.asgi:application --host 0.0.0.0 --reload --reload-include '*.html' {%- else %} -exec python manage.py runserver_plus 0.0.0.0:8000 +exec python manage.py runserver 0.0.0.0:8000 {%- endif %} diff --git a/{{cookiecutter.project_slug}}/compose/local/docs/Dockerfile b/{{cookiecutter.project_slug}}/compose/local/docs/Dockerfile index c45d18c95..f8bcc35bd 100644 --- a/{{cookiecutter.project_slug}}/compose/local/docs/Dockerfile +++ b/{{cookiecutter.project_slug}}/compose/local/docs/Dockerfile @@ -1,7 +1,5 @@ -ARG PYTHON_VERSION=3.10-slim-bullseye - # define an alias for the specfic python version used in this file. -FROM python:${PYTHON_VERSION} as python +FROM python:3.11.3-slim-bullseye as python # Python build stage diff --git a/{{cookiecutter.project_slug}}/compose/production/django/Dockerfile b/{{cookiecutter.project_slug}}/compose/production/django/Dockerfile index ef80441ba..84c702db0 100644 --- a/{{cookiecutter.project_slug}}/compose/production/django/Dockerfile +++ b/{{cookiecutter.project_slug}}/compose/production/django/Dockerfile @@ -1,5 +1,3 @@ -ARG PYTHON_VERSION=3.10-slim-bullseye - {% if cookiecutter.frontend_pipeline in ['Gulp', 'Webpack'] -%} FROM node:16-bullseye-slim as client-builder @@ -26,9 +24,8 @@ ENV DJANGO_AZURE_ACCOUNT_NAME=${DJANGO_AZURE_ACCOUNT_NAME} RUN npm run build {%- endif %} - # define an alias for the specfic python version used in this file. -FROM python:${PYTHON_VERSION} as python +FROM python:3.11.3-slim-bullseye as python # Python build stage FROM python as python-build-stage diff --git a/{{cookiecutter.project_slug}}/compose/production/nginx/default.conf b/{{cookiecutter.project_slug}}/compose/production/nginx/default.conf index aafdd5bee..562dba86c 100644 --- a/{{cookiecutter.project_slug}}/compose/production/nginx/default.conf +++ b/{{cookiecutter.project_slug}}/compose/production/nginx/default.conf @@ -1,7 +1,7 @@ server { - listen 80; - server_name localhost; - location /media/ { - alias /usr/share/nginx/media/; - } + listen 80; + server_name localhost; + location /media/ { + alias /usr/share/nginx/media/; + } } diff --git a/{{cookiecutter.project_slug}}/compose/production/traefik/Dockerfile b/{{cookiecutter.project_slug}}/compose/production/traefik/Dockerfile index 2365c4c49..7b053059d 100644 --- a/{{cookiecutter.project_slug}}/compose/production/traefik/Dockerfile +++ b/{{cookiecutter.project_slug}}/compose/production/traefik/Dockerfile @@ -1,4 +1,4 @@ -FROM traefik:2.9.8 +FROM traefik:2.9.10 RUN mkdir -p /etc/traefik/acme \ && touch /etc/traefik/acme/acme.json \ && chmod 600 /etc/traefik/acme/acme.json diff --git a/{{cookiecutter.project_slug}}/compose/production/traefik/traefik.yml b/{{cookiecutter.project_slug}}/compose/production/traefik/traefik.yml index ea57f4a51..724c95cdf 100644 --- a/{{cookiecutter.project_slug}}/compose/production/traefik/traefik.yml +++ b/{{cookiecutter.project_slug}}/compose/production/traefik/traefik.yml @@ -4,7 +4,7 @@ log: entryPoints: web: # http - address: ":80" + address: ':80' http: # https://docs.traefik.io/routing/entrypoints/#entrypoint redirections: @@ -13,18 +13,18 @@ entryPoints: web-secure: # https - address: ":443" + address: ':443' {%- if cookiecutter.use_celery == 'y' %} flower: - address: ":5555" + address: ':5555' {%- endif %} certificatesResolvers: letsencrypt: # https://docs.traefik.io/master/https/acme/#lets-encrypt acme: - email: "{{ cookiecutter.email }}" + email: '{{ cookiecutter.email }}' storage: /etc/traefik/acme/acme.json # https://docs.traefik.io/master/https/acme/#httpchallenge httpChallenge: @@ -34,9 +34,9 @@ http: routers: web-secure-router: {%- if cookiecutter.domain_name.count('.') == 1 %} - rule: "Host(`{{ cookiecutter.domain_name }}`) || Host(`www.{{ cookiecutter.domain_name }}`)" + rule: 'Host(`{{ cookiecutter.domain_name }}`) || Host(`www.{{ cookiecutter.domain_name }}`)' {%- else %} - rule: "Host(`{{ cookiecutter.domain_name }}`)" + rule: 'Host(`{{ cookiecutter.domain_name }}`)' {%- endif %} entryPoints: - web-secure @@ -49,7 +49,7 @@ http: {%- if cookiecutter.use_celery == 'y' %} flower-secure-router: - rule: "Host(`{{ cookiecutter.domain_name }}`)" + rule: 'Host(`{{ cookiecutter.domain_name }}`)' entryPoints: - flower service: flower @@ -60,7 +60,11 @@ http: {%- if cookiecutter.cloud_provider == 'None' %} web-media-router: - rule: "Host(`{{ cookiecutter.domain_name }}`) && PathPrefix(`/media/`)" + {%- if cookiecutter.domain_name.count('.') == 1 %} + rule: '(Host(`{{ cookiecutter.domain_name }}`) || Host(`www.{{ cookiecutter.domain_name }}`)) && PathPrefix(`/media/`)' + {%- else %} + rule: 'Host(`{{ cookiecutter.domain_name }}`) && PathPrefix(`/media/`)' + {%- endif %} entryPoints: - web-secure middlewares: @@ -75,7 +79,7 @@ http: # https://docs.traefik.io/master/middlewares/headers/#hostsproxyheaders # https://docs.djangoproject.com/en/dev/ref/csrf/#ajax headers: - hostsProxyHeaders: ["X-CSRFToken"] + hostsProxyHeaders: ['X-CSRFToken'] services: django: diff --git a/{{cookiecutter.project_slug}}/config/settings/base.py b/{{cookiecutter.project_slug}}/config/settings/base.py index cc77b864a..dbb396c65 100644 --- a/{{cookiecutter.project_slug}}/config/settings/base.py +++ b/{{cookiecutter.project_slug}}/config/settings/base.py @@ -225,8 +225,6 @@ FIXTURE_DIRS = (str(APPS_DIR / "fixtures"),) SESSION_COOKIE_HTTPONLY = True # https://docs.djangoproject.com/en/dev/ref/settings/#csrf-cookie-httponly CSRF_COOKIE_HTTPONLY = True -# https://docs.djangoproject.com/en/dev/ref/settings/#secure-browser-xss-filter -SECURE_BROWSER_XSS_FILTER = True # https://docs.djangoproject.com/en/dev/ref/settings/#x-frame-options X_FRAME_OPTIONS = "DENY" @@ -314,9 +312,15 @@ CELERY_TASK_SEND_SENT_EVENT = True # ------------------------------------------------------------------------------ ACCOUNT_ALLOW_REGISTRATION = env.bool("DJANGO_ACCOUNT_ALLOW_REGISTRATION", True) # https://django-allauth.readthedocs.io/en/latest/configuration.html -ACCOUNT_AUTHENTICATION_METHOD = "username" +ACCOUNT_AUTHENTICATION_METHOD = "{{cookiecutter.username_type}}" # https://django-allauth.readthedocs.io/en/latest/configuration.html ACCOUNT_EMAIL_REQUIRED = True +{%- if cookiecutter.username_type == "email" %} +# https://django-allauth.readthedocs.io/en/latest/configuration.html +ACCOUNT_USERNAME_REQUIRED = False +# https://django-allauth.readthedocs.io/en/latest/configuration.html +ACCOUNT_USER_MODEL_USERNAME_FIELD = None +{%- endif %} # https://django-allauth.readthedocs.io/en/latest/configuration.html ACCOUNT_EMAIL_VERIFICATION = "mandatory" # https://django-allauth.readthedocs.io/en/latest/configuration.html diff --git a/{{cookiecutter.project_slug}}/config/settings/local.py b/{{cookiecutter.project_slug}}/config/settings/local.py index 7220c5e4c..09d3bb9fa 100644 --- a/{{cookiecutter.project_slug}}/config/settings/local.py +++ b/{{cookiecutter.project_slug}}/config/settings/local.py @@ -47,15 +47,15 @@ EMAIL_BACKEND = env( # WhiteNoise # ------------------------------------------------------------------------------ # http://whitenoise.evans.io/en/latest/django.html#using-whitenoise-in-development -INSTALLED_APPS = ["whitenoise.runserver_nostatic"] + INSTALLED_APPS # noqa F405 +INSTALLED_APPS = ["whitenoise.runserver_nostatic"] + INSTALLED_APPS # noqa: F405 {% endif %} # django-debug-toolbar # ------------------------------------------------------------------------------ # https://django-debug-toolbar.readthedocs.io/en/latest/installation.html#prerequisites -INSTALLED_APPS += ["debug_toolbar"] # noqa F405 +INSTALLED_APPS += ["debug_toolbar"] # noqa: F405 # https://django-debug-toolbar.readthedocs.io/en/latest/installation.html#middleware -MIDDLEWARE += ["debug_toolbar.middleware.DebugToolbarMiddleware"] # noqa F405 +MIDDLEWARE += ["debug_toolbar.middleware.DebugToolbarMiddleware"] # noqa: F405 # https://django-debug-toolbar.readthedocs.io/en/latest/configuration.html#debug-toolbar-config DEBUG_TOOLBAR_CONFIG = { "DISABLE_PANELS": ["debug_toolbar.panels.redirects.RedirectsPanel"], @@ -82,7 +82,7 @@ if env("USE_DOCKER") == "yes": # django-extensions # ------------------------------------------------------------------------------ # https://django-extensions.readthedocs.io/en/latest/installation_instructions.html#configuration -INSTALLED_APPS += ["django_extensions"] # noqa F405 +INSTALLED_APPS += ["django_extensions"] # noqa: F405 {% if cookiecutter.use_celery == 'y' -%} # Celery @@ -98,7 +98,7 @@ CELERY_TASK_EAGER_PROPAGATES = True {%- if cookiecutter.frontend_pipeline == 'Webpack' %} # django-webpack-loader # ------------------------------------------------------------------------------ -WEBPACK_LOADER["DEFAULT"]["CACHE"] = not DEBUG # noqa F405 +WEBPACK_LOADER["DEFAULT"]["CACHE"] = not DEBUG # noqa: F405 {%- endif %} # Your stuff... diff --git a/{{cookiecutter.project_slug}}/config/settings/production.py b/{{cookiecutter.project_slug}}/config/settings/production.py index 5de0529e2..d5760147c 100644 --- a/{{cookiecutter.project_slug}}/config/settings/production.py +++ b/{{cookiecutter.project_slug}}/config/settings/production.py @@ -2,8 +2,10 @@ import logging import sentry_sdk + {%- if cookiecutter.use_celery == 'y' %} from sentry_sdk.integrations.celery import CeleryIntegration + {%- endif %} from sentry_sdk.integrations.django import DjangoIntegration from sentry_sdk.integrations.logging import LoggingIntegration @@ -22,7 +24,7 @@ ALLOWED_HOSTS = env.list("DJANGO_ALLOWED_HOSTS", default=["{{ cookiecutter.domai # DATABASES # ------------------------------------------------------------------------------ -DATABASES["default"]["CONN_MAX_AGE"] = env.int("CONN_MAX_AGE", default=60) # noqa F405 +DATABASES["default"]["CONN_MAX_AGE"] = env.int("CONN_MAX_AGE", default=60) # noqa: F405 # CACHES # ------------------------------------------------------------------------------ @@ -68,7 +70,7 @@ SECURE_CONTENT_TYPE_NOSNIFF = env.bool( # STORAGES # ------------------------------------------------------------------------------ # https://django-storages.readthedocs.io/en/latest/#installation -INSTALLED_APPS += ["storages"] # noqa F405 +INSTALLED_APPS += ["storages"] # noqa: F405 {%- endif -%} {% if cookiecutter.cloud_provider == 'AWS' %} # https://django-storages.readthedocs.io/en/latest/backends/amazon-S3.html#settings @@ -159,7 +161,7 @@ ADMIN_URL = env("DJANGO_ADMIN_URL") # Anymail # ------------------------------------------------------------------------------ # https://anymail.readthedocs.io/en/stable/installation/#installing-anymail -INSTALLED_APPS += ["anymail"] # noqa F405 +INSTALLED_APPS += ["anymail"] # noqa: F405 # https://docs.djangoproject.com/en/dev/ref/settings/#email-backend # https://anymail.readthedocs.io/en/stable/installation/#anymail-settings-reference {%- if cookiecutter.mail_service == 'Mailgun' %} @@ -241,7 +243,7 @@ COMPRESS_STORAGE = "compressor.storage.GzipCompressorFileStorage" COMPRESS_STORAGE = STATICFILES_STORAGE {%- endif %} # https://django-compressor.readthedocs.io/en/latest/settings/#django.conf.settings.COMPRESS_URL -COMPRESS_URL = STATIC_URL{% if cookiecutter.use_whitenoise == 'y' or cookiecutter.cloud_provider == 'None' %} # noqa F405{% endif %} +COMPRESS_URL = STATIC_URL{% if cookiecutter.use_whitenoise == 'y' or cookiecutter.cloud_provider == 'None' %} # noqa: F405{% endif %} {%- if cookiecutter.use_whitenoise == 'y' %} # https://django-compressor.readthedocs.io/en/latest/settings/#django.conf.settings.COMPRESS_OFFLINE COMPRESS_OFFLINE = True # Offline compression is required when using Whitenoise @@ -259,7 +261,7 @@ COMPRESS_FILTERS = { # Collectfast # ------------------------------------------------------------------------------ # https://github.com/antonagestam/collectfast#installation -INSTALLED_APPS = ["collectfast"] + INSTALLED_APPS # noqa F405 +INSTALLED_APPS = ["collectfast"] + INSTALLED_APPS # noqa: F405 {% endif %} # LOGGING # ------------------------------------------------------------------------------ @@ -373,7 +375,7 @@ sentry_sdk.init( # django-rest-framework # ------------------------------------------------------------------------------- # Tools that generate code samples can use SERVERS to point to the correct domain -SPECTACULAR_SETTINGS["SERVERS"] = [ # noqa F405 +SPECTACULAR_SETTINGS["SERVERS"] = [ # noqa: F405 {"url": "https://{{ cookiecutter.domain_name }}", "description": "Production server"} ] diff --git a/{{cookiecutter.project_slug}}/config/settings/test.py b/{{cookiecutter.project_slug}}/config/settings/test.py index 587b99324..7941c7413 100644 --- a/{{cookiecutter.project_slug}}/config/settings/test.py +++ b/{{cookiecutter.project_slug}}/config/settings/test.py @@ -27,12 +27,12 @@ EMAIL_BACKEND = "django.core.mail.backends.locmem.EmailBackend" # DEBUGGING FOR TEMPLATES # ------------------------------------------------------------------------------ -TEMPLATES[0]["OPTIONS"]["debug"] = True # type: ignore # noqa F405 +TEMPLATES[0]["OPTIONS"]["debug"] = True # type: ignore # noqa: F405 {%- if cookiecutter.frontend_pipeline == 'Webpack' %} # django-webpack-loader # ------------------------------------------------------------------------------ -WEBPACK_LOADER["DEFAULT"][ # noqa F405 +WEBPACK_LOADER["DEFAULT"][ # noqa: F405 "LOADER_CLASS" ] = "webpack_loader.loader.FakeWebpackLoader" diff --git a/{{cookiecutter.project_slug}}/gulpfile.js b/{{cookiecutter.project_slug}}/gulpfile.js index fa3636eab..df434c134 100644 --- a/{{cookiecutter.project_slug}}/gulpfile.js +++ b/{{cookiecutter.project_slug}}/gulpfile.js @@ -3,29 +3,29 @@ //////////////////////////////// // Gulp and package -const { src, dest, parallel, series, watch } = require('gulp') -const pjson = require('./package.json') +const { src, dest, parallel, series, watch } = require('gulp'); +const pjson = require('./package.json'); // Plugins -const autoprefixer = require('autoprefixer') -const browserSync = require('browser-sync').create() -const concat = require('gulp-concat') +const autoprefixer = require('autoprefixer'); +const browserSync = require('browser-sync').create(); +const concat = require('gulp-concat'); const tildeImporter = require('node-sass-tilde-importer'); -const cssnano = require ('cssnano') -const imagemin = require('gulp-imagemin') -const pixrem = require('pixrem') -const plumber = require('gulp-plumber') -const postcss = require('gulp-postcss') -const reload = browserSync.reload -const rename = require('gulp-rename') -const sass = require('gulp-sass')(require('sass')) -const spawn = require('child_process').spawn -const uglify = require('gulp-uglify-es').default +const cssnano = require('cssnano'); +const imagemin = require('gulp-imagemin'); +const pixrem = require('pixrem'); +const plumber = require('gulp-plumber'); +const postcss = require('gulp-postcss'); +const reload = browserSync.reload; +const rename = require('gulp-rename'); +const sass = require('gulp-sass')(require('sass')); +const spawn = require('child_process').spawn; +const uglify = require('gulp-uglify-es').default; // Relative paths function function pathsConfig(appName) { - this.app = `./${pjson.name}` - const vendorsRoot = 'node_modules' + this.app = `./${pjson.name}`; + const vendorsRoot = 'node_modules'; return { vendorsJs: [ @@ -39,10 +39,10 @@ function pathsConfig(appName) { fonts: `${this.app}/static/fonts`, images: `${this.app}/static/images`, js: `${this.app}/static/js`, - } + }; } -const paths = pathsConfig() +const paths = pathsConfig(); //////////////////////////////// // Tasks @@ -51,27 +51,27 @@ const paths = pathsConfig() // Styles autoprefixing and minification function styles() { const processCss = [ - autoprefixer(), // adds vendor prefixes - pixrem(), // add fallbacks for rem units - ] + autoprefixer(), // adds vendor prefixes + pixrem(), // add fallbacks for rem units + ]; const minifyCss = [ - cssnano({ preset: 'default' }) // minify result - ] + cssnano({ preset: 'default' }), // minify result + ]; return src(`${paths.sass}/project.scss`) - .pipe(sass({ - importer: tildeImporter, - includePaths: [ - paths.sass - ] - }).on('error', sass.logError)) + .pipe( + sass({ + importer: tildeImporter, + includePaths: [paths.sass], + }).on('error', sass.logError), + ) .pipe(plumber()) // Checks for errors .pipe(postcss(processCss)) .pipe(dest(paths.css)) .pipe(rename({ suffix: '.min' })) .pipe(postcss(minifyCss)) // Minifies the result - .pipe(dest(paths.css)) + .pipe(dest(paths.css)); } // Javascript minification @@ -80,7 +80,7 @@ function scripts() { .pipe(plumber()) // Checks for errors .pipe(uglify()) // Minifies the js .pipe(rename({ suffix: '.min' })) - .pipe(dest(paths.js)) + .pipe(dest(paths.js)); } // Vendor Javascript minification @@ -91,97 +91,91 @@ function vendorScripts() { .pipe(plumber()) // Checks for errors .pipe(uglify()) // Minifies the js .pipe(rename({ suffix: '.min' })) - .pipe(dest(paths.js, { sourcemaps: '.' })) + .pipe(dest(paths.js, { sourcemaps: '.' })); } // Image compression function imgCompression() { return src(`${paths.images}/*`) .pipe(imagemin()) // Compresses PNG, JPEG, GIF and SVG images - .pipe(dest(paths.images)) + .pipe(dest(paths.images)); } {%- if cookiecutter.use_async == 'y' -%} // Run django server function asyncRunServer() { - const cmd = spawn('gunicorn', [ - 'config.asgi', '-k', 'uvicorn.workers.UvicornWorker', '--reload' - ], {stdio: 'inherit'} - ) - cmd.on('close', function(code) { - console.log('gunicorn exited with code ' + code) + const cmd = spawn( + 'gunicorn', + ['config.asgi', '-k', 'uvicorn.workers.UvicornWorker', '--reload'], + {stdio: 'inherit'}, + ); + cmd.on('close', function (code) { + console.log('gunicorn exited with code ' + code); }) } {%- else %} // Run django server function runServer(cb) { - const cmd = spawn('python', ['manage.py', 'runserver'], {stdio: 'inherit'}) - cmd.on('close', function(code) { - console.log('runServer exited with code ' + code) - cb(code) - }) + const cmd = spawn('python', ['manage.py', 'runserver'], { stdio: 'inherit' }); + cmd.on('close', function (code) { + console.log('runServer exited with code ' + code); + cb(code); + }); } {%- endif %} // Browser sync server for live reload function initBrowserSync() { browserSync.init( - [ - `${paths.css}/*.css`, - `${paths.js}/*.js`, - `${paths.templates}/*.html` - ], { + [`${paths.css}/*.css`, `${paths.js}/*.js`, `${paths.templates}/*.html`], + { {%- if cookiecutter.use_docker == 'y' %} // https://www.browsersync.io/docs/options/#option-open // Disable as it doesn't work from inside a container open: false, {%- endif %} // https://www.browsersync.io/docs/options/#option-proxy - proxy: { + proxy: { {%- if cookiecutter.use_docker == 'n' %} target: '127.0.0.1:8000', {%- else %} target: 'django:8000', {%- endif %} proxyReq: [ - function(proxyReq, req) { - // Assign proxy "host" header same as current request at Browsersync server - proxyReq.setHeader('Host', req.headers.host) - } - ] - } - } - ) + function (proxyReq, req) { + // Assign proxy 'host' header same as current request at Browsersync server + proxyReq.setHeader('Host', req.headers.host); + }, + ], + }, + }, + ); } // Watch function watchPaths() { - watch(`${paths.sass}/*.scss`{% if cookiecutter.windows == 'y' %}, { usePolling: true }{% endif %}, styles) - watch(`${paths.templates}/**/*.html`{% if cookiecutter.windows == 'y' %}, { usePolling: true }{% endif %}).on("change", reload) - watch([`${paths.js}/*.js`, `!${paths.js}/*.min.js`]{% if cookiecutter.windows == 'y' %}, { usePolling: true }{% endif %}, scripts).on("change", reload) + watch(`${paths.sass}/*.scss`{% if cookiecutter.windows == 'y' %}, { usePolling: true }{% endif %}, styles); + watch(`${paths.templates}/**/*.html`{% if cookiecutter.windows == 'y' %}, { usePolling: true }{% endif %}).on('change', reload); + watch([`${paths.js}/*.js`, `!${paths.js}/*.min.js`]{% if cookiecutter.windows == 'y' %}, { usePolling: true }{% endif %}, scripts).on( + 'change', + reload, + ); } // Generate all assets -const generateAssets = parallel( - styles, - scripts, - vendorScripts, - imgCompression -) +const generateAssets = parallel(styles, scripts, vendorScripts, imgCompression); // Set up dev environment -const dev = parallel( - {%- if cookiecutter.use_docker == 'n' %} - {%- if cookiecutter.use_async == 'y' %} - asyncRunServer, - {%- else %} - runServer, - {%- endif %} - {%- endif %} - initBrowserSync, - watchPaths -) +{%- if cookiecutter.use_docker == 'n' %} +{%- if cookiecutter.use_async == 'y' %} +const dev = parallel(asyncRunServer, initBrowserSync, watchPaths); +{%- else %} +const dev = parallel(runServer, initBrowserSync, watchPaths); +{%- endif %} +{%- else %} +const dev = parallel(initBrowserSync, watchPaths); +{%- endif %} -exports.default = series(generateAssets, dev) -exports["generate-assets"] = generateAssets -exports["dev"] = dev +exports.default = series(generateAssets, dev); +exports['generate-assets'] = generateAssets; +exports['dev'] = dev; diff --git a/{{cookiecutter.project_slug}}/local.yml b/{{cookiecutter.project_slug}}/local.yml index 66ca3b0ef..e55e18d32 100644 --- a/{{cookiecutter.project_slug}}/local.yml +++ b/{{cookiecutter.project_slug}}/local.yml @@ -25,7 +25,7 @@ services: - ./.envs/.local/.django - ./.envs/.local/.postgres ports: - - "8000:8000" + - '8000:8000' command: /start postgres: @@ -53,7 +53,7 @@ services: - ./config:/app/config:z - ./{{ cookiecutter.project_slug }}:/app/{{ cookiecutter.project_slug }}:z ports: - - "9000:9000" + - '9000:9000' command: /start-docs {%- if cookiecutter.use_mailhog == 'y' %} @@ -101,7 +101,7 @@ services: image: {{ cookiecutter.project_slug }}_local_flower container_name: {{ cookiecutter.project_slug }}_local_flower ports: - - "5555:5555" + - '5555:5555' command: /start-flower {%- endif %} @@ -121,10 +121,10 @@ services: - /app/node_modules command: npm run dev ports: - - "3000:3000" + - '3000:3000' {%- if cookiecutter.frontend_pipeline == 'Gulp' %} # Expose browsersync UI: https://www.browsersync.io/docs/options/#option-ui - - "3001:3001" + - '3001:3001' {%- endif %} {%- endif %} diff --git a/{{cookiecutter.project_slug}}/production.yml b/{{cookiecutter.project_slug}}/production.yml index 4e9b9e048..4d56fbfa8 100644 --- a/{{cookiecutter.project_slug}}/production.yml +++ b/{{cookiecutter.project_slug}}/production.yml @@ -60,10 +60,10 @@ services: volumes: - production_traefik:/etc/traefik/acme ports: - - "0.0.0.0:80:80" - - "0.0.0.0:443:443" + - '0.0.0.0:80:80' + - '0.0.0.0:443:443' {%- if cookiecutter.use_celery == 'y' %} - - "0.0.0.0:5555:5555" + - '0.0.0.0:5555:5555' {%- endif %} redis: diff --git a/{{cookiecutter.project_slug}}/requirements/base.txt b/{{cookiecutter.project_slug}}/requirements/base.txt index 1550be1bb..0fdee1f86 100644 --- a/{{cookiecutter.project_slug}}/requirements/base.txt +++ b/{{cookiecutter.project_slug}}/requirements/base.txt @@ -1,6 +1,6 @@ -pytz==2022.7.1 # https://github.com/stub42/pytz +pytz==2023.3 # https://github.com/stub42/pytz python-slugify==8.0.1 # https://github.com/un33k/python-slugify -Pillow==9.4.0 # https://github.com/python-pillow/Pillow +Pillow==9.5.0 # https://github.com/python-pillow/Pillow {%- if cookiecutter.frontend_pipeline == 'Django Compressor' %} {%- if cookiecutter.windows == 'y' and cookiecutter.use_docker == 'n' %} rcssmin==1.1.0 --install-option="--without-c-extensions" # https://github.com/ndparker/rcssmin @@ -12,27 +12,27 @@ argon2-cffi==21.3.0 # https://github.com/hynek/argon2_cffi {%- if cookiecutter.use_whitenoise == 'y' %} whitenoise==6.4.0 # https://github.com/evansd/whitenoise {%- endif %} -redis==4.5.1 # https://github.com/redis/redis-py +redis==4.5.4 # https://github.com/redis/redis-py {%- if cookiecutter.use_docker == "y" or cookiecutter.windows == "n" %} hiredis==2.2.2 # https://github.com/redis/hiredis-py {%- endif %} {%- if cookiecutter.use_celery == "y" %} celery==5.2.7 # pyup: < 6.0 # https://github.com/celery/celery -django-celery-beat==2.4.0 # https://github.com/celery/django-celery-beat +django-celery-beat==2.5.0 # https://github.com/celery/django-celery-beat {%- if cookiecutter.use_docker == 'y' %} flower==1.2.0 # https://github.com/mher/flower {%- endif %} {%- endif %} {%- if cookiecutter.use_async == 'y' %} -uvicorn[standard]==0.20.0 # https://github.com/encode/uvicorn +uvicorn[standard]==0.21.1 # https://github.com/encode/uvicorn {%- endif %} # Django # ------------------------------------------------------------------------------ -django==4.0.10 # pyup: < 4.1 # https://www.djangoproject.com/ +django==4.1.8 # pyup: < 4.2 # https://www.djangoproject.com/ django-environ==0.10.0 # https://github.com/joke2k/django-environ django-model-utils==4.3.1 # https://github.com/jazzband/django-model-utils -django-allauth==0.52.0 # https://github.com/pennersr/django-allauth +django-allauth==0.54.0 # https://github.com/pennersr/django-allauth django-crispy-forms==2.0 # https://github.com/django-crispy-forms/django-crispy-forms crispy-bootstrap5==0.7 # https://github.com/django-crispy-forms/crispy-bootstrap5 {%- if cookiecutter.frontend_pipeline == 'Django Compressor' %} @@ -44,7 +44,7 @@ django-redis==5.2.0 # https://github.com/jazzband/django-redis djangorestframework==3.14.0 # https://github.com/encode/django-rest-framework django-cors-headers==3.14.0 # https://github.com/adamchainz/django-cors-headers # DRF-spectacular for api documentation -drf-spectacular==0.26.0 # https://github.com/tfranzel/drf-spectacular +drf-spectacular==0.26.1 # https://github.com/tfranzel/drf-spectacular {%- endif %} {%- if cookiecutter.frontend_pipeline == 'Webpack' %} django-webpack-loader==1.8.1 # https://github.com/django-webpack/django-webpack-loader diff --git a/{{cookiecutter.project_slug}}/requirements/local.txt b/{{cookiecutter.project_slug}}/requirements/local.txt index e0928bc21..a867b0673 100644 --- a/{{cookiecutter.project_slug}}/requirements/local.txt +++ b/{{cookiecutter.project_slug}}/requirements/local.txt @@ -1,24 +1,24 @@ -r base.txt Werkzeug[watchdog]==2.2.3 # https://github.com/pallets/werkzeug -ipdb==0.13.11 # https://github.com/gotcha/ipdb +ipdb==0.13.13 # https://github.com/gotcha/ipdb {%- if cookiecutter.use_docker == 'y' %} -psycopg2==2.9.5 # https://github.com/psycopg/psycopg2 +psycopg2==2.9.6 # https://github.com/psycopg/psycopg2 {%- else %} -psycopg2-binary==2.9.5 # https://github.com/psycopg/psycopg2 +psycopg2-binary==2.9.6 # https://github.com/psycopg/psycopg2 {%- endif %} {%- if cookiecutter.use_async == 'y' or cookiecutter.use_celery == 'y' %} -watchfiles==0.18.1 # https://github.com/samuelcolvin/watchfiles +watchfiles==0.19.0 # https://github.com/samuelcolvin/watchfiles {%- endif %} # Testing # ------------------------------------------------------------------------------ mypy==1.1.1 # https://github.com/python/mypy -django-stubs==1.15.0 # https://github.com/typeddjango/django-stubs -pytest==7.2.2 # https://github.com/pytest-dev/pytest -pytest-sugar==0.9.6 # https://github.com/Frozenball/pytest-sugar +django-stubs==1.16.0 # https://github.com/typeddjango/django-stubs +pytest==7.3.1 # https://github.com/pytest-dev/pytest +pytest-sugar==0.9.7 # https://github.com/Frozenball/pytest-sugar {%- if cookiecutter.use_drf == "y" %} -djangorestframework-stubs==1.9.1 # https://github.com/typeddjango/djangorestframework-stubs +djangorestframework-stubs==1.10.0 # https://github.com/typeddjango/djangorestframework-stubs {%- endif %} # Documentation @@ -30,19 +30,19 @@ sphinx-autobuild==2021.3.14 # https://github.com/GaretJax/sphinx-autobuild # ------------------------------------------------------------------------------ flake8==6.0.0 # https://github.com/PyCQA/flake8 flake8-isort==6.0.0 # https://github.com/gforcada/flake8-isort -coverage==7.2.1 # https://github.com/nedbat/coveragepy -black==23.1.0 # https://github.com/psf/black +coverage==7.2.2 # https://github.com/nedbat/coveragepy +black==23.3.0 # https://github.com/psf/black pylint-django==2.5.3 # https://github.com/PyCQA/pylint-django {%- if cookiecutter.use_celery == 'y' %} pylint-celery==0.3 # https://github.com/PyCQA/pylint-celery {%- endif %} -pre-commit==3.1.1 # https://github.com/pre-commit/pre-commit +pre-commit==3.2.2 # https://github.com/pre-commit/pre-commit # Django # ------------------------------------------------------------------------------ factory-boy==3.2.1 # https://github.com/FactoryBoy/factory_boy -django-debug-toolbar==3.8.1 # https://github.com/jazzband/django-debug-toolbar +django-debug-toolbar==4.0.0 # https://github.com/jazzband/django-debug-toolbar django-extensions==3.2.1 # https://github.com/django-extensions/django-extensions django-coverage-plugin==3.0.0 # https://github.com/nedbat/django_coverage_plugin pytest-django==4.5.2 # https://github.com/pytest-dev/pytest-django diff --git a/{{cookiecutter.project_slug}}/requirements/production.txt b/{{cookiecutter.project_slug}}/requirements/production.txt index 3d725fae7..42cdbf53f 100644 --- a/{{cookiecutter.project_slug}}/requirements/production.txt +++ b/{{cookiecutter.project_slug}}/requirements/production.txt @@ -3,12 +3,12 @@ -r base.txt gunicorn==20.1.0 # https://github.com/benoitc/gunicorn -psycopg2==2.9.5 # https://github.com/psycopg/psycopg2 +psycopg2==2.9.6 # https://github.com/psycopg/psycopg2 {%- if cookiecutter.use_whitenoise == 'n' %} Collectfast==2.2.0 # https://github.com/antonagestam/collectfast {%- endif %} {%- if cookiecutter.use_sentry == "y" %} -sentry-sdk==1.16.0 # https://github.com/getsentry/sentry-python +sentry-sdk==1.19.0 # https://github.com/getsentry/sentry-python {%- endif %} {%- if cookiecutter.use_docker == "n" and cookiecutter.windows == "y" %} hiredis==2.2.2 # https://github.com/redis/hiredis-py @@ -24,21 +24,21 @@ django-storages[google]==1.13.2 # https://github.com/jschneier/django-storages django-storages[azure]==1.13.2 # https://github.com/jschneier/django-storages {%- endif %} {%- if cookiecutter.mail_service == 'Mailgun' %} -django-anymail[mailgun]==9.0 # https://github.com/anymail/django-anymail +django-anymail[mailgun]==9.1 # https://github.com/anymail/django-anymail {%- elif cookiecutter.mail_service == 'Amazon SES' %} -django-anymail[amazon_ses]==9.0 # https://github.com/anymail/django-anymail +django-anymail[amazon_ses]==9.1 # https://github.com/anymail/django-anymail {%- elif cookiecutter.mail_service == 'Mailjet' %} -django-anymail[mailjet]==9.0 # https://github.com/anymail/django-anymail +django-anymail[mailjet]==9.1 # https://github.com/anymail/django-anymail {%- elif cookiecutter.mail_service == 'Mandrill' %} -django-anymail[mandrill]==9.0 # https://github.com/anymail/django-anymail +django-anymail[mandrill]==9.1 # https://github.com/anymail/django-anymail {%- elif cookiecutter.mail_service == 'Postmark' %} -django-anymail[postmark]==9.0 # https://github.com/anymail/django-anymail +django-anymail[postmark]==9.1 # https://github.com/anymail/django-anymail {%- elif cookiecutter.mail_service == 'Sendgrid' %} -django-anymail[sendgrid]==9.0 # https://github.com/anymail/django-anymail +django-anymail[sendgrid]==9.1 # https://github.com/anymail/django-anymail {%- elif cookiecutter.mail_service == 'SendinBlue' %} -django-anymail[sendinblue]==9.0 # https://github.com/anymail/django-anymail +django-anymail[sendinblue]==9.1 # https://github.com/anymail/django-anymail {%- elif cookiecutter.mail_service == 'SparkPost' %} -django-anymail[sparkpost]==9.0 # https://github.com/anymail/django-anymail +django-anymail[sparkpost]==9.1 # https://github.com/anymail/django-anymail {%- elif cookiecutter.mail_service == 'Other SMTP' %} -django-anymail==9.0 # https://github.com/anymail/django-anymail +django-anymail==9.1 # https://github.com/anymail/django-anymail {%- endif %} diff --git a/{{cookiecutter.project_slug}}/runtime.txt b/{{cookiecutter.project_slug}}/runtime.txt index 69b0ccfc8..afe12ad1b 100644 --- a/{{cookiecutter.project_slug}}/runtime.txt +++ b/{{cookiecutter.project_slug}}/runtime.txt @@ -1 +1 @@ -python-3.10.8 +python-3.11.3 diff --git a/{{cookiecutter.project_slug}}/setup.cfg b/{{cookiecutter.project_slug}}/setup.cfg index 7ee60215a..ab191732b 100644 --- a/{{cookiecutter.project_slug}}/setup.cfg +++ b/{{cookiecutter.project_slug}}/setup.cfg @@ -18,7 +18,7 @@ force_grid_wrap = 0 use_parentheses = true [mypy] -python_version = 3.10 +python_version = 3.11 check_untyped_defs = True ignore_missing_imports = True warn_unused_ignores = True @@ -35,6 +35,6 @@ ignore_errors = True [coverage:run] include = {{cookiecutter.project_slug}}/** -omit = *migrations*, *tests* +omit = */migrations/*, */tests/* plugins = django_coverage_plugin diff --git a/{{cookiecutter.project_slug}}/webpack/common.config.js b/{{cookiecutter.project_slug}}/webpack/common.config.js index 41efb1c77..6aba2bc77 100644 --- a/{{cookiecutter.project_slug}}/webpack/common.config.js +++ b/{{cookiecutter.project_slug}}/webpack/common.config.js @@ -3,20 +3,25 @@ const BundleTracker = require('webpack-bundle-tracker'); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); module.exports = { - target: "web", + target: 'web', context: path.join(__dirname, '../'), entry: { - 'project': path.resolve(__dirname, '../{{cookiecutter.project_slug}}/static/js/project'), - 'vendors': path.resolve(__dirname, '../{{cookiecutter.project_slug}}/static/js/vendors'), + project: path.resolve(__dirname, '../{{cookiecutter.project_slug}}/static/js/project'), + vendors: path.resolve(__dirname, '../{{cookiecutter.project_slug}}/static/js/vendors'), }, output: { - path: path.resolve(__dirname, '../{{cookiecutter.project_slug}}/static/webpack_bundles/'), + path: path.resolve( + __dirname, + '../{{cookiecutter.project_slug}}/static/webpack_bundles/', + ), publicPath: '/static/webpack_bundles/', filename: 'js/[name]-[fullhash].js', chunkFilename: 'js/[name]-[hash].js', }, plugins: [ - new BundleTracker({filename: path.resolve(__dirname, '../webpack-stats.json')}), + new BundleTracker({ + filename: path.resolve(__dirname, '../webpack-stats.json'), + }), new MiniCssExtractPlugin({ filename: 'css/[name].[contenthash].css' }), ], module: { @@ -35,11 +40,7 @@ module.exports = { loader: 'postcss-loader', options: { postcssOptions: { - plugins: [ - 'postcss-preset-env', - 'autoprefixer', - 'pixrem', - ], + plugins: ['postcss-preset-env', 'autoprefixer', 'pixrem'], }, }, }, diff --git a/{{cookiecutter.project_slug}}/webpack/prod.config.js b/{{cookiecutter.project_slug}}/webpack/prod.config.js index b9c2186e5..868d26ddd 100644 --- a/{{cookiecutter.project_slug}}/webpack/prod.config.js +++ b/{{cookiecutter.project_slug}}/webpack/prod.config.js @@ -5,9 +5,9 @@ const commonConfig = require('./common.config'); {%- if cookiecutter.use_whitenoise == 'n' %} {%- if cookiecutter.cloud_provider == 'AWS' %} const s3BucketName = process.env.DJANGO_AWS_STORAGE_BUCKET_NAME; -const awsS3Domain = process.env.DJANGO_AWS_S3_CUSTOM_DOMAIN ? - process.env.DJANGO_AWS_S3_CUSTOM_DOMAIN - : `${s3BucketName}.s3.amazonaws.com`; +const awsS3Domain = process.env.DJANGO_AWS_S3_CUSTOM_DOMAIN + ? process.env.DJANGO_AWS_S3_CUSTOM_DOMAIN + : `${s3BucketName}.s3.amazonaws.com`; const staticUrl = `https://${awsS3Domain}/static/`; {%- elif cookiecutter.cloud_provider == 'GCP' %} const staticUrl = `https://storage.googleapis.com/${process.env.DJANGO_GCP_STORAGE_BUCKET_NAME}/static/`; diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/static/js/project.js b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/static/js/project.js index 62770f1c9..930fa54a2 100644 --- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/static/js/project.js +++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/static/js/project.js @@ -1,5 +1,5 @@ -{%- if cookiecutter.frontend_pipeline == 'Webpack' %} +{%- if cookiecutter.frontend_pipeline == 'Webpack' -%} import '../sass/project.scss'; -{%- endif %} +{% endif -%} /* Project specific Javascript goes here. */ diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/static/sass/project.scss b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/static/sass/project.scss index c9511e720..43435aca8 100644 --- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/static/sass/project.scss +++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/static/sass/project.scss @@ -1,12 +1,11 @@ -@import "custom_bootstrap_vars"; -@import "~bootstrap/scss/bootstrap"; - +@import 'custom_bootstrap_vars'; +@import '~bootstrap/scss/bootstrap'; // project specific CSS goes here -//////////////////////////////// - //Variables// -//////////////////////////////// +/////////////// +// Variables // +/////////////// // Alert colors @@ -17,9 +16,9 @@ $pink: #f2dede; $dark-pink: #eed3d7; $red: #b94a48; -//////////////////////////////// - //Alerts// -//////////////////////////////// +//////////// +// Alerts // +//////////// // bootstrap alert CSS, translated to the django-standard levels of // debug, info, success, warning, error diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/templates/base.html b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/templates/base.html index 05cc449db..ad51a6e18 100644 --- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/templates/base.html +++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/templates/base.html @@ -92,8 +92,7 @@ {% if request.user.is_authenticated %}