Skip to content

Commit e03df78

Browse files
authored
feat: allow and mention ruff-formatter (#299)
* feat: allow and mention ruff-formatter Signed-off-by: Henry Schreiner <[email protected]> * docs: 'exclude' is a little different Signed-off-by: Henry Schreiner <[email protected]> --------- Signed-off-by: Henry Schreiner <[email protected]>
1 parent 2d64048 commit e03df78

File tree

10 files changed

+139
-38
lines changed

10 files changed

+139
-38
lines changed

.pre-commit-config.yaml

Lines changed: 13 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -6,23 +6,6 @@ ci:
66
exclude: "^({{cookiecutter\\.project_name}}|hooks/pre_gen_project.py$)"
77

88
repos:
9-
- repo: https://github.com/psf/black-pre-commit-mirror
10-
rev: "23.10.0"
11-
hooks:
12-
- id: black-jupyter
13-
14-
- repo: https://github.com/adamchainz/blacken-docs
15-
rev: "1.16.0"
16-
hooks:
17-
- id: blacken-docs
18-
additional_dependencies: [black==23.10.0]
19-
20-
- repo: https://github.com/astral-sh/ruff-pre-commit
21-
rev: "v0.1.1"
22-
hooks:
23-
- id: ruff
24-
args: ["--fix", "--show-fixes"]
25-
269
- repo: https://github.com/pre-commit/pre-commit-hooks
2710
rev: "v4.5.0"
2811
hooks:
@@ -39,6 +22,19 @@ repos:
3922
- id: requirements-txt-fixer
4023
- id: trailing-whitespace
4124

25+
- repo: https://github.com/adamchainz/blacken-docs
26+
rev: "1.16.0"
27+
hooks:
28+
- id: blacken-docs
29+
additional_dependencies: [black==23.*]
30+
31+
- repo: https://github.com/astral-sh/ruff-pre-commit
32+
rev: "v0.1.3"
33+
hooks:
34+
- id: ruff
35+
args: ["--fix", "--show-fixes"]
36+
- id: ruff-format
37+
4238
- repo: https://github.com/pre-commit/pygrep-hooks
4339
rev: "v1.10.0"
4440
hooks:

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -357,7 +357,7 @@ for family, grp in itertools.groupby(collected.checks.items(), key=lambda x: x[1
357357

358358
### Pre-commit
359359
- [`PC100`](https://learn.scientific-python.org/development/guides/style#PC100): Has pre-commit-hooks
360-
- [`PC110`](https://learn.scientific-python.org/development/guides/style#PC110): Uses black
360+
- [`PC110`](https://learn.scientific-python.org/development/guides/style#PC110): Uses black or ruff-format
361361
- [`PC111`](https://learn.scientific-python.org/development/guides/style#PC111): Uses blacken-docs
362362
- [`PC140`](https://learn.scientific-python.org/development/guides/style#PC140): Uses mypy
363363
- [`PC160`](https://learn.scientific-python.org/development/guides/style#PC160): Uses codespell

docs/pages/guides/style.md

Lines changed: 62 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ ci:
7979
autoupdate_commit_msg: "chore: update pre-commit hooks"
8080
```
8181

82-
## Black
82+
## Format
8383

8484
{% rr PC110 %} [Black](https://black.readthedocs.io/en/latest/) is a popular
8585
auto-formatter from the Python Software Foundation. One of the main features of
@@ -102,6 +102,8 @@ There are a _few_ options, mostly to enable/disable certain files, remove string
102102
normalization, and to change the line length, and those go in your
103103
`pyproject.toml` file.
104104

105+
{% tabs %} {% tab black Black %}
106+
105107
Here is the snippet to add Black to your `.pre-commit-config.yml`:
106108

107109
```yaml
@@ -124,6 +126,37 @@ Here is the snippet to add Black to your `.pre-commit-config.yml`:
124126

125127
{% enddetails %}
126128

129+
{% endtab %} {% tab ruff Ruff-format %}
130+
131+
Ruff, the powerful Rust-based linter, also has a formatter that is designed to
132+
look like Black, but run 30x faster. Here is the snippet to add Black to your
133+
`.pre-commit-config.yml` (combine with Ruff below):
134+
135+
```yaml
136+
- repo: https://github.com/astral-sh/ruff-pre-commit
137+
rev: "v0.1.3"
138+
hooks:
139+
# id: ruff would go here if using both
140+
- id: ruff-format
141+
```
142+
143+
{% details You can add a Ruff badge to your repo as well %}
144+
145+
[![Code style: Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/format.json))](https://github.com/astral-sh/ruff)
146+
147+
```md
148+
[![Code style: Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/format.json))](https://github.com/astral-sh/ruff)
149+
```
150+
151+
```rst
152+
.. image:: https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/format.json
153+
:target: https://github.com/astral-sh/ruff
154+
```
155+
156+
{% enddetails %}
157+
158+
{% endtab %} {% endtabs %}
159+
127160
In _very_ specific situations, you may want to retain special formatting. After
128161
carefully deciding that it is a special use case, you can use `# fmt: on` and
129162
`# fmt: off` around a code block to have it keep custom formatting. _Always_
@@ -179,15 +212,13 @@ src = ["src"]
179212
exclude = []
180213
181214
[tool.ruff.lint]
182-
select = [
183-
"E", "F", "W", # flake8
215+
extend-select = [
184216
"B", # flake8-bugbear
185217
"I", # isort
186218
"ARG", # flake8-unused-arguments
187219
"C4", # flake8-comprehensions
188220
"EM", # flake8-errmsg
189221
"ICN", # flake8-import-conventions
190-
"ISC", # flake8-implicit-str-concat
191222
"G", # flake8-logging-format
192223
"PGH", # pygrep-hooks
193224
"PIE", # flake8-pie
@@ -203,6 +234,8 @@ select = [
203234
"EXE", # flake8-executable
204235
"NPY", # NumPy specific rules
205236
"PD", # pandas-vet
237+
"FURB", # referb
238+
"PYI", # flake8-pyi
206239
]
207240
ignore = [
208241
"PLR", # Design related pylint codes
@@ -255,7 +288,8 @@ without this).
255288
Here are some good error codes to enable on most (but not all!) projects:
256289

257290
- `E`, `F`, `W`: These are the standard flake8 checks, classic checks that have
258-
stood the test of time.
291+
stood the test of time. Not required if you use `extend-select` (`W` not
292+
needed if you use a formatter)
259293
- `B`: This finds patterns that are very bug-prone. {% rr RF101 %}
260294
- `I`: This sorts your includes. There are multiple benefits, such as smaller
261295
diffs, fewer conflicts, a way to auto-inject `__future__` imports, and easier
@@ -270,7 +304,7 @@ Here are some good error codes to enable on most (but not all!) projects:
270304
error string directly in the exception you are throwing, producing a cleaner
271305
traceback without duplicating the error string.
272306
- `ISC`: Checks for implicit string concatenation, which can help catch mistakes
273-
with missing commas.
307+
with missing commas. (May collide with formatter)
274308
- `PGH`: Checks for patterns, such as type ignores or noqa's without a specific
275309
error code.
276310
- `PL`: A set of four code groups that cover some (200 or so out of 600 rules)
@@ -284,9 +318,28 @@ Here are some good error codes to enable on most (but not all!) projects:
284318
- `T20`: Disallow `print` in your code (built on the assumption that it's a
285319
common debugging tool).
286320
- `UP`: Upgrade old Python syntax to your `target-version`. {% rr RF103 %}
321+
- `FURB`: From the refurb tool, a collection of helpful cleanups.
322+
- `PYI`: Typing related checks
287323

288324
A few others small ones are included above, and there are even more available in
289-
Ruff.
325+
Ruff. You can use `ALL` to get them all, then ignore the ones you want to
326+
ignore. New checks go into `--preview` before being activated in a minor
327+
release.
328+
329+
{% details You can add a Ruff badge to your repo as well %}
330+
331+
[![Code style: Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json))](https://github.com/astral-sh/ruff)
332+
333+
```md
334+
[![Code style: Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json))](https://github.com/astral-sh/ruff)
335+
```
336+
337+
```rst
338+
.. image:: https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json
339+
:target: https://github.com/astral-sh/ruff
340+
```
341+
342+
{% enddetails %}
290343

291344
{% details Separate tools that Ruff replaces %}
292345

@@ -867,3 +920,5 @@ You also might like the following hook, which cleans Jupyter outputs:
867920
[schemastore]: https://schemastore.org
868921

869922
<!-- prettier-ignore-end -->
923+
924+
<script src="{% link assets/js/tabs.js %}"></script>

pyproject.toml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -138,15 +138,13 @@ src = ["src"]
138138
exclude = []
139139

140140
[tool.ruff.lint]
141-
select = [
142-
"E", "F", "W", # flake8
141+
extend-select = [
143142
"B", # flake8-bugbear
144143
"I", # isort
145144
"ARG", # flake8-unused-arguments
146145
"C4", # flake8-comprehensions
147146
"EM", # flake8-errmsg
148147
"ICN", # flake8-import-conventions
149-
"ISC", # flake8-implicit-str-concat
150148
"PGH", # pygrep-hooks
151149
"PIE", # flake8-pie
152150
"PL", # pylint

src/sp_repo_review/checks/general.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@ class General:
1212

1313

1414
class PY001(General):
15+
1516
"Has a pyproject.toml"
17+
1618
url = mk_url("packaging-simple")
1719

1820
@staticmethod
@@ -26,6 +28,7 @@ def check(package: Traversable) -> bool:
2628

2729
class PY002(General):
2830
"Has a README.(md|rst) file"
31+
2932
url = mk_url("packaging-simple")
3033

3134
@staticmethod
@@ -39,6 +42,7 @@ def check(root: Traversable) -> bool:
3942

4043
class PY003(General):
4144
"Has a LICENSE* file"
45+
4246
url = mk_url("packaging-simple")
4347

4448
@staticmethod
@@ -49,6 +53,7 @@ def check(package: Traversable) -> bool:
4953

5054
class PY004(General):
5155
"Has docs folder"
56+
5257
url = mk_url("packaging-simple")
5358

5459
@staticmethod
@@ -59,6 +64,7 @@ def check(package: Traversable) -> bool:
5964

6065
class PY005(General):
6166
"Has tests folder"
67+
6268
url = mk_url("packaging-simple")
6369

6470
@staticmethod
@@ -79,6 +85,7 @@ def check(package: Traversable) -> bool:
7985

8086
class PY006(General):
8187
"Has pre-commit config"
88+
8289
url = mk_url("style")
8390

8491
@staticmethod
@@ -89,6 +96,7 @@ def check(root: Traversable) -> bool:
8996

9097
class PY007(General):
9198
"Supports an easy task runner (nox or tox)"
99+
92100
url = mk_url("tasks")
93101

94102
@staticmethod

src/sp_repo_review/checks/github.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ class GitHub:
4040

4141
class GH100(GitHub):
4242
"Has GitHub Actions config"
43+
4344
url = mk_url("gha-basic")
4445

4546
@staticmethod
@@ -54,6 +55,7 @@ def check(workflows: dict[str, Any]) -> bool:
5455

5556
class GH101(GitHub):
5657
"Has nice names"
58+
5759
requires = {"GH100"}
5860
url = mk_url("gha-basic")
5961

@@ -68,6 +70,7 @@ def check(workflows: dict[str, Any]) -> bool:
6870

6971
class GH102(GitHub):
7072
"Auto-cancel on repeated PRs"
73+
7174
requires = {"GH100"}
7275
url = mk_url("gha-basic")
7376

@@ -87,6 +90,7 @@ def check(workflows: dict[str, Any]) -> bool:
8790

8891
class GH103(GitHub):
8992
"At least one workflow with manual dispatch trigger"
93+
9094
requires = {"GH100"}
9195
url = mk_url("gha-basic")
9296

@@ -105,6 +109,7 @@ def check(workflows: dict[str, Any]) -> bool:
105109

106110
class GH200(GitHub):
107111
"Maintained by Dependabot"
112+
108113
url = mk_url("gha-basic")
109114

110115
@staticmethod
@@ -128,6 +133,7 @@ def check(dependabot: dict[str, Any]) -> bool:
128133

129134
class GH210(GitHub):
130135
"Maintains the GitHub action versions with Dependabot"
136+
131137
requires = {"GH200"}
132138
url = mk_url("gha-basic")
133139

@@ -154,6 +160,7 @@ def check(dependabot: dict[str, Any]) -> bool:
154160

155161
class GH211(GitHub):
156162
"Do not pin core actions as major versions"
163+
157164
requires = {"GH200", "GH210"} # Currently listing both helps - TODO: remove GH200
158165
url = mk_url("gha-basic")
159166

src/sp_repo_review/checks/precommit.py

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,50 +41,71 @@ def check(cls, precommit: dict[str, Any]) -> bool | None | str:
4141

4242
class PC100(PreCommit):
4343
"Has pre-commit-hooks"
44+
4445
repo = "https://github.com/pre-commit/pre-commit-hooks"
4546

4647

4748
class PC110(PreCommit):
48-
"Uses black"
49+
"Uses black or ruff-format"
50+
4951
repo = "https://github.com/psf/black-pre-commit-mirror"
5052
renamed = "https://github.com/psf/black"
53+
alternate = "https://github.com/astral-sh/ruff-pre-commit"
54+
55+
@classmethod
56+
def check(cls, precommit: dict[str, Any]) -> bool | None | str:
57+
"Must have `{self.repo}` or `{self.alternate}` + `id: ruff-format` in `.pre-commit-config.yaml`"
58+
for repo in precommit.get("repos", {}):
59+
if repo.get("repo", "").lower() == cls.alternate and any(
60+
hook.get("id", "") == "ruff-format" for hook in repo.get("hooks", {})
61+
):
62+
return True
63+
64+
return super().check(precommit)
5165

5266

5367
class PC111(PreCommit):
5468
"Uses blacken-docs"
69+
5570
requires = {"PY006", "PC110"}
5671
repo = "https://github.com/adamchainz/blacken-docs"
5772
renamed = "https://github.com/asottile/blacken-docs"
5873

5974

6075
class PC190(PreCommit):
6176
"Uses Ruff"
77+
6278
repo = "https://github.com/astral-sh/ruff-pre-commit"
6379
renamed = "https://github.com/charliermarsh/ruff-pre-commit"
6480

6581

6682
class PC140(PreCommit):
6783
"Uses mypy"
84+
6885
repo = "https://github.com/pre-commit/mirrors-mypy"
6986

7087

7188
class PC160(PreCommit):
7289
"Uses codespell"
90+
7391
repo = "https://github.com/codespell-project/codespell"
7492

7593

7694
class PC170(PreCommit):
7795
"Uses PyGrep hooks (only needed if RST present)"
96+
7897
repo = "https://github.com/pre-commit/pygrep-hooks"
7998

8099

81100
class PC180(PreCommit):
82101
"Uses prettier"
102+
83103
repo = "https://github.com/pre-commit/mirrors-prettier"
84104

85105

86106
class PC191(PreCommit):
87107
"Ruff show fixes if fixes enabled"
108+
88109
requires = {"PC190"}
89110
repo = "https://github.com/astral-sh/ruff-pre-commit"
90111

0 commit comments

Comments
 (0)