root: add ruff linter (#5240)

* root: add ruff linter

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* actually add ruff

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* fix lint

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

---------

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
This commit is contained in:
Jens L 2023-04-18 13:28:19 +02:00 committed by GitHub
parent 5f99887b50
commit dfa80543b5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 108 additions and 70 deletions

View File

@ -23,13 +23,14 @@ jobs:
fail-fast: false fail-fast: false
matrix: matrix:
job: job:
- pylint
- black
- isort
- bandit - bandit
- pyright - black
- pending-migrations
- codespell - codespell
- isort
- pending-migrations
- pylint
- pyright
- ruff
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v3

View File

@ -3,6 +3,7 @@ PWD = $(shell pwd)
UID = $(shell id -u) UID = $(shell id -u)
GID = $(shell id -g) GID = $(shell id -g)
NPM_VERSION = $(shell python -m scripts.npm_version) NPM_VERSION = $(shell python -m scripts.npm_version)
PY_SOURCES = authentik tests scripts lifecycle
CODESPELL_ARGS = -D - -D .github/codespell-dictionary.txt \ CODESPELL_ARGS = -D - -D .github/codespell-dictionary.txt \
-I .github/codespell-words.txt \ -I .github/codespell-words.txt \
@ -38,13 +39,14 @@ test:
coverage report coverage report
lint-fix: lint-fix:
isort authentik tests scripts lifecycle isort authentik $(PY_SOURCES)
black authentik tests scripts lifecycle black authentik $(PY_SOURCES)
ruff authentik $(PY_SOURCES)
codespell -w $(CODESPELL_ARGS) codespell -w $(CODESPELL_ARGS)
lint: lint:
pylint authentik tests lifecycle pylint $(PY_SOURCES)
bandit -r authentik tests lifecycle -x node_modules bandit -r $(PY_SOURCES) -x node_modules
golangci-lint run -v golangci-lint run -v
migrate: migrate:
@ -171,7 +173,6 @@ website-watch:
# These targets are use by GitHub actions to allow usage of matrix # These targets are use by GitHub actions to allow usage of matrix
# which makes the YAML File a lot smaller # which makes the YAML File a lot smaller
PY_SOURCES=authentik tests lifecycle
ci--meta-debug: ci--meta-debug:
python -V python -V
node --version node --version
@ -182,6 +183,9 @@ ci-pylint: ci--meta-debug
ci-black: ci--meta-debug ci-black: ci--meta-debug
black --check $(PY_SOURCES) black --check $(PY_SOURCES)
ci-ruff: ci--meta-debug
ruff check $(PY_SOURCES)
ci-codespell: ci--meta-debug ci-codespell: ci--meta-debug
codespell $(CODESPELL_ARGS) -s codespell $(CODESPELL_ARGS) -s

View File

@ -6,7 +6,6 @@ from pathlib import Path
import django.contrib.postgres.fields import django.contrib.postgres.fields
from dacite.core import from_dict from dacite.core import from_dict
from django.apps.registry import Apps from django.apps.registry import Apps
from django.conf import settings
from django.db import migrations, models from django.db import migrations, models
from django.db.backends.base.schema import BaseDatabaseSchemaEditor from django.db.backends.base.schema import BaseDatabaseSchemaEditor
from yaml import load from yaml import load
@ -15,7 +14,7 @@ from authentik.blueprints.v1.labels import LABEL_AUTHENTIK_SYSTEM
from authentik.lib.config import CONFIG from authentik.lib.config import CONFIG
def check_blueprint_v1_file(BlueprintInstance: type["BlueprintInstance"], path: Path): def check_blueprint_v1_file(BlueprintInstance: type, path: Path):
"""Check if blueprint should be imported""" """Check if blueprint should be imported"""
from authentik.blueprints.models import BlueprintInstanceStatus from authentik.blueprints.models import BlueprintInstanceStatus
from authentik.blueprints.v1.common import BlueprintLoader, BlueprintMetadata from authentik.blueprints.v1.common import BlueprintLoader, BlueprintMetadata

View File

@ -2,8 +2,6 @@
from django.db import migrations from django.db import migrations
from authentik.lib.generators import generate_id
class Migration(migrations.Migration): class Migration(migrations.Migration):
dependencies = [ dependencies = [

View File

@ -11,7 +11,6 @@ from django.db.backends.base.schema import BaseDatabaseSchemaEditor
import authentik.events.models import authentik.events.models
import authentik.lib.models import authentik.lib.models
from authentik.events.models import EventAction, NotificationSeverity, TransportMode
from authentik.lib.migrations import progress_bar from authentik.lib.migrations import progress_bar

View File

@ -13,7 +13,6 @@ from paramiko.ssh_exception import SSHException
from structlog.stdlib import get_logger from structlog.stdlib import get_logger
from yaml import safe_dump from yaml import safe_dump
from authentik import __version__
from authentik.outposts.apps import MANAGED_OUTPOST from authentik.outposts.apps import MANAGED_OUTPOST
from authentik.outposts.controllers.base import BaseClient, BaseController, ControllerException from authentik.outposts.controllers.base import BaseClient, BaseController, ControllerException
from authentik.outposts.docker_ssh import DockerInlineSSH, SSHManagedExternallyException from authentik.outposts.docker_ssh import DockerInlineSSH, SSHManagedExternallyException

View File

@ -22,7 +22,7 @@ from kubernetes.client import (
V1SecurityContext, V1SecurityContext,
) )
from authentik import __version__, get_full_version from authentik import get_full_version
from authentik.outposts.controllers.base import FIELD_MANAGER from authentik.outposts.controllers.base import FIELD_MANAGER
from authentik.outposts.controllers.k8s.base import KubernetesObjectReconciler from authentik.outposts.controllers.k8s.base import KubernetesObjectReconciler
from authentik.outposts.controllers.k8s.triggers import NeedsUpdate from authentik.outposts.controllers.k8s.triggers import NeedsUpdate

View File

@ -1,10 +1,8 @@
# Generated by Django 3.1 on 2020-08-18 15:59 # Generated by Django 3.1 on 2020-08-18 15:59
import django.db.models.deletion import django.db.models.deletion
from django.apps.registry import Apps
from django.conf import settings from django.conf import settings
from django.db import migrations, models from django.db import migrations, models
from django.db.backends.base.schema import BaseDatabaseSchemaEditor
import authentik.core.models import authentik.core.models
import authentik.lib.generators import authentik.lib.generators

View File

@ -3,8 +3,6 @@
import django.contrib.postgres.fields import django.contrib.postgres.fields
from django.db import migrations, models from django.db import migrations, models
import authentik.lib.generators
class Migration(migrations.Migration): class Migration(migrations.Migration):
dependencies = [ dependencies = [

View File

@ -10,7 +10,6 @@ from duo_client.admin import Admin
from duo_client.auth import Auth from duo_client.auth import Auth
from rest_framework.serializers import BaseSerializer, Serializer from rest_framework.serializers import BaseSerializer, Serializer
from authentik import __version__
from authentik.core.types import UserSettingSerializer from authentik.core.types import UserSettingSerializer
from authentik.flows.models import ConfigurableStage, FriendlyNamedStage, Stage from authentik.flows.models import ConfigurableStage, FriendlyNamedStage, Stage
from authentik.lib.models import SerializerModel from authentik.lib.models import SerializerModel

View File

@ -4,7 +4,7 @@ from django.apps.registry import Apps
from django.db import migrations, models from django.db import migrations, models
from django.db.backends.base.schema import BaseDatabaseSchemaEditor from django.db.backends.base.schema import BaseDatabaseSchemaEditor
from authentik.stages.password import BACKEND_APP_PASSWORD, BACKEND_INBUILT from authentik.stages.password import BACKEND_APP_PASSWORD
def update_default_backends(apps: Apps, schema_editor: BaseDatabaseSchemaEditor): def update_default_backends(apps: Apps, schema_editor: BaseDatabaseSchemaEditor):

View File

@ -1,7 +1,6 @@
# Generated by Django 3.2.6 on 2021-08-23 14:34 # Generated by Django 3.2.6 on 2021-08-23 14:34
import django.contrib.postgres.fields
from django.apps.registry import Apps from django.apps.registry import Apps
from django.db import migrations, models from django.db import migrations
from django.db.backends.base.schema import BaseDatabaseSchemaEditor from django.db.backends.base.schema import BaseDatabaseSchemaEditor
from authentik.stages.password import BACKEND_INBUILT from authentik.stages.password import BACKEND_INBUILT

View File

@ -3,9 +3,7 @@
import uuid import uuid
import django.db.models.deletion import django.db.models.deletion
from django.apps.registry import Apps
from django.db import migrations, models from django.db import migrations, models
from django.db.backends.base.schema import BaseDatabaseSchemaEditor
import authentik.lib.utils.time import authentik.lib.utils.time

View File

@ -155,6 +155,6 @@ if not CONFIG.y_bool("disable_startup_analytics", False):
}, },
timeout=5, timeout=5,
) )
# pylint: disable=bare-except # pylint: disable=broad-exception-caught
except: # nosec except Exception: # nosec
pass pass

