Skip to content

Commit c2eaa5d

Browse files
committed
ci(pre-commit): remove the deprecated pyright files, and add the ver_sync hook
- remove the deprecated pyright config files: `.pre-commit-pyrightconfig.json` - add `ver_sync` local hook to auto synchronize versions for lint tools
1 parent 795436a commit c2eaa5d

File tree

4 files changed

+121
-25
lines changed

4 files changed

+121
-25
lines changed

.pre-commit-config.yaml

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,22 +25,18 @@ repos:
2525
rev: v0.1.1
2626
hooks:
2727
- id: ruff
28+
alias: ruff # NOTE: don't change this alias, it's used in `ver_sync.py`, keep consistent with `pyproject.toml`
2829
args: [--fix, --exit-non-zero-on-fix]
2930
- repo: https://github.com/psf/black-pre-commit-mirror
3031
rev: 23.10.0
3132
hooks:
3233
- id: black
33-
# # pyright will be performed by `hatch run lint`
34-
# # because pyright requires a actual testing environment with all dependencies installed
35-
# - repo: https://github.com/RobertCraigie/pyright-python
36-
# rev: v1.1.332
37-
# hooks:
38-
# - id: pyright
39-
# args: [-p, ".pre-commit-pyrightconfig.json"] # ignore `reportMissingImports`
34+
alias: black # NOTE: don't change this alias, it's used in `ver_sync.py`, keep consistent with `pyproject.toml`
4035
- repo: https://github.com/codespell-project/codespell
4136
rev: v2.2.6
4237
hooks:
4338
- id: codespell
39+
alias: codespell # NOTE: don't change this alias, it's used in `ver_sync.py`, keep consistent with `pyproject.toml`
4440
additional_dependencies:
4541
- tomli
4642
- repo: https://github.com/alessandrojcm/commitlint-pre-commit-hook
@@ -50,3 +46,14 @@ repos:
5046
stages: [commit-msg]
5147
# NOTE: the dependencies must consistent with `commitlint.config.js`
5248
additional_dependencies: ["@commitlint/config-conventional"]
49+
- repo: local
50+
hooks:
51+
- id: ver_sync
52+
stages: [pre-commit]
53+
name: synchronize versions of lint tools
54+
entry: python scripts/pre_commit_scripts/ver_sync.py
55+
language: python
56+
additional_dependencies:
57+
- tomlkit == 0.12.* # TODO: Once it releases version 1.0.0, we will remove this restriction.
58+
- ruamel.yaml == 0.18.* # TODO: Once it releases version 1.0.0, we will remove this restriction.
59+
- packaging == 23.*

.pre-commit-pyrightconfig.json

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

