-
-
Notifications
You must be signed in to change notification settings - Fork 8
Expand file tree
/
Copy pathupdate-pre-commit
More file actions
executable file
·167 lines (144 loc) · 5.01 KB
/
Copy pathupdate-pre-commit
File metadata and controls
executable file
·167 lines (144 loc) · 5.01 KB
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
#!/usr/bin/env python3
# Copyright © Michal Čihař <michal@weblate.org>
#
# SPDX-License-Identifier: CC0-1.0
"""Synchronizes pre-commit config for Weblate repositories."""
import re
import subprocess
import sys
from pathlib import Path
import ruamel.yaml
MD_REPOS = [
"https://github.com/executablebooks/mdformat",
"https://github.com/igorshubovych/markdownlint-cli",
]
REMOVE_REPOS = [
"https://github.com/asottile/pyupgrade",
"https://github.com/psf/black",
"https://github.com/PyCQA/isort",
"https://github.com/adamchainz/blacken-docs",
"https://github.com/rhysd/actionlint",
*MD_REPOS,
]
SYNC_REPOS = [
"https://github.com/kjanat/actionlint",
"https://github.com/zizmorcore/zizmor-pre-commit",
]
DEPENDENCY_PATTERNS = (
("python", re.compile(r"[^'\" ]+==[^'\" ,\s]+")),
("node", re.compile(r"[^'\" ]+@[^'\" ,\s]+")),
)
yaml = ruamel.yaml.YAML()
yaml.indent = 2
yaml.preserve_quotes = False
yaml.width = sys.maxsize
# Load template
template_path = Path(__file__).parent / ".pre-commit-config.yaml"
with template_path.open() as handle:
template = yaml.load(handle)
template_repos = {repo["repo"]: repo for repo in template["repos"]}
# Load target
precommit_file = Path(sys.argv[1])
with precommit_file.open() as handle:
data = yaml.load(handle)
changed = False
# Migrate markdown to rmdml
if [repo["repo"] in MD_REPOS for repo in data["repos"]]:
SYNC_REPOS.append("https://github.com/rvben/rumdl-pre-commit")
# Remove no longer wanted
remove = [
offset for offset, repo in enumerate(data["repos"]) if repo["repo"] in REMOVE_REPOS
]
if remove:
for offset in reversed(remove):
del data["repos"][offset]
changed = True
# Apply fixups
missing = set(SYNC_REPOS)
# pyproject linter/formatter
pyproject = precommit_file.parent / "pyproject.toml"
if pyproject.exists():
missing.add("https://github.com/abravalheri/validate-pyproject")
missing.add("https://github.com/pappasam/toml-sort")
for offset, repo in enumerate(data["repos"]):
if repo["repo"] in missing:
missing.remove(repo["repo"])
if repo["repo"] in template_repos and template_repos[repo["repo"]] != repo:
data["repos"][offset] = template_repos[repo["repo"]]
changed = True
# This is checked by ruff as well
if (
repo["repo"] == "https://github.com/pre-commit/pre-commit-hooks"
and {"id": "debug-statements"} in repo["hooks"]
):
repo["hooks"] = [
hook for hook in repo["hooks"] if hook["id"] != "debug-statements"
]
changed = True
# Migrate gitleaks to kingfisher
if repo["repo"] == "https://github.com/gitleaks/gitleaks":
repo["repo"] = "https://github.com/mongodb/kingfisher"
repo["rev"] = template_repos[repo["repo"]]["rev"]
repo["hooks"] = [{"id": "kingfisher-auto"}]
changed = True
# Add missing
for name in missing:
data["repos"].append(template_repos[name])
changed = True
for repo in data["repos"]:
for hook in repo["hooks"]:
if (
repo["repo"] == "https://github.com/mongodb/kingfisher"
and hook["id"] == "kingfisher-auto"
):
env = hook.setdefault("env", {})
if env.get("KINGFISHER_VERSION") != repo["rev"]:
env["KINGFISHER_VERSION"] = repo["rev"]
changed = True
# Add language tags so that Renovate can detect additional dependencies
dependencies = hook.get("additional_dependencies", ())
language = next(
(
language
for language, pattern in DEPENDENCY_PATTERNS
if any(pattern.search(dependency) for dependency in dependencies)
),
None,
)
if language is not None and hook.get("language") != language:
hook["language"] = language
changed = True
# Convert wrong float rev to str
if "rev" in repo and isinstance(repo["rev"], float):
repo["rev"] = str(repo["rev"])
changed = True
# Update CI config
if "ci" not in data:
data["ci"] = {}
changed = True
if "autoupdate_schedule" not in data["ci"]:
data["ci"]["autoupdate_schedule"] = "quarterly"
changed = True
if any(
repo["repo"] == "https://github.com/mongodb/kingfisher" for repo in data["repos"]
):
if "kingfisher-auto" not in data["ci"]["skip"]:
data["ci"]["skip"].append("kingfisher-auto")
changed = True
elif "kingfisher-auto" in data["ci"]["skip"]:
data["ci"]["skip"].remove("kingfisher-auto")
changed = True
if any(repo["repo"] == "https://github.com/fsfe/reuse-tool" for repo in data["repos"]):
if "reuse" not in data["ci"]["skip"]:
data["ci"]["skip"].append("reuse")
changed = True
elif "reuse" in data["ci"]["skip"]:
data["ci"]["skip"].remove("reuse")
changed = True
# Save changed file
if changed:
with open(sys.argv[1], "w") as handle:
yaml.dump(data, handle)
subprocess.run(
["uvx", "prek", "run", "--files", sys.argv[1]], check=False, capture_output=True
)