mirror of
				https://github.com/encode/django-rest-framework.git
				synced 2025-10-31 07:57:55 +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 | MANIFEST | ||||||
| coverage.* | coverage.* | ||||||
| 
 | 
 | ||||||
|  | !.github | ||||||
| !.gitignore | !.gitignore | ||||||
|  | !.pre-commit-config.yaml | ||||||
| !.travis.yml | !.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.9", env: DJANGO=main } | ||||||
| 
 | 
 | ||||||
|       - { python: "3.8", env: TOXENV=base } |       - { python: "3.8", env: TOXENV=base } | ||||||
|       - { python: "3.8", env: TOXENV=lint } |  | ||||||
|       - { python: "3.8", env: TOXENV=docs } |       - { python: "3.8", env: TOXENV=docs } | ||||||
| 
 | 
 | ||||||
|       - python: "3.8" |       - 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 | Then clone your fork. The clone command will look like this, with your GitHub | ||||||
| username instead of YOUR-USERNAME: | 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. | 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. | 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 | ## Testing | ||||||
| 
 | 
 | ||||||
|  | @ -79,18 +87,6 @@ Run using a more concise output style. | ||||||
| 
 | 
 | ||||||
|     ./runtests.py -q |     ./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. | Run the tests for a given test case. | ||||||
| 
 | 
 | ||||||
|     ./runtests.py MyTestCase |     ./runtests.py MyTestCase | ||||||
|  |  | ||||||
|  | @ -9,5 +9,4 @@ | ||||||
| -r requirements/requirements-optionals.txt | -r requirements/requirements-optionals.txt | ||||||
| -r requirements/requirements-testing.txt | -r requirements/requirements-testing.txt | ||||||
| -r requirements/requirements-documentation.txt | -r requirements/requirements-documentation.txt | ||||||
| -r requirements/requirements-codestyle.txt |  | ||||||
| -r requirements/requirements-packaging.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 | #! /usr/bin/env python3 | ||||||
| import subprocess |  | ||||||
| import sys | import sys | ||||||
| 
 | 
 | ||||||
| import pytest | 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): | def split_class_and_function(string): | ||||||
|     class_string, function_string = string.split('.', 1) |     class_string, function_string = string.split('.', 1) | ||||||
|  | @ -54,31 +20,6 @@ def is_class(string): | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| if __name__ == "__main__": | 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: |     if len(sys.argv) > 1: | ||||||
|         pytest_args = sys.argv[1:] |         pytest_args = sys.argv[1:] | ||||||
|         first_arg = pytest_args[0] |         first_arg = pytest_args[0] | ||||||
|  | @ -104,14 +45,5 @@ if __name__ == "__main__": | ||||||
|             # `runtests.py TestCase [flags]` |             # `runtests.py TestCase [flags]` | ||||||
|             # `runtests.py test_function [flags]` |             # `runtests.py test_function [flags]` | ||||||
|             pytest_args = ['tests', '-k', pytest_args[0]] + pytest_args[1:] |             pytest_args = ['tests', '-k', pytest_args[0]] + pytest_args[1:] | ||||||
|     else: |  | ||||||
|         pytest_args = PYTEST_ARGS[style] |  | ||||||
| 
 | 
 | ||||||
|     if run_tests: |     sys.exit(pytest.main(pytest_args)) | ||||||
|         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)) |  | ||||||
|  |  | ||||||
							
								
								
									
										12
									
								
								tox.ini
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								tox.ini
									
									
									
									
									
								
							|  | @ -5,7 +5,7 @@ envlist = | ||||||
|        {py36,py37,py38,py39}-django31, |        {py36,py37,py38,py39}-django31, | ||||||
|        {py36,py37,py38,py39}-django32, |        {py36,py37,py38,py39}-django32, | ||||||
|        {py38,py39}-djangomain, |        {py38,py39}-djangomain, | ||||||
|        base,dist,lint,docs, |        base,dist,docs, | ||||||
| 
 | 
 | ||||||
| [travis:env] | [travis:env] | ||||||
| DJANGO = | DJANGO = | ||||||
|  | @ -16,7 +16,7 @@ DJANGO = | ||||||
|     main: djangomain |     main: djangomain | ||||||
| 
 | 
 | ||||||
| [testenv] | [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} | envdir = {toxworkdir}/venvs/{envname} | ||||||
| setenv = | setenv = | ||||||
|        PYTHONDONTWRITEBYTECODE=1 |        PYTHONDONTWRITEBYTECODE=1 | ||||||
|  | @ -37,18 +37,12 @@ deps = | ||||||
|         -rrequirements/requirements-testing.txt |         -rrequirements/requirements-testing.txt | ||||||
| 
 | 
 | ||||||
| [testenv:dist] | [testenv:dist] | ||||||
| commands = ./runtests.py --fast --no-pkgroot --staticfiles {posargs} | commands = ./runtests.py --no-pkgroot --staticfiles {posargs} | ||||||
| deps = | deps = | ||||||
|         django |         django | ||||||
|         -rrequirements/requirements-testing.txt |         -rrequirements/requirements-testing.txt | ||||||
|         -rrequirements/requirements-optionals.txt |         -rrequirements/requirements-optionals.txt | ||||||
| 
 | 
 | ||||||
| [testenv:lint] |  | ||||||
| commands = ./runtests.py --lintonly |  | ||||||
| deps = |  | ||||||
|         -rrequirements/requirements-codestyle.txt |  | ||||||
|         -rrequirements/requirements-testing.txt |  | ||||||
| 
 |  | ||||||
| [testenv:docs] | [testenv:docs] | ||||||
| skip_install = true | skip_install = true | ||||||
| commands = mkdocs build | commands = mkdocs build | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user