46
poetry.lock generated
View File

@ -1,4 +1,4 @@
# This file is automatically @generated by Poetry and should not be changed by hand. # This file is automatically @generated by Poetry 1.4.2 and should not be changed by hand.
[[package]] [[package]]
name = "aiohttp" name = "aiohttp"
@ -2780,6 +2780,21 @@ pytest = ">=5.4.0"
docs = ["sphinx", "sphinx-rtd-theme"] docs = ["sphinx", "sphinx-rtd-theme"]
testing = ["Django", "django-configurations (>=2.0)"] testing = ["Django", "django-configurations (>=2.0)"]
[[package]]
name = "pytest-github-actions-annotate-failures"
version = "0.1.8"
description = "pytest plugin to annotate failed tests with a workflow command for GitHub Actions"
category = "dev"
optional = false
python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*"
files = [
{file = "pytest-github-actions-annotate-failures-0.1.8.tar.gz", hash = "sha256:2d6e6cb5f8d0aae4a27a20cc4e20fabd3199a121c57f44bc48fe28e372e0be23"},
{file = "pytest_github_actions_annotate_failures-0.1.8-py2.py3-none-any.whl", hash = "sha256:6a882ff21672fa79deae8d917eb965a6bde2b25191e7632e1adfc23ffac008ab"},
]
[package.dependencies]
pytest = ">=4.0.0"
[[package]] [[package]]
name = "pytest-randomly" name = "pytest-randomly"
version = "3.12.0" version = "3.12.0"
@ -3025,6 +3040,33 @@ files = [
[package.dependencies] [package.dependencies]
pyasn1 = ">=0.1.3" pyasn1 = ">=0.1.3"
[[package]]
name = "ruff"
version = "0.0.261"
description = "An extremely fast Python linter, written in Rust."
category = "dev"
optional = false
python-versions = ">=3.7"
files = [
{file = "ruff-0.0.261-py3-none-macosx_10_7_x86_64.whl", hash = "sha256:6624a966c4a21110cee6780333e2216522a831364896f3d98f13120936eff40a"},
{file = "ruff-0.0.261-py3-none-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl", hash = "sha256:2dba68a9e558ab33e6dd5d280af798a2d9d3c80c913ad9c8b8e97d7b287f1cc9"},
{file = "ruff-0.0.261-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8dbd0cee5a81b0785dc0feeb2640c1e31abe93f0d77c5233507ac59731a626f1"},
{file = "ruff-0.0.261-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:581e64fa1518df495ca890a605ee65065101a86db56b6858f848bade69fc6489"},
{file = "ruff-0.0.261-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cc970f6ece0b4950e419f0252895ee42e9e8e5689c6494d18f5dc2c6ebb7f798"},
{file = "ruff-0.0.261-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:8fa98e747e0fe185d65a40b0ea13f55c492f3b5f9a032a1097e82edaddb9e52e"},
{file = "ruff-0.0.261-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f268d52a71bf410aa45c232870c17049df322a7d20e871cfe622c9fc784aab7b"},
{file = "ruff-0.0.261-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d1293acc64eba16a11109678dc4743df08c207ed2edbeaf38b3e10eb2597321b"},
{file = "ruff-0.0.261-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d95596e2f4cafead19a6d1ec0b86f8fda45ba66fe934de3956d71146a87959b3"},
{file = "ruff-0.0.261-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:4bcec45abdf65c1328a269cf6cc193f7ff85b777fa2865c64cf2c96b80148a2c"},
{file = "ruff-0.0.261-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:6c5f397ec0af42a434ad4b6f86565027406c5d0d0ebeea0d5b3f90c4bf55bc82"},
{file = "ruff-0.0.261-py3-none-musllinux_1_2_i686.whl", hash = "sha256:39abd02342cec0c131b2ddcaace08b2eae9700cab3ca7dba64ae5fd4f4881bd0"},
{file = "ruff-0.0.261-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:aaa4f52a6e513f8daa450dac4859e80390d947052f592f0d8e796baab24df2fc"},
{file = "ruff-0.0.261-py3-none-win32.whl", hash = "sha256:daff64b4e86e42ce69e6367d63aab9562fc213cd4db0e146859df8abc283dba0"},
{file = "ruff-0.0.261-py3-none-win_amd64.whl", hash = "sha256:0fbc689c23609edda36169c8708bb91bab111d8f44cb4a88330541757770ab30"},
{file = "ruff-0.0.261-py3-none-win_arm64.whl", hash = "sha256:d2eddc60ae75fc87f8bb8fd6e8d5339cf884cd6de81e82a50287424309c187ba"},
{file = "ruff-0.0.261.tar.gz", hash = "sha256:c1c715b0d1e18f9c509d7c411ca61da3543a4aa459325b1b1e52b8301d65c6d2"},
]
[[package]] [[package]]
name = "selenium" name = "selenium"
version = "4.8.3" version = "4.8.3"
@ -4062,4 +4104,4 @@ files = [
[metadata] [metadata]
lock-version = "2.0" lock-version = "2.0"
python-versions = "^3.11" python-versions = "^3.11"
content-hash = "61d20a7f2b76b6554b4c2095db152395c41d6c650b2f7f16662d5ed2f8cc0983" content-hash = "8712c3c416712e7577cf1b1e3685e7032e3a4bdbd797ad99508554b15e0a2fbf"

View File

@ -17,6 +17,11 @@ line-length = 100
target-version = ['py311'] target-version = ['py311']
exclude = 'node_modules' exclude = 'node_modules'
[tool.ruff]
line-length = 100
target-version = "py311"
exclude = ["**/migrations/**", "**/node_modules/**"]
[tool.isort] [tool.isort]
multi_line_output = 3 multi_line_output = 3
include_trailing_comma = true include_trailing_comma = true
@ -30,12 +35,12 @@ force_to_top = "*"
source = ["authentik"] source = ["authentik"]
relative_files = true relative_files = true
omit = [ omit = [
"*/asgi.py", "*/asgi.py",
"manage.py", "manage.py",
"*/migrations/*", "*/migrations/*",
"*/management/commands/*", "*/management/commands/*",
"*/apps.py", "*/apps.py",
"website/", "website/",
] ]
[tool.coverage.report] [tool.coverage.report]
@ -43,19 +48,19 @@ sort = "Cover"
skip_covered = true skip_covered = true
precision = 2 precision = 2
exclude_lines = [ exclude_lines = [
"pragma: no cover", "pragma: no cover",
# Don't complain about missing debug-only code: # Don't complain about missing debug-only code:
"def __unicode__", "def __unicode__",
"def __str__", "def __str__",
"def __repr__", "def __repr__",
"if self.debug", "if self.debug",
"if TYPE_CHECKING", "if TYPE_CHECKING",
# Don't complain if tests don't hit defensive assertion code: # Don't complain if tests don't hit defensive assertion code:
"raise AssertionError", "raise AssertionError",
"raise NotImplementedError", "raise NotImplementedError",
# Don't complain if non-runnable code isn't run: # Don't complain if non-runnable code isn't run:
"if 0:", "if 0:",
"if __name__ == .__main__.:", "if __name__ == .__main__.:",
] ]
show_missing = true show_missing = true
@ -64,20 +69,20 @@ good-names = ["pk", "id", "i", "j", "k", "_", "bar"]
[tool.pylint.master] [tool.pylint.master]
disable = [ disable = [
"arguments-differ", "arguments-differ",
"locally-disabled", "locally-disabled",
"too-many-ancestors", "too-many-ancestors",
"too-few-public-methods", "too-few-public-methods",
"import-outside-toplevel", "import-outside-toplevel",
"signature-differs", "signature-differs",
"similarities", "similarities",
"cyclic-import", "cyclic-import",
"protected-access", "protected-access",
"unused-argument", "unused-argument",
"raise-missing-from", "raise-missing-from",
"fixme", "fixme",
# To preserve django's translation function we need to use %-formatting # To preserve django's translation function we need to use %-formatting
"consider-using-f-string", "consider-using-f-string",
] ]
load-plugins = ["pylint_django", "pylint.extensions.bad_builtin"] load-plugins = ["pylint_django", "pylint.extensions.bad_builtin"]
@ -99,8 +104,8 @@ python_files = ["tests.py", "test_*.py", "*_tests.py"]
junit_family = "xunit2" junit_family = "xunit2"
addopts = "-p no:celery --junitxml=unittest.xml" addopts = "-p no:celery --junitxml=unittest.xml"
filterwarnings = [ filterwarnings = [
"ignore:defusedxml.lxml is no longer supported and will be removed in a future release.:DeprecationWarning", "ignore:defusedxml.lxml is no longer supported and will be removed in a future release.:DeprecationWarning",
"ignore:SelectableGroups dict interface is deprecated. Use select.:DeprecationWarning", "ignore:SelectableGroups dict interface is deprecated. Use select.:DeprecationWarning",
] ]
[tool.poetry] [tool.poetry]
@ -176,8 +181,10 @@ pylint-django = "*"
pyrad = "*" pyrad = "*"
pytest = "*" pytest = "*"
pytest-django = "*" pytest-django = "*"
pytest-github-actions-annotate-failures = "*"
pytest-randomly = "*" pytest-randomly = "*"
requests-mock = "*" requests-mock = "*"
ruff = "*"
selenium = "*" selenium = "*"
[build-system] [build-system]

View File

@ -3,7 +3,7 @@ from yaml import safe_dump
from authentik.lib.generators import generate_id from authentik.lib.generators import generate_id
with open("local.env.yml", "w") as _config: with open("local.env.yml", "w", encoding="utf-8") as _config:
safe_dump( safe_dump(
{ {
"log_level": "debug", "log_level": "debug",

View File

@ -11,7 +11,6 @@ from docker.client import DockerClient, from_env
from docker.models.containers import Container from docker.models.containers import Container
from selenium.webdriver.common.by import By from selenium.webdriver.common.by import By
from authentik import __version__
from authentik.blueprints.tests import apply_blueprint, reconcile_app from authentik.blueprints.tests import apply_blueprint, reconcile_app
from authentik.core.models import Application from authentik.core.models import Application
from authentik.flows.models import Flow from authentik.flows.models import Flow

View File

@ -9,7 +9,6 @@ from docker import DockerClient, from_env
from docker.models.containers import Container from docker.models.containers import Container
from docker.types.healthcheck import Healthcheck from docker.types.healthcheck import Healthcheck
from authentik import __version__
from authentik.core.tests.utils import create_test_flow from authentik.core.tests.utils import create_test_flow
from authentik.crypto.models import CertificateKeyPair from authentik.crypto.models import CertificateKeyPair
from authentik.outposts.controllers.docker import DockerController from authentik.outposts.controllers.docker import DockerController

View File

@ -9,7 +9,6 @@ from docker import DockerClient, from_env
from docker.models.containers import Container from docker.models.containers import Container
from docker.types.healthcheck import Healthcheck from docker.types.healthcheck import Healthcheck
from authentik import __version__
from authentik.core.tests.utils import create_test_flow from authentik.core.tests.utils import create_test_flow
from authentik.crypto.models import CertificateKeyPair from authentik.crypto.models import CertificateKeyPair
from authentik.outposts.models import ( from authentik.outposts.models import (