Skip to content

Commit ebc67dd

Browse files
authored
Merge pull request #347 from NLeSC/336-use-ruff-instead-of-prospector-and-isort
use ruff instead of prospector and isort (Refs #336)
2 parents a56c6c7 + e3d1275 commit ebc67dd

15 files changed

Lines changed: 125 additions & 100 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
### Changed
1313

14+
* Moved from prospector to ruff [#336](https://github.com/NLeSC/python-template/issues/336)
1415
* Renamed `project_name` to `directory_name` in cookiecutter questionnaire
1516
* Initial linting is error free [#227](https://github.com/NLeSC/python-template/issues/227)
1617
* Consolidated test/lint/build/docs into single matrix workflow [#270](https://github.com/NLeSC/python-template/issues/276)

README.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ an empty Python package. Features include:
1111
- [Python static setup configuration]({{cookiecutter.directory_name}}/setup.cfg),
1212
- Open source software license,
1313
- Continuous integration with [GitHub action workflows]({{cookiecutter.directory_name}}/.github/workflows) for building, testing, link checking and linting,
14-
- Code style checking with [prospector](https://pypi.org/project/prospector/),
14+
- Code style checking with [ruff](https://beta.ruff.rs/),
1515
- [Editorconfig]({{cookiecutter.directory_name}}/.editorconfig),
1616
- Usage and contribution documents:
1717
- [README.md]({{cookiecutter.directory_name}}/README.md) for package users,
@@ -131,7 +131,6 @@ my-python-project/
131131
├── next_steps.md
132132
├── NOTICE
133133
├── project_setup.md
134-
├── .prospector.yml
135134
├── .pylintrc
136135
├── pyproject.toml
137136
├── README.dev.md

tests/test_project.py

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import os
22
import subprocess
3+
import sys
34
from sys import platform
45
from typing import Sequence
56

@@ -107,6 +108,8 @@ def test_generate_api_docs(baked_with_development_dependencies, project_env_bin_
107108
assert (project_dir / 'docs' / '_build' / 'html' / 'index.html').exists()
108109

109110

111+
@pytest.mark.skipif(sys.version_info < (3, 9), reason=
112+
"requires python 3.9 or higher, see https://github.com/NLeSC/python-template/pull/347#issuecomment-1710684574")
110113
def test_coverage_api_docs(baked_with_development_dependencies, project_env_bin_dir):
111114
project_dir = baked_with_development_dependencies
112115
bin_dir = project_env_bin_dir
@@ -116,9 +119,28 @@ def test_coverage_api_docs(baked_with_development_dependencies, project_env_bin_
116119
assert 'build succeeded' in result.stdout
117120
coverage_file = project_dir / 'docs' / '_build' / 'coverage' / 'python.txt'
118121
coverage_file_lines = coverage_file.read_text('utf8').splitlines()
119-
expected = ['Undocumented Python objects',
120-
'===========================']
121-
assert coverage_file_lines == expected
122+
# Coverage file lines should look globally like:
123+
# ['Undocumented Python objects',
124+
# '===========================',
125+
# '',
126+
# 'Statistics',
127+
# '----------',
128+
# '',
129+
# '+-----------------------------+----------+--------------+',
130+
# '| Module | Coverage | Undocumented |',
131+
# '+=============================+==========+==============+',
132+
# '| my_python_package | 100.00% | 0 |',
133+
# '+-----------------------------+----------+--------------+',
134+
# '| my_python_package.my_module | 100.00% | 0 |',
135+
# '+-----------------------------+----------+--------------+',
136+
# '| TOTAL | 100.00% | 0 |',
137+
# '+-----------------------------+----------+--------------+',
138+
# ''
139+
# ]
140+
# The package coverage lines change order between runs, so we test for each data row individually:
141+
assert '| my_python_package | 100.00% | 0 |' in coverage_file_lines
142+
assert '| my_python_package.my_module | 100.00% | 0 |' in coverage_file_lines
143+
assert '| TOTAL | 100.00% | 0 |' in coverage_file_lines
122144

123145

124146
def test_doctest_api_docs(baked_with_development_dependencies, project_env_bin_dir):
@@ -131,20 +153,11 @@ def test_doctest_api_docs(baked_with_development_dependencies, project_env_bin_d
131153
assert (project_dir / 'docs' / '_build' / 'doctest' / 'output.txt').exists()
132154

133155

134-
def test_prospector(baked_with_development_dependencies, project_env_bin_dir):
156+
def test_ruff_check(baked_with_development_dependencies, project_env_bin_dir):
135157
project_dir = baked_with_development_dependencies
136158
bin_dir = project_env_bin_dir
137159

138-
result = run([f'{bin_dir}prospector'], project_dir)
139-
assert result.returncode == 0
140-
assert 'Messages Found: 0' in result.stdout
141-
142-
143-
def test_isort_check(baked_with_development_dependencies, project_env_bin_dir):
144-
project_dir = baked_with_development_dependencies
145-
bin_dir = project_env_bin_dir
146-
147-
result = run([f'{bin_dir}isort', '--check-only', 'my_python_package'], project_dir)
160+
result = run([f'{bin_dir}ruff', '.'], project_dir)
148161
assert result.returncode == 0
149162
assert '' in result.stdout
150163

{{cookiecutter.directory_name}}/.githooks/pre-commit

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,29 +3,17 @@
33
echo "Script $0 triggered ..."
44

55
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
6-
echo "Starting prospector analysis using configuration from .prospector.yml..."
6+
echo "Starting ruff analysis..."
77

8-
# quietly run prospector
9-
prospector 1>/dev/null
8+
# quietly run ruff
9+
ruff . --fix
1010

1111
# use return code to abort commit if necessary
1212
if [ $? != "0" ]; then
13-
echo "Commit aborted. Run 'prospector' to see the errors."
13+
echo "Commit aborted. Fix linter issues found by ruff before committing."
1414
exit 1
1515
fi
1616

1717
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
18-
echo "Starting isort analysis using configuration from setup.cfg..."
19-
20-
# recursively run isort on {{ cookiecutter.package_name }}/ directory, don't try to automatically fix anything
21-
isort --recursive --check-only {{ cookiecutter.package_name }}
22-
23-
if [ $? != "0" ]; then
24-
echo "Commit aborted."
25-
echo " Run 'isort --check-only --diff {{ cookiecutter.package_name }}' to see what's wrong."
26-
echo " Run 'isort {{ cookiecutter.package_name }}' to let isort fix problems automatically."
27-
exit 1
28-
fi
29-
3018
echo "Pre-commit checks completed successfully."
3119
exit 0

{{cookiecutter.directory_name}}/.github/next_steps/05_linting.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ Your repository has a [workflow]({{ cookiecutter.repository }}/blob/main/.github
77
Linter workflow may fail if `description` or `keywords` field in [setup.cfg]({{ cookiecutter.repository }}/blob/main/setup.cfg) is empty. Please update these fields. To validate your changes run:
88

99
```shell
10-
prospector
10+
ruff .
1111
```
1212

1313
Enabling [githook](https://git-scm.com/docs/githooks) will automatically lint your code in every commit. You can enable it by running the command below.

{{cookiecutter.directory_name}}/.github/workflows/build.yml

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,5 @@ jobs:
5858
run: |
5959
python -m pip install --upgrade pip setuptools
6060
python -m pip install .[dev,publishing]
61-
- name: Check style against standards using prospector
62-
run: prospector
63-
- name: Check import order
64-
run: isort --check-only {{ cookiecutter.package_name }} --diff
61+
- name: Check style against standards using ruff
62+
run: ruff .

{{cookiecutter.directory_name}}/.github/workflows/sonarcloud.yml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,6 @@ jobs:
2929
python --version
3030
- name: Install dependencies
3131
run: python -m pip install .[dev]
32-
- name: Check style against standards using prospector
33-
run: prospector --zero-exit --output-format grouped --output-format pylint:pylint-report.txt
3432
- name: Run unit tests with coverage
3533
run: python -m pytest --cov --cov-report term --cov-report xml --junitxml=xunit-result.xml tests/
3634
- name: Correct coverage paths

{{cookiecutter.directory_name}}/.prospector.yml

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

{{cookiecutter.directory_name}}/README.dev.md

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -62,28 +62,20 @@ coverage report
6262

6363
## Running linters locally
6464

65-
For linting we will use [prospector](https://pypi.org/project/prospector/) and to sort imports we will use
66-
[isort](https://pycqa.github.io/isort/). Running the linters requires an activated virtual environment with the
67-
development tools installed.
65+
For linting and sorting imports we will use [ruff](https://beta.ruff.rs/docs/). Running the linters requires an
66+
activated virtual environment with the development tools installed.
6867

6968
```shell
7069
# linter
71-
prospector
70+
ruff .
7271

73-
# recursively check import style for the {{ cookiecutter.package_name }} module only
74-
isort --check-only {{ cookiecutter.package_name }}
75-
76-
# recursively check import style for the {{ cookiecutter.package_name }} module only and show
77-
# any proposed changes as a diff
78-
isort --check-only --diff {{ cookiecutter.package_name }}
79-
80-
# recursively fix import style for the {{ cookiecutter.package_name }} module only
81-
isort {{ cookiecutter.package_name }}
72+
# linter with automatic fixing
73+
ruff . --fix
8274
```
8375

8476
To fix readability of your code style you can use [yapf](https://github.com/google/yapf).
8577

86-
You can enable automatic linting with `prospector` and `isort` on commit by enabling the git hook from `.githooks/pre-commit`, like so:
78+
You can enable automatic linting with `ruff` on commit by enabling the git hook from `.githooks/pre-commit`, like so:
8779

8880
```shell
8981
git config --local core.hooksPath .githooks

{{cookiecutter.directory_name}}/pyproject.toml

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,78 @@ skip_missing_interpreters = true
1919
commands = pytest
2020
extras = dev
2121
"""
22+
23+
[tool.ruff]
24+
# Enable Pyflakes `E` and `F` codes by default.
25+
select = [
26+
"F", # Pyflakes
27+
"E", # pycodestyle (error)
28+
"W", # pycodestyle (warning)
29+
# "C90", # mccabe
30+
"I", # isort
31+
"D", # pydocstyle
32+
# "PL", # Pylint
33+
# "PLC", # Convention
34+
# "PLE", # Error
35+
# "PLR", # Refactor
36+
# "PLW", # Warning
37+
38+
]
39+
ignore = [
40+
'D100', # Missing module docstring
41+
'D104', # Missing public package docstring
42+
# The following list excludes rules irrelevant to the Google style
43+
'D203',
44+
'D204',
45+
'D213',
46+
'D215',
47+
'D400',
48+
'D401',
49+
'D404',
50+
'D406',
51+
'D407',
52+
'D408',
53+
'D409',
54+
'D413',
55+
]
56+
57+
# Allow autofix for all enabled rules (when `--fix`) is provided.
58+
fixable = ["A", "B", "C", "D", "E", "F", "I"]
59+
unfixable = []
60+
61+
exclude = [
62+
".bzr",
63+
".direnv",
64+
".eggs",
65+
".git",
66+
".hg",
67+
".mypy_cache",
68+
".nox",
69+
".pants.d",
70+
".ruff_cache",
71+
".svn",
72+
".tox",
73+
".venv",
74+
"__pypackages__",
75+
"_build",
76+
"buck-out",
77+
"build",
78+
"dist",
79+
"node_modules",
80+
"venv",
81+
".venv",
82+
"scripts",
83+
]
84+
per-file-ignores = {}
85+
86+
87+
# Allow unused variables when underscore-prefixed.
88+
dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$"
89+
90+
target-version = "py39"
91+
line-length = 120
92+
93+
[tool.ruff.isort]
94+
known-first-party = ["{{ cookiecutter.package_name }}"]
95+
force-single-line = true
96+
no-lines-before = ["future","standard-library","third-party","first-party","local-folder"]

0 commit comments

Comments
 (0)