mirror of
https://github.com/cookiecutter/cookiecutter-django.git
synced 2024-11-10 19:57:09 +03:00
Ruff as formatter & linter
This commit is contained in:
parent
dd841c6478
commit
6ba6104f09
|
@ -4,40 +4,30 @@ Linters
|
|||
.. index:: linters
|
||||
|
||||
|
||||
flake8
|
||||
ruff
|
||||
------
|
||||
|
||||
To run flake8: ::
|
||||
Ruff is a Python linter and code formatter, written in Rust.
|
||||
It is a aggregation of flake8, pylint, pyupgrade and many more.
|
||||
|
||||
$ flake8
|
||||
Ruff comes with a linter (``ruff check``) and a formatter (``ruff format``).
|
||||
The linter is a wrapper around flake8, pylint, and other linters,
|
||||
and the formatter is a wrapper around black, isort, and other formatters.
|
||||
|
||||
The config for flake8 is located in setup.cfg. It specifies:
|
||||
To run ruff without modifying your files: ::
|
||||
|
||||
* Set max line length to 120 chars
|
||||
* Exclude ``.tox,.git,*/migrations/*,*/static/CACHE/*,docs,node_modules``
|
||||
$ ruff format --diff .
|
||||
$ ruff check .
|
||||
|
||||
pylint
|
||||
------
|
||||
Ruff is capable of fixing most of the problems it encounters.
|
||||
Be sure you commit first before running `ruff` so you can restore to a savepoint (and amend afterwards to prevent a double commit. : ::
|
||||
|
||||
To run pylint: ::
|
||||
$ ruff format .
|
||||
$ ruff check --fix .
|
||||
# be careful with the --unsafe-fixes option, it can break your code
|
||||
$ ruff check --fix --unsafe-fixes .
|
||||
|
||||
$ pylint <python files that you wish to lint>
|
||||
|
||||
The config for pylint is located in .pylintrc. It specifies:
|
||||
|
||||
* Use the pylint_django plugin. If using Celery, also use pylint_celery.
|
||||
* Set max line length to 120 chars
|
||||
* Disable linting messages for missing docstring and invalid name
|
||||
* max-parents=13
|
||||
|
||||
pycodestyle
|
||||
-----------
|
||||
|
||||
This is included in flake8's checks, but you can also run it separately to see a more detailed report: ::
|
||||
|
||||
$ pycodestyle <python files that you wish to lint>
|
||||
|
||||
The config for pycodestyle is located in setup.cfg. It specifies:
|
||||
|
||||
* Set max line length to 120 chars
|
||||
* Exclude ``.tox,.git,*/migrations/*,*/static/CACHE/*,docs,node_modules``
|
||||
The config for ruff is located in pyproject.toml.
|
||||
On of the most important option is `tool.ruff.lint.select`.
|
||||
`select` determines which linters are run. In example, `DJ <https://docs.astral.sh/ruff/rules/#flake8-django-dj>`_ refers to flake8-django.
|
||||
For a full list of available linters, see `https://docs.astral.sh/ruff/rules/ <https://docs.astral.sh/ruff/rules/>`_
|
||||
|
|
|
@ -4,9 +4,7 @@ binaryornot==0.4.4
|
|||
|
||||
# Code quality
|
||||
# ------------------------------------------------------------------------------
|
||||
black==24.2.0
|
||||
isort==5.13.2
|
||||
flake8==7.0.0
|
||||
ruff==0.2.1
|
||||
django-upgrade==1.16.0
|
||||
djlint==1.34.1
|
||||
pre-commit==3.6.1
|
||||
|
|
|
@ -37,22 +37,11 @@
|
|||
"editor.codeActionsOnSave": {
|
||||
"source.organizeImports": true
|
||||
},
|
||||
// Uncomment when fixed
|
||||
// https://github.com/microsoft/vscode-remote-release/issues/8474
|
||||
// "editor.defaultFormatter": "ms-python.black-formatter",
|
||||
"formatting.blackPath": "/usr/local/bin/black",
|
||||
"formatting.provider": "black",
|
||||
"editor.defaultFormatter": "charliermarsh.ruff",
|
||||
"languageServer": "Pylance",
|
||||
// "linting.banditPath": "/usr/local/py-utils/bin/bandit",
|
||||
"linting.enabled": true,
|
||||
"linting.flake8Enabled": true,
|
||||
"linting.flake8Path": "/usr/local/bin/flake8",
|
||||
"linting.mypyEnabled": true,
|
||||
"linting.mypyPath": "/usr/local/bin/mypy",
|
||||
"linting.pycodestylePath": "/usr/local/bin/pycodestyle",
|
||||
// "linting.pydocstylePath": "/usr/local/py-utils/bin/pydocstyle",
|
||||
"linting.pylintEnabled": true,
|
||||
"linting.pylintPath": "/usr/local/bin/pylint"
|
||||
}
|
||||
},
|
||||
// https://code.visualstudio.com/docs/remote/devcontainerjson-reference#_vs-code-specific-properties
|
||||
|
|
|
@ -33,26 +33,15 @@ repos:
|
|||
- id: django-upgrade
|
||||
args: ['--target-version', '4.2']
|
||||
|
||||
- repo: https://github.com/asottile/pyupgrade
|
||||
rev: v3.15.0
|
||||
# Run the Ruff linter.
|
||||
- repo: https://github.com/astral-sh/ruff-pre-commit
|
||||
rev: v0.2.1
|
||||
hooks:
|
||||
- id: pyupgrade
|
||||
args: [--py311-plus]
|
||||
|
||||
- repo: https://github.com/psf/black
|
||||
rev: 24.2.0
|
||||
hooks:
|
||||
- id: black
|
||||
|
||||
- repo: https://github.com/PyCQA/isort
|
||||
rev: 5.13.2
|
||||
hooks:
|
||||
- id: isort
|
||||
|
||||
- repo: https://github.com/PyCQA/flake8
|
||||
rev: 7.0.0
|
||||
hooks:
|
||||
- id: flake8
|
||||
# Linter
|
||||
- id: ruff
|
||||
args: [--fix, --exit-non-zero-on-fix]
|
||||
# Formatter
|
||||
- id: ruff-format
|
||||
|
||||
- repo: https://github.com/Riverside-Healthcare/djLint
|
||||
rev: v1.34.1
|
||||
|
|
|
@ -10,9 +10,9 @@ jobs:
|
|||
include:
|
||||
- name: "Linter"
|
||||
before_script:
|
||||
- pip install -q flake8
|
||||
- pip install -q ruff
|
||||
script:
|
||||
- "flake8"
|
||||
- ruff check .
|
||||
|
||||
- name: "Django Test"
|
||||
{%- if cookiecutter.use_docker == 'y' %}
|
||||
|
@ -24,7 +24,7 @@ jobs:
|
|||
- docker compose -f local.yml run --rm django python manage.py migrate
|
||||
- docker compose -f local.yml up -d
|
||||
script:
|
||||
- "docker compose -f local.yml run django pytest"
|
||||
- docker compose -f local.yml run django pytest
|
||||
after_failure:
|
||||
- docker compose -f local.yml logs
|
||||
{%- else %}
|
||||
|
@ -41,5 +41,5 @@ jobs:
|
|||
install:
|
||||
- pip install -r requirements/local.txt
|
||||
script:
|
||||
- "pytest"
|
||||
- pytest
|
||||
{%- endif %}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
{{ cookiecutter.description }}
|
||||
|
||||
[![Built with Cookiecutter Django](https://img.shields.io/badge/built%20with-Cookiecutter%20Django-ff69b4.svg?logo=cookiecutter)](https://github.com/cookiecutter/cookiecutter-django/)
|
||||
[![Black code style](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/ambv/black)
|
||||
[![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)
|
||||
|
||||
{%- if cookiecutter.open_source_license != "Not open source" %}
|
||||
|
||||
|
|
|
@ -16,25 +16,6 @@ include = ["{{cookiecutter.project_slug}}/**"]
|
|||
omit = ["*/migrations/*", "*/tests/*"]
|
||||
plugins = ["django_coverage_plugin"]
|
||||
|
||||
|
||||
# ==== black ====
|
||||
[tool.black]
|
||||
line-length = 119
|
||||
target-version = ['py311']
|
||||
|
||||
|
||||
# ==== isort ====
|
||||
[tool.isort]
|
||||
profile = "black"
|
||||
line_length = 119
|
||||
known_first_party = [
|
||||
"{{cookiecutter.project_slug}}",
|
||||
"config",
|
||||
]
|
||||
skip = ["venv/"]
|
||||
skip_glob = ["**/migrations/*.py"]
|
||||
|
||||
|
||||
# ==== mypy ====
|
||||
[tool.mypy]
|
||||
python_version = "3.11"
|
||||
|
@ -58,40 +39,6 @@ ignore_errors = true
|
|||
[tool.django-stubs]
|
||||
django_settings_module = "config.settings.test"
|
||||
|
||||
|
||||
# ==== PyLint ====
|
||||
[tool.pylint.MASTER]
|
||||
load-plugins = [
|
||||
"pylint_django",
|
||||
{%- if cookiecutter.use_celery == "y" %}
|
||||
"pylint_celery",
|
||||
{%- endif %}
|
||||
]
|
||||
django-settings-module = "config.settings.local"
|
||||
|
||||
[tool.pylint.FORMAT]
|
||||
max-line-length = 119
|
||||
|
||||
[tool.pylint."MESSAGES CONTROL"]
|
||||
disable = [
|
||||
"missing-docstring",
|
||||
"invalid-name",
|
||||
]
|
||||
|
||||
[tool.pylint.DESIGN]
|
||||
max-parents = 13
|
||||
|
||||
[tool.pylint.TYPECHECK]
|
||||
generated-members = [
|
||||
"REQUEST",
|
||||
"acl_users",
|
||||
"aq_parent",
|
||||
"[a-zA-Z]+_set{1,2}",
|
||||
"save",
|
||||
"delete",
|
||||
]
|
||||
|
||||
|
||||
# ==== djLint ====
|
||||
[tool.djlint]
|
||||
blank_line_after_tag = "load,extends"
|
||||
|
@ -110,3 +57,112 @@ indent_size = 2
|
|||
|
||||
[tool.djlint.js]
|
||||
indent_size = 2
|
||||
|
||||
[tool.ruff]
|
||||
# Exclude a variety of commonly ignored directories.
|
||||
exclude = [
|
||||
".bzr",
|
||||
".direnv",
|
||||
".eggs",
|
||||
".git",
|
||||
".git-rewrite",
|
||||
".hg",
|
||||
".mypy_cache",
|
||||
".nox",
|
||||
".pants.d",
|
||||
".pytype",
|
||||
".ruff_cache",
|
||||
".svn",
|
||||
".tox",
|
||||
".venv",
|
||||
"__pypackages__",
|
||||
"_build",
|
||||
"buck-out",
|
||||
"build",
|
||||
"dist",
|
||||
"node_modules",
|
||||
"venv",
|
||||
"*/migrations/*.py",
|
||||
"staticfiles/*"
|
||||
]
|
||||
# Same as Django: https://github.com/cookiecutter/cookiecutter-django/issues/4792.
|
||||
line-length = 88
|
||||
indent-width = 4
|
||||
target-version = "py311"
|
||||
|
||||
[tool.ruff.lint]
|
||||
select = [
|
||||
"F",
|
||||
"E",
|
||||
"W",
|
||||
"C90",
|
||||
"I",
|
||||
"N",
|
||||
"UP",
|
||||
"YTT",
|
||||
# "ANN", # flake8-annotations: we should support this in the future but 100+ errors atm
|
||||
"ASYNC",
|
||||
"S",
|
||||
"BLE",
|
||||
"FBT",
|
||||
"B",
|
||||
"A",
|
||||
"COM",
|
||||
"C4",
|
||||
"DTZ",
|
||||
"T10",
|
||||
"DJ",
|
||||
"EM",
|
||||
"EXE",
|
||||
"FA",
|
||||
'ISC',
|
||||
"ICN",
|
||||
"G",
|
||||
'INP',
|
||||
'PIE',
|
||||
"T20",
|
||||
'PYI',
|
||||
'PT',
|
||||
"Q",
|
||||
"RSE",
|
||||
"RET",
|
||||
"SLF",
|
||||
"SLOT",
|
||||
"SIM",
|
||||
"TID",
|
||||
"TCH",
|
||||
"INT",
|
||||
# "ARG", # Unused function argument
|
||||
"PTH",
|
||||
"ERA",
|
||||
"PD",
|
||||
"PGH",
|
||||
"PL",
|
||||
"TRY",
|
||||
"FLY",
|
||||
# "NPY",
|
||||
# "AIR",
|
||||
"PERF",
|
||||
# "FURB",
|
||||
# "LOG",
|
||||
"RUF"
|
||||
]
|
||||
ignore = [
|
||||
"S101", # Use of assert detected https://docs.astral.sh/ruff/rules/assert/
|
||||
"RUF012", # Mutable class attributes should be annotated with `typing.ClassVar`
|
||||
"SIM102" # sometimes it's better to nest
|
||||
]
|
||||
# Allow fix for all enabled rules (when `--fix`) is provided.
|
||||
fixable = ["ALL"]
|
||||
unfixable = []
|
||||
# Allow unused variables when underscore-prefixed.
|
||||
dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$"
|
||||
|
||||
[tool.ruff.format]
|
||||
quote-style = "double"
|
||||
indent-style = "space"
|
||||
skip-magic-trailing-comma = false
|
||||
line-ending = "auto"
|
||||
|
||||
[tool.ruff.lint.isort]
|
||||
force-single-line = true
|
||||
|
|
|
@ -28,15 +28,9 @@ sphinx-autobuild==2024.2.4 # https://github.com/GaretJax/sphinx-autobuild
|
|||
|
||||
# Code quality
|
||||
# ------------------------------------------------------------------------------
|
||||
flake8==7.0.0 # https://github.com/PyCQA/flake8
|
||||
flake8-isort==6.1.1 # https://github.com/gforcada/flake8-isort
|
||||
ruff==0.2.1
|
||||
coverage==7.4.1 # https://github.com/nedbat/coveragepy
|
||||
black==24.2.0 # https://github.com/psf/black
|
||||
djlint==1.34.1 # https://github.com/Riverside-Healthcare/djLint
|
||||
pylint-django==2.5.5 # 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.6.1 # https://github.com/pre-commit/pre-commit
|
||||
|
||||
# Django
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
# flake8 and pycodestyle don't support pyproject.toml
|
||||
# https://github.com/PyCQA/flake8/issues/234
|
||||
# https://github.com/PyCQA/pycodestyle/issues/813
|
||||
[flake8]
|
||||
max-line-length = 119
|
||||
exclude = .tox,.git,*/migrations/*,*/static/CACHE/*,docs,node_modules,venv,.venv
|
||||
extend-ignore = E203
|
||||
|
||||
[pycodestyle]
|
||||
max-line-length = 119
|
||||
exclude = .tox,.git,*/migrations/*,*/static/CACHE/*,docs,node_modules,venv,.venv
|
|
@ -58,7 +58,7 @@ class TestUserAdmin:
|
|||
def force_allauth(self, settings):
|
||||
settings.DJANGO_ADMIN_FORCE_ALLAUTH = True
|
||||
# Reload the admin module to apply the setting change
|
||||
import {{ cookiecutter.project_slug }}.users.admin as users_admin # pylint: disable=import-outside-toplevel
|
||||
import {{ cookiecutter.project_slug }}.users.admin as users_admin
|
||||
|
||||
try:
|
||||
reload(users_admin)
|
||||
|
|
Loading…
Reference in New Issue
Block a user