Skip to content

Commit aa12a5f

Browse files
authored
Lint with pre-commit (#7900)
Following [my comment here](#7589 (comment)) 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.
1 parent 846fe70 commit aa12a5f

File tree

9 files changed

+59
-100
lines changed

9 files changed

+59
-100
lines changed

.github/workflows/pre-commit.yml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
name: pre-commit
2+
3+
on:
4+
push:
5+
branches:
6+
- master
7+
pull_request:
8+
9+
jobs:
10+
pre-commit:
11+
runs-on: ubuntu-20.04
12+
13+
steps:
14+
- uses: actions/checkout@v2
15+
with:
16+
fetch-depth: 0
17+
18+
- uses: actions/setup-python@v2
19+
with:
20+
python-version: 3.9
21+
22+
- uses: pre-commit/[email protected]
23+
with:
24+
token: ${{ secrets.GITHUB_TOKEN }}

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
MANIFEST
1616
coverage.*
1717

18+
!.github
1819
!.gitignore
20+
!.pre-commit-config.yaml
1921
!.travis.yml
20-
!.isort.cfg

.pre-commit-config.yaml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
repos:
2+
- repo: https://github.com/pre-commit/pre-commit-hooks
3+
rev: v3.4.0
4+
hooks:
5+
- id: check-added-large-files
6+
- id: check-case-conflict
7+
- id: check-json
8+
- id: check-merge-conflict
9+
- id: check-symlinks
10+
- id: check-toml
11+
- repo: https://github.com/pycqa/isort
12+
rev: 5.8.0
13+
hooks:
14+
- id: isort
15+
- repo: https://gitlab.com/pycqa/flake8
16+
rev: 3.9.0
17+
hooks:
18+
- id: flake8
19+
additional_dependencies:
20+
- flake8-tidy-imports

.travis.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ matrix:
2727
- { python: "3.9", env: DJANGO=main }
2828

2929
- { python: "3.8", env: TOXENV=base }
30-
- { python: "3.8", env: TOXENV=lint }
3130
- { python: "3.8", env: TOXENV=docs }
3231

3332
- python: "3.8"

docs/community/contributing.md

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -54,11 +54,19 @@ To start developing on Django REST framework, first create a Fork from the
5454
Then clone your fork. The clone command will look like this, with your GitHub
5555
username instead of YOUR-USERNAME:
5656

57-
git clone https://github.com/YOUR-USERNAME/Spoon-Knife
57+
git clone https://github.com/YOUR-USERNAME/django-rest-framework
5858

5959
See GitHub's [_Fork a Repo_][how-to-fork] Guide for more help.
6060

6161
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.
62+
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.
63+
To set them up, first ensure you have the pre-commit tool installed, for example:
64+
65+
python -m pip install pre-commit
66+
67+
Then run:
68+
69+
pre-commit install
6270

6371
## Testing
6472

@@ -79,18 +87,6 @@ Run using a more concise output style.
7987

8088
./runtests.py -q
8189

82-
Run the tests using a more concise output style, no coverage, no flake8.
83-
84-
./runtests.py --fast
85-
86-
Don't run the flake8 code linting.
87-
88-
./runtests.py --nolint
89-
90-
Only run the flake8 code linting, don't run the tests.
91-
92-
./runtests.py --lintonly
93-
9490
Run the tests for a given test case.
9591

9692
./runtests.py MyTestCase

requirements.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,4 @@
99
-r requirements/requirements-optionals.txt
1010
-r requirements/requirements-testing.txt
1111
-r requirements/requirements-documentation.txt
12-
-r requirements/requirements-codestyle.txt
1312
-r requirements/requirements-packaging.txt

requirements/requirements-codestyle.txt

Lines changed: 0 additions & 6 deletions
This file was deleted.

runtests.py

Lines changed: 1 addition & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,8 @@
11
#! /usr/bin/env python3
2-
import subprocess
32
import sys
43

54
import pytest
65

7-
PYTEST_ARGS = {
8-
'default': [],
9-
'fast': ['-q'],
10-
}
11-
12-
FLAKE8_ARGS = ['rest_framework', 'tests']
13-
14-
ISORT_ARGS = ['--check-only', '--diff', 'rest_framework', 'tests']
15-
16-
17-
def exit_on_failure(ret, message=None):
18-
if ret:
19-
sys.exit(ret)
20-
21-
22-
def flake8_main(args):
23-
print('Running flake8 code linting')
24-
ret = subprocess.call(['flake8'] + args)
25-
print('flake8 failed' if ret else 'flake8 passed')
26-
return ret
27-
28-
29-
def isort_main(args):
30-
print('Running isort code checking')
31-
ret = subprocess.call(['isort'] + args)
32-
33-
if ret:
34-
print('isort failed: Some modules have incorrectly ordered imports. Fix by running `isort --recursive .`')
35-
else:
36-
print('isort passed')
37-
38-
return ret
39-
406

417
def split_class_and_function(string):
428
class_string, function_string = string.split('.', 1)
@@ -54,31 +20,6 @@ def is_class(string):
5420

5521

5622
if __name__ == "__main__":
57-
try:
58-
sys.argv.remove('--nolint')
59-
except ValueError:
60-
run_flake8 = True
61-
run_isort = True
62-
else:
63-
run_flake8 = False
64-
run_isort = False
65-
66-
try:
67-
sys.argv.remove('--lintonly')
68-
except ValueError:
69-
run_tests = True
70-
else:
71-
run_tests = False
72-
73-
try:
74-
sys.argv.remove('--fast')
75-
except ValueError:
76-
style = 'default'
77-
else:
78-
style = 'fast'
79-
run_flake8 = False
80-
run_isort = False
81-
8223
if len(sys.argv) > 1:
8324
pytest_args = sys.argv[1:]
8425
first_arg = pytest_args[0]
@@ -104,14 +45,5 @@ def is_class(string):
10445
# `runtests.py TestCase [flags]`
10546
# `runtests.py test_function [flags]`
10647
pytest_args = ['tests', '-k', pytest_args[0]] + pytest_args[1:]
107-
else:
108-
pytest_args = PYTEST_ARGS[style]
109-
110-
if run_tests:
111-
exit_on_failure(pytest.main(pytest_args))
112-
113-
if run_flake8:
114-
exit_on_failure(flake8_main(FLAKE8_ARGS))
11548

116-
if run_isort:
117-
exit_on_failure(isort_main(ISORT_ARGS))
49+
sys.exit(pytest.main(pytest_args))

tox.ini

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ envlist =
55
{py36,py37,py38,py39}-django31,
66
{py36,py37,py38,py39}-django32,
77
{py38,py39}-djangomain,
8-
base,dist,lint,docs,
8+
base,dist,docs,
99

1010
[travis:env]
1111
DJANGO =
@@ -16,7 +16,7 @@ DJANGO =
1616
main: djangomain
1717

1818
[testenv]
19-
commands = python -W error::DeprecationWarning -W error::PendingDeprecationWarning runtests.py --fast --coverage {posargs}
19+
commands = python -W error::DeprecationWarning -W error::PendingDeprecationWarning runtests.py --coverage {posargs}
2020
envdir = {toxworkdir}/venvs/{envname}
2121
setenv =
2222
PYTHONDONTWRITEBYTECODE=1
@@ -37,18 +37,12 @@ deps =
3737
-rrequirements/requirements-testing.txt
3838

3939
[testenv:dist]
40-
commands = ./runtests.py --fast --no-pkgroot --staticfiles {posargs}
40+
commands = ./runtests.py --no-pkgroot --staticfiles {posargs}
4141
deps =
4242
django
4343
-rrequirements/requirements-testing.txt
4444
-rrequirements/requirements-optionals.txt
4545

46-
[testenv:lint]
47-
commands = ./runtests.py --lintonly
48-
deps =
49-
-rrequirements/requirements-codestyle.txt
50-
-rrequirements/requirements-testing.txt
51-
5246
[testenv:docs]
5347
skip_install = true
5448
commands = mkdocs build

0 commit comments

Comments
 (0)