forked from pandas-dev/pandas
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsync_flake8_versions.py
169 lines (136 loc) · 5.02 KB
/
sync_flake8_versions.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
"""
Check that the flake8 (and pandas-dev-flaker) pins are the same in:
- environment.yml
- .pre-commit-config.yaml, in the flake8 hook
- .pre-commit-config.yaml, in the additional dependencies of the yesqa hook
The flake8 hook revision in .pre-commit-config.yaml is taken as the reference revision.
Usage: either
- ``python scripts/sync_flake8_versions.py``, or
- ``pre-commit run sync-flake8-versions --all-files``.
"""
from __future__ import annotations
from dataclasses import (
dataclass,
replace,
)
import sys
from typing import (
Any,
Mapping,
Sequence,
TypeVar,
)
import yaml
@dataclass
class Revision:
name: str
compare: str
version: str
@dataclass
class Revisions:
name: str
pre_commit: Revision | None = None
yesqa: Revision | None = None
environment: Revision | None = None
YamlMapping = Mapping[str, Any]
Repo = TypeVar("Repo", bound=YamlMapping)
COMPARE = ("<=", "==", ">=", "<", ">", "=")
def _get_repo_hook(repos: Sequence[Repo], hook_name: str) -> tuple[Repo, YamlMapping]:
for repo in repos:
for hook in repo["hooks"]:
if hook["id"] == hook_name:
return repo, hook
else: # pragma: no cover
raise RuntimeError(f"Repo with hook {hook_name} not found")
def _conda_to_pip_compat(dep):
if dep.compare == "=":
return replace(dep, compare="==")
else:
return dep
def _validate_additional_dependencies(
flake8_additional_dependencies,
yesqa_additional_dependencies,
environment_additional_dependencies,
) -> None:
for dep in flake8_additional_dependencies:
if dep not in yesqa_additional_dependencies:
sys.stdout.write(
f"Mismatch of '{dep.name}' version between 'flake8' "
"and 'yesqa' in '.pre-commit-config.yaml'\n"
)
sys.exit(1)
if dep not in environment_additional_dependencies:
sys.stdout.write(
f"Mismatch of '{dep.name}' version between 'enviroment.yml' "
"and additional dependencies of 'flake8' in '.pre-commit-config.yaml'\n"
)
sys.exit(1)
def _validate_revisions(revisions):
if revisions.environment != revisions.pre_commit:
sys.stdout.write(
f"{revisions.name} in 'environment.yml' does not "
"match in 'flake8' from 'pre-commit'\n"
)
sys.exit(1)
if revisions.yesqa != revisions.pre_commit:
sys.stdout.write(
f"{revisions.name} in 'yesqa' does not match "
"in 'flake8' from 'pre-commit'\n"
)
sys.exit(1)
def _process_dependencies(deps):
for dep in deps:
if isinstance(dep, str):
for compare in COMPARE:
if compare in dep:
pkg, rev = dep.split(compare, maxsplit=1)
yield _conda_to_pip_compat(Revision(pkg, compare, rev))
break
else:
yield from _process_dependencies(dep["pip"])
def get_revisions(
precommit_config: YamlMapping, environment: YamlMapping
) -> tuple[Revisions, Revisions]:
flake8_revisions = Revisions(name="flake8")
pandas_dev_flaker_revisions = Revisions(name="pandas-dev-flaker")
repos = precommit_config["repos"]
flake8_repo, flake8_hook = _get_repo_hook(repos, "flake8")
flake8_revisions.pre_commit = Revision("flake8", "==", flake8_repo["rev"])
flake8_additional_dependencies = []
for dep in _process_dependencies(flake8_hook.get("additional_dependencies", [])):
if dep.name == "pandas-dev-flaker":
pandas_dev_flaker_revisions.pre_commit = dep
else:
flake8_additional_dependencies.append(dep)
_, yesqa_hook = _get_repo_hook(repos, "yesqa")
yesqa_additional_dependencies = []
for dep in _process_dependencies(yesqa_hook.get("additional_dependencies", [])):
if dep.name == "flake8":
flake8_revisions.yesqa = dep
elif dep.name == "pandas-dev-flaker":
pandas_dev_flaker_revisions.yesqa = dep
else:
yesqa_additional_dependencies.append(dep)
environment_dependencies = environment["dependencies"]
environment_additional_dependencies = []
for dep in _process_dependencies(environment_dependencies):
if dep.name == "flake8":
flake8_revisions.environment = dep
elif dep.name == "pandas-dev-flaker":
pandas_dev_flaker_revisions.environment = dep
else:
environment_additional_dependencies.append(dep)
_validate_additional_dependencies(
flake8_additional_dependencies,
yesqa_additional_dependencies,
environment_additional_dependencies,
)
for revisions in flake8_revisions, pandas_dev_flaker_revisions:
_validate_revisions(revisions)
if __name__ == "__main__":
with open(".pre-commit-config.yaml") as fd:
precommit_config = yaml.safe_load(fd)
with open("environment.yml") as fd:
environment = yaml.safe_load(fd)
get_revisions(precommit_config, environment)
sys.exit(0)