mirror of
https://github.com/encode/django-rest-framework.git
synced 2024-11-28 04:24:00 +03:00
Lint with pre-commit (#7900)
Following [my comment here](https://github.com/encode/django-rest-framework/pull/7589#issuecomment-813301322) and [Django's own move to pre-commit](https://docs.djangoproject.com/en/dev/internals/contributing/writing-code/coding-style/#pre-commit-checks). * Add pre-commit config file to run flake8 and isort. * Add extra "common sense" hooks. * Run pre-commit on GitHub actions using the [official action](https://github.com/pre-commit/action/). This is a good way to get up-and-running but it would be better if we activated [pre-commit.ci](https://pre-commit.ci/), which is faster and will auto-update the hooks for us going forwards. * Remove `runtests.py` code for running linting tools. * Remove `runtests.py --fast` flag, since that would now just run `pytest -q`, which can be done with `runtests.py -q` instead. * Remove tox configuration and requirements files for linting. * Update the contributing guide to mention setting up pre-commit.
This commit is contained in:
parent
846fe70cff
commit
aa12a5f967
24
.github/workflows/pre-commit.yml
vendored
Normal file
24
.github/workflows/pre-commit.yml
vendored
Normal file
|
@ -0,0 +1,24 @@
|
|||
name: pre-commit
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
pre-commit:
|
||||
runs-on: ubuntu-20.04
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: 3.9
|
||||
|
||||
- uses: pre-commit/action@v2.0.0
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -15,6 +15,7 @@
|
|||
MANIFEST
|
||||
coverage.*
|
||||
|
||||
!.github
|
||||
!.gitignore
|
||||
!.pre-commit-config.yaml
|
||||
!.travis.yml
|
||||
!.isort.cfg
|
||||
|
|
20
.pre-commit-config.yaml
Normal file
20
.pre-commit-config.yaml
Normal file
|
@ -0,0 +1,20 @@
|
|||
repos:
|
||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||
rev: v3.4.0
|
||||
hooks:
|
||||
- id: check-added-large-files
|
||||
- id: check-case-conflict
|
||||
- id: check-json
|
||||
- id: check-merge-conflict
|
||||
- id: check-symlinks
|
||||
- id: check-toml
|
||||
- repo: https://github.com/pycqa/isort
|
||||
rev: 5.8.0
|
||||
hooks:
|
||||
- id: isort
|
||||
- repo: https://gitlab.com/pycqa/flake8
|
||||
rev: 3.9.0
|
||||
hooks:
|
||||
- id: flake8
|
||||
additional_dependencies:
|
||||
- flake8-tidy-imports
|
|
@ -27,7 +27,6 @@ matrix:
|
|||
- { python: "3.9", env: DJANGO=main }
|
||||
|
||||
- { python: "3.8", env: TOXENV=base }
|
||||
- { python: "3.8", env: TOXENV=lint }
|
||||
- { python: "3.8", env: TOXENV=docs }
|
||||
|
||||
- python: "3.8"
|
||||
|
|
|
@ -54,11 +54,19 @@ To start developing on Django REST framework, first create a Fork from the
|
|||
Then clone your fork. The clone command will look like this, with your GitHub
|
||||
username instead of YOUR-USERNAME:
|
||||
|
||||
git clone https://github.com/YOUR-USERNAME/Spoon-Knife
|
||||
git clone https://github.com/YOUR-USERNAME/django-rest-framework
|
||||
|
||||
See GitHub's [_Fork a Repo_][how-to-fork] Guide for more help.
|
||||
|
||||
Changes should broadly follow the [PEP 8][pep-8] style conventions, and we recommend you set up your editor to automatically indicate non-conforming styles.
|
||||
You can check your contributions against these conventions each time you commit using the [pre-commit](https://pre-commit.com/) hooks, which we also run on CI.
|
||||
To set them up, first ensure you have the pre-commit tool installed, for example:
|
||||
|
||||
python -m pip install pre-commit
|
||||
|
||||
Then run:
|
||||
|
||||
pre-commit install
|
||||
|
||||
## Testing
|
||||
|
||||
|
@ -79,18 +87,6 @@ Run using a more concise output style.
|
|||
|
||||
./runtests.py -q
|
||||
|
||||
Run the tests using a more concise output style, no coverage, no flake8.
|
||||
|
||||
./runtests.py --fast
|
||||
|
||||
Don't run the flake8 code linting.
|
||||
|
||||
./runtests.py --nolint
|
||||
|
||||
Only run the flake8 code linting, don't run the tests.
|
||||
|
||||
./runtests.py --lintonly
|
||||
|
||||
Run the tests for a given test case.
|
||||
|
||||
./runtests.py MyTestCase
|
||||
|
|
|
@ -9,5 +9,4 @@
|
|||
-r requirements/requirements-optionals.txt
|
||||
-r requirements/requirements-testing.txt
|
||||
-r requirements/requirements-documentation.txt
|
||||
-r requirements/requirements-codestyle.txt
|
||||
-r requirements/requirements-packaging.txt
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
# PEP8 code linting, which we run on all commits.
|
||||
flake8>=3.8.4,<3.9
|
||||
flake8-tidy-imports>=4.1.0,<4.2
|
||||
|
||||
# Sort and lint imports
|
||||
isort>=5.6.2,<6.0
|
70
runtests.py
70
runtests.py
|
@ -1,42 +1,8 @@
|
|||
#! /usr/bin/env python3
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
import pytest
|
||||
|
||||
PYTEST_ARGS = {
|
||||
'default': [],
|
||||
'fast': ['-q'],
|
||||
}
|
||||
|
||||
FLAKE8_ARGS = ['rest_framework', 'tests']
|
||||
|
||||
ISORT_ARGS = ['--check-only', '--diff', 'rest_framework', 'tests']
|
||||
|
||||
|
||||
def exit_on_failure(ret, message=None):
|
||||
if ret:
|
||||
sys.exit(ret)
|
||||
|
||||
|
||||
def flake8_main(args):
|
||||
print('Running flake8 code linting')
|
||||
ret = subprocess.call(['flake8'] + args)
|
||||
print('flake8 failed' if ret else 'flake8 passed')
|
||||
return ret
|
||||
|
||||
|
||||
def isort_main(args):
|
||||
print('Running isort code checking')
|
||||
ret = subprocess.call(['isort'] + args)
|
||||
|
||||
if ret:
|
||||
print('isort failed: Some modules have incorrectly ordered imports. Fix by running `isort --recursive .`')
|
||||
else:
|
||||
print('isort passed')
|
||||
|
||||
return ret
|
||||
|
||||
|
||||
def split_class_and_function(string):
|
||||
class_string, function_string = string.split('.', 1)
|
||||
|
@ -54,31 +20,6 @@ def is_class(string):
|
|||
|
||||
|
||||
if __name__ == "__main__":
|
||||
try:
|
||||
sys.argv.remove('--nolint')
|
||||
except ValueError:
|
||||
run_flake8 = True
|
||||
run_isort = True
|
||||
else:
|
||||
run_flake8 = False
|
||||
run_isort = False
|
||||
|
||||
try:
|
||||
sys.argv.remove('--lintonly')
|
||||
except ValueError:
|
||||
run_tests = True
|
||||
else:
|
||||
run_tests = False
|
||||
|
||||
try:
|
||||
sys.argv.remove('--fast')
|
||||
except ValueError:
|
||||
style = 'default'
|
||||
else:
|
||||
style = 'fast'
|
||||
run_flake8 = False
|
||||
run_isort = False
|
||||
|
||||
if len(sys.argv) > 1:
|
||||
pytest_args = sys.argv[1:]
|
||||
first_arg = pytest_args[0]
|
||||
|
@ -104,14 +45,5 @@ if __name__ == "__main__":
|
|||
# `runtests.py TestCase [flags]`
|
||||
# `runtests.py test_function [flags]`
|
||||
pytest_args = ['tests', '-k', pytest_args[0]] + pytest_args[1:]
|
||||
else:
|
||||
pytest_args = PYTEST_ARGS[style]
|
||||
|
||||
if run_tests:
|
||||
exit_on_failure(pytest.main(pytest_args))
|
||||
|
||||
if run_flake8:
|
||||
exit_on_failure(flake8_main(FLAKE8_ARGS))
|
||||
|
||||
if run_isort:
|
||||
exit_on_failure(isort_main(ISORT_ARGS))
|
||||
sys.exit(pytest.main(pytest_args))
|
||||
|
|
12
tox.ini
12
tox.ini
|
@ -5,7 +5,7 @@ envlist =
|
|||
{py36,py37,py38,py39}-django31,
|
||||
{py36,py37,py38,py39}-django32,
|
||||
{py38,py39}-djangomain,
|
||||
base,dist,lint,docs,
|
||||
base,dist,docs,
|
||||
|
||||
[travis:env]
|
||||
DJANGO =
|
||||
|
@ -16,7 +16,7 @@ DJANGO =
|
|||
main: djangomain
|
||||
|
||||
[testenv]
|
||||
commands = python -W error::DeprecationWarning -W error::PendingDeprecationWarning runtests.py --fast --coverage {posargs}
|
||||
commands = python -W error::DeprecationWarning -W error::PendingDeprecationWarning runtests.py --coverage {posargs}
|
||||
envdir = {toxworkdir}/venvs/{envname}
|
||||
setenv =
|
||||
PYTHONDONTWRITEBYTECODE=1
|
||||
|
@ -37,18 +37,12 @@ deps =
|
|||
-rrequirements/requirements-testing.txt
|
||||
|
||||
[testenv:dist]
|
||||
commands = ./runtests.py --fast --no-pkgroot --staticfiles {posargs}
|
||||
commands = ./runtests.py --no-pkgroot --staticfiles {posargs}
|
||||
deps =
|
||||
django
|
||||
-rrequirements/requirements-testing.txt
|
||||
-rrequirements/requirements-optionals.txt
|
||||
|
||||
[testenv:lint]
|
||||
commands = ./runtests.py --lintonly
|
||||
deps =
|
||||
-rrequirements/requirements-codestyle.txt
|
||||
-rrequirements/requirements-testing.txt
|
||||
|
||||
[testenv:docs]
|
||||
skip_install = true
|
||||
commands = mkdocs build
|
||||
|
|
Loading…
Reference in New Issue
Block a user