pyproject.toml

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ build-backend = "hatchling.build"
55
# https://hatch.pypa.io/latest/config/metadata/
66
[project]
77
name = "fastapi-proxy-lib"
8-
# the lowest required python version should be added to `.pre-commit-pyrightconfig.json`
98
requires-python = ">=3.8"
109
readme = "README.md"
1110
license = { file = "LICENSE" }
@@ -74,13 +73,17 @@ tag_name = "v{new_version}"
7473
path = ".venv" # for vscode auto selecting python interpreter
7574
features = ["all"]
7675
dependencies = [
77-
# lint
78-
# The dependencies version must be consistent with the `.pre-commit-config.yaml`.
79-
# # "pre-commit == 3.5.0", # install it by pipx for global, not hatch for local
80-
"black == 23.10.0",
76+
# NOTE: 👇
77+
# The versions of `black`, `ruff`, `codespell`, must be consistent with the `.pre-commit-config.yaml`.
78+
# Don't edit them manually, use `pre-commit run ver_sync` instead.
79+
"black==23.10.0",
80+
"ruff==0.1.1",
81+
"codespell==2.2.6",
82+
# Don't write comments on these lines, because they will be removed by `pre-commit run ver_sync`.
83+
# NOTE: 👆
84+
85+
# lint-check
8186
"pyright == 1.1.332", # pyright must be installed in the runtime environment
82-
"ruff == 0.1.1",
83-
"codespell == 2.2.6",
8487
# test
8588
"pytest == 7.*",
8689
"pytest-cov == 4.*",
@@ -217,7 +220,8 @@ exclude_also = [
217220
"raise NotImplementedError",
218221
"class .*\\bProtocol\\):",
219222
"@(abc\\.)?abstractmethod",
220-
"@(typing_extensions\\.)?deprecated", # deprecated code will not be tested
223+
# # deprecated code will not be tested
224+
"@(typing_extensions\\.)?deprecated",
221225
# `overload` just for type hint, will not be tested
222226
"@(typing_extensions\\.)?overload",
223227
"@(typing\\.)?overload",
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
# pyright: basic
2+
3+
"""Maintain lint tools version consistency between `.pre-commit-config.yaml` and `pyproject.toml`."""
4+
5+
6+
# https://packaging.pypa.io/en/stable/requirements.html
7+
# https://yaml.readthedocs.io/en/latest/example/
8+
# https://tomlkit.readthedocs.io/en/latest/quickstart/
9+
# https://hatch.pypa.io/latest/config/environment/overview/#dependencies
10+
11+
12+
import sys
13+
from pathlib import Path
14+
from typing import (
15+
Any,
16+
Dict,
17+
List,
18+
Union,
19+
)
20+
21+
import tomlkit # type: ignore
22+
import tomlkit.items # type: ignore
23+
from packaging.requirements import Requirement # type: ignore
24+
from packaging.specifiers import SpecifierSet # type: ignore
25+
from packaging.version import Version # type: ignore
26+
from ruamel.yaml import YAML # type: ignore
27+
28+
yaml = YAML(typ="safe")
29+
30+
pre_commit_config_yaml_path = Path(".pre-commit-config.yaml")
31+
pyproject_toml_path = Path("pyproject.toml")
32+
33+
RepoType = Dict[str, Any]
34+
HookType = Dict[str, Any]
35+
36+
if __name__ == "__main__":
37+
# NOTE: 这三个键名应该对应
38+
# pyproject_toml["tool"]["hatch"]["envs"]["default"]["dependencies"] 里的值
39+
vers_in_pre_commit: Dict[str, Union[None, str]] = {
40+
"ruff": None,
41+
"black": None,
42+
"codespell": None,
43+
}
44+
45+
# 找出pre-commit-config.yaml中的版本
46+
pre_commit_yaml = yaml.load(pre_commit_config_yaml_path)
47+
repos_lst: List[RepoType] = pre_commit_yaml["repos"]
48+
49+
for repo in repos_lst:
50+
hooks_lst: List[HookType] = repo["hooks"]
51+
hook = hooks_lst[0] # 特殊标记的只有一个hook
52+
hook_alias = hook.get("alias") # 只有特殊标记的才有alias
53+
if hook_alias is None:
54+
continue
55+
if hook_alias in vers_in_pre_commit:
56+
vers_in_pre_commit[hook_alias] = repo["rev"]
57+
58+
# 检查是否正确
59+
new_vers: Dict[str, Version] = {}
60+
for name, ver in vers_in_pre_commit.items():
61+
if not isinstance(ver, str):
62+
sys.exit(f"Error: version of `{name}` not found in pre-commit-config.yaml")
63+
try:
64+
new_vers[name] = Version(ver)
65+
except Exception as e:
66+
sys.exit(f"{e}: version of `{name}` in pre-commit-config.yaml is invalid")
67+
68+
# 修改pyproject.toml中的版本
69+
with open(pyproject_toml_path, "rb") as f: # NOTE: 用二进制模式打开
70+
pyproject_toml = tomlkit.load(f)
71+
requir_lst = pyproject_toml["tool"]["hatch"]["envs"]["default"]["dependencies"] # type: ignore
72+
assert isinstance(requir_lst, tomlkit.items.Array)
73+
74+
for idx, require in enumerate(requir_lst):
75+
assert isinstance(require, tomlkit.items.String)
76+
parsed_requir = Requirement(require)
77+
if parsed_requir.name in new_vers:
78+
# 更新版本
79+
parsed_requir.specifier = SpecifierSet(
80+
f"=={new_vers.pop(parsed_requir.name)}"
81+
)
82+
requir_lst[idx] = str(parsed_requir)
83+
84+
# 在上一步的pop操作应该把所有的依赖都更新了,如果这里字典不为空,说明发生了错误
85+
if new_vers:
86+
sys.exit(
87+
f"Error: version of `{new_vers.popitem()}` not found in pyproject.toml"
88+
)
89+
90+
# 如果没错误,就准备更新
91+
pyproject_toml["tool"]["hatch"]["envs"]["default"]["dependencies"] = requir_lst # type: ignore
92+
93+
with open(pyproject_toml_path, "wb") as f:
94+
toml_str = tomlkit.dumps(pyproject_toml)
95+
f.write(toml_str.encode("utf-8")) # NOTE: 用utf-8二进制写入,否则文本样式会乱

0 commit comments

Comments
 (0)