diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a4f3a07e365..c2381a986d5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -47,67 +47,15 @@ }, { "name": "Set up packages", - "run": "set -e\n\npip install -U pip setuptools wheel\npip install -U \\\n flake8 pylint pylint-django pylint-plugin-utils isort black autopep8 \\\n coveralls pyyaml pytest-django\npip install -U -r requirements.txt\n\necho \"PATH=$PATH\" >> $GITHUB_ENV\n" + "run": "set -e\n\npip install -U pip setuptools wheel\npip install -U \\\n pre-commit coveralls pyyaml pytest-django\npip install -U -r requirements.txt\n\necho \"PATH=$PATH\" >> $GITHUB_ENV\n" }, { "name": "Copy secret.py", "run": "cp intranet/settings/ci_secret.py intranet/settings/secret.py" }, { - "name": "Run flake8", - "run": "flake8 --max-line-length 150 --exclude=*/migrations/* intranet/ scripts/ docs/ *.py" - }, - { - "name": "Run pylintx", - "run": "pylint --jobs=0 --disable=fixme,broad-exception-caught,broad-exception-raised,unsupported-binary-operation,global-statement,attribute-defined-outside-init,cyclic-import,consider-using-f-string --django-settings-module=intranet.settings intranet/" - } - ] - }, - "formatting": { - "runs-on": "ubuntu-latest", - "strategy": { - "matrix": { - "python-version": [ - 3.8 - ] - }, - "fail-fast": false - }, - "steps": [ - { - "name": "Set up repo", - "uses": "actions/checkout@v2" - }, - { - "name": "Set up Python ${{ matrix.python-version }}", - "uses": "actions/setup-python@v2", - "with": { - "python-version": "${{ matrix.python-version }}" - } - }, - { - "name": "Set up pip cache", - "uses": "actions/cache@v2", - "with": { - "path": "~/.cache/pip", - "key": "pip-${{ matrix.python-version }}" - } - }, - { - "name": "Set up packages", - "run": "set -e\n\npip install -U pip setuptools wheel\npip install -U \\\n flake8 pylint pylint-django pylint-plugin-utils isort black autopep8 \\\n coveralls pyyaml pytest-django\npip install -U -r requirements.txt\n\necho \"PATH=$PATH\" >> $GITHUB_ENV\n" - }, - { - "name": "Copy secret.py", - "run": "cp intranet/settings/ci_secret.py intranet/settings/secret.py" - }, - { - "name": "Format code", - "run": "./scripts/build_ensure_no_changes.sh ./scripts/format.sh" - }, - { - "name": "Format static files and templates", - "run": "./scripts/build_ensure_no_changes.sh ./scripts/static_templates_format.sh" + "name": "Run pre-commit", + "run": "pre-commit run --all-files" } ] }, @@ -146,7 +94,7 @@ }, { "name": "Set up packages", - "run": "set -e\n\npip install -U pip setuptools wheel\npip install -U \\\n flake8 pylint pylint-django pylint-plugin-utils isort black autopep8 \\\n coveralls pyyaml pytest-django\npip install -U -r requirements.txt\n\necho \"PATH=$PATH\" >> $GITHUB_ENV\n" + "run": "set -e\n\npip install -U pip setuptools wheel\npip install -U \\\n pre-commit coveralls pyyaml pytest-django\npip install -U -r requirements.txt\n\necho \"PATH=$PATH\" >> $GITHUB_ENV\n" }, { "name": "Copy secret.py", @@ -251,7 +199,7 @@ }, { "name": "Set up packages", - "run": "set -e\n\npip install -U pip setuptools wheel\npip install -U \\\n flake8 pylint pylint-django pylint-plugin-utils isort black autopep8 \\\n coveralls pyyaml pytest-django\npip install -U -r requirements.txt\n\necho \"PATH=$PATH\" >> $GITHUB_ENV\n" + "run": "set -e\n\npip install -U pip setuptools wheel\npip install -U \\\n pre-commit coveralls pyyaml pytest-django\npip install -U -r requirements.txt\n\necho \"PATH=$PATH\" >> $GITHUB_ENV\n" }, { "name": "Copy secret.py", @@ -328,7 +276,6 @@ "finish_success": { "needs": [ "linting", - "formatting", "build", "tests" ], diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 00000000000..df754f70ded --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,43 @@ +default_stages: [commit, push] +fail_fast: false +exclude: ^(intranet/middleware|intranet/apps/.*/migrations|intranet/static/.*vendor/.*|intranet/.*/stubs|Ion.egg-info|\.github) + +# This is for pre-commit ci +# After adding pre-commit ci, the "linting" stage of the tests +# can be safely deleted +ci: + autofix_commit_msg: | + chore: auto fixes from pre-commit hooks + + for more information, see https://pre-commit.ci + autoupdate_commit_msg: 'build: pre-commit autoupdate' + +repos: + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.4.0 + hooks: + - id: check-ast + name: Validate Python + - id: trailing-whitespace + - id: mixed-line-ending + args: ["--fix=lf"] + - id: check-toml + - id: check-yaml + - id: detect-private-key + - repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.3.5 + hooks: + - id: ruff + args: [ "--fix", "--exit-non-zero-on-fix" ] + name: ruff lint + files: ^intranet/apps/.* + - id: ruff-format + files: ^intranet/apps/.* + - repo: https://github.com/codespell-project/codespell + rev: v2.2.5 + hooks: + - id: codespell + files: ^.*\.(py|md|rst)$ + # TODO: Remove after python version >= 3.11 + additional_dependencies: + - tomli diff --git a/Ion.egg-info/SOURCES.txt b/Ion.egg-info/SOURCES.txt index 3112c26638b..0cde27ad002 100644 --- a/Ion.egg-info/SOURCES.txt +++ b/Ion.egg-info/SOURCES.txt @@ -4,6 +4,7 @@ .gitattributes .gitignore .isort.cfg +.pre-commit-config.yaml .pylintrc .style.yapf CONTRIBUTING.md diff --git a/ci/spec.yml b/ci/spec.yml index f12f1670462..7a379b52643 100644 --- a/ci/spec.yml +++ b/ci/spec.yml @@ -57,8 +57,7 @@ env: pip install -U pip setuptools wheel pip install -U \ - flake8 pylint pylint-django pylint-plugin-utils isort black autopep8 \ - coveralls pyyaml pytest-django + pre-commit coveralls pyyaml pytest-django pip install -U -r requirements.txt echo "PATH=$PATH" >> $GITHUB_ENV @@ -83,30 +82,8 @@ jobs: - *setup_packages - *copy_secret - - name: Run flake8 - run: 'flake8 --max-line-length 150 --exclude=*/migrations/* intranet/ scripts/ docs/ *.py' - - name: Run pylintx - run: pylint --jobs=0 --disable=fixme,broad-exception-caught,broad-exception-raised,unsupported-binary-operation,global-statement,attribute-defined-outside-init,cyclic-import,consider-using-f-string --django-settings-module=intranet.settings intranet/ - - formatting: - runs-on: ubuntu-latest - - strategy: - matrix: - python-version: *python_versions - fail-fast: false - - steps: - - *repo_setup - - *python_setup - - *setup_pip_cache - - *setup_packages - - *copy_secret - - - name: Format code - run: ./scripts/build_ensure_no_changes.sh ./scripts/format.sh - - name: Format static files and templates - run: ./scripts/build_ensure_no_changes.sh ./scripts/static_templates_format.sh + - name: Run pre-commit + run: 'pre-commit run --all-files' build: runs-on: ubuntu-latest @@ -256,7 +233,6 @@ jobs: finish_success: needs: - linting - - formatting - build - tests diff --git a/pyproject.toml b/pyproject.toml index 853b7e3700b..085f22884ae 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -42,3 +42,93 @@ exclude = ''' | stubs )/ ''' + +[tool.ruff] +extend-exclude = [ + "Ion.egg-info", + "build", + ".env", + "env", + "migrations", +] + +# show fixes made in stdout +# show-fixes = true + +line-length = 150 + +target-version = "py38" + +[tool.ruff.lint] +select = [ + # flake8-bugbear + "B", + # flake8-comprehensions + "C4", + # flake8-django + "DJ", + # pycodestyle + "E", + # Pyflakes + "F", + # isort + "I", + # flake8-no-pep420 + "INP", + # Pylint + "PL", + # ruff + "RUF", + # pyupgrade + "UP", +] +ignore = [ + # default arguments for timezone.now() + "B008", + # null=True on CharField/TextField + "DJ001", + # No __str__ method on Model + "DJ008", + # Django order of model methods + "DJ012", + # ambiguous variable name + "E741", + # as recommended by https://docs.astral.sh/ruff/formatter/#conflicting-lint-rules + "E111", + "E114", + "E117", + "E501", + # branching + "PLR09", + # avoid magic numbers + "PLR2004", + # loop variables overwritten by assignment + "PLW2901", + # Use ternary operator (x if cond else y) + "RUF005", + # mutable class attrs annotated as typing.ClassVar + "RUF012", + # implicit Optional + "RUF013", +] + +[tool.ruff.lint.per-file-ignores] +"__init__.py" = [ + "F401", + "F403", +] + +[tool.ruff.lint.flake8-pytest-style] +fixture-parentheses = false +mark-parentheses = false +parametrize-names-type = "tuple" +parametrize-values-type = "tuple" + +[tool.ruff.format] +docstring-code-format = true +line-ending = "lf" + +[tool.codespell] +write-changes = true +skip = "*.pyi,*/vendor,*/migrations,*media" +ignore-words-list = "num,ans,intranet" diff --git a/requirements-dev.txt b/requirements-dev.txt index 96156df604a..2699d5bc1cd 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -9,3 +9,4 @@ pylint-django==2.5.5 pylint-plugin-utils==0.8.2 names==0.3.0 whitenoise==6.6.0 +pre-commit==3.5.0