feat: auto-update pre-commit config
This commit is contained in:
@@ -1,5 +1,7 @@
|
|||||||
# File used in CI to ensure pre-commit dependencies are kept up-to-date.
|
# File used in CI to ensure pre-commit dependencies are kept up-to-date.
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import re
|
||||||
import sys
|
import sys
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
@@ -10,6 +12,24 @@ pre_commit_file = Path(".pre-commit-config.yaml")
|
|||||||
require_dev = Path("requirements-dev.txt")
|
require_dev = Path("requirements-dev.txt")
|
||||||
require = Path("requirements.txt")
|
require = Path("requirements.txt")
|
||||||
|
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser()
|
||||||
|
parser.add_argument("--update", action="store_true")
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
|
||||||
|
def replace_dependency_version(pre_commit_text: str, dependency: str) -> tuple[str, bool]:
|
||||||
|
"""
|
||||||
|
Regex-based replacement of a dependency version in the pre-commit config file.
|
||||||
|
using regex here ensures we only replace the version of the dependency while
|
||||||
|
keeping the overall file intact.
|
||||||
|
"""
|
||||||
|
package_name = dependency.split("==", 1)[0]
|
||||||
|
pattern = re.compile(rf"^(\s*-\s+){re.escape(package_name)}==.*$", re.MULTILINE)
|
||||||
|
updated_text, replacements = pattern.subn(rf"\1{dependency}", pre_commit_text, count=1)
|
||||||
|
return updated_text, replacements > 0 and updated_text != pre_commit_text
|
||||||
|
|
||||||
|
|
||||||
with require_dev.open("r") as rfile:
|
with require_dev.open("r") as rfile:
|
||||||
requirements = rfile.readlines()
|
requirements = rfile.readlines()
|
||||||
|
|
||||||
@@ -23,6 +43,18 @@ supported = ("types-", "SQLAlchemy", "scipy-stubs")
|
|||||||
# Only keep the first part of the line up to the first space
|
# Only keep the first part of the line up to the first space
|
||||||
type_reqs = [r.strip("\n").split()[0] for r in requirements if r.startswith(supported)]
|
type_reqs = [r.strip("\n").split()[0] for r in requirements if r.startswith(supported)]
|
||||||
|
|
||||||
|
with pre_commit_file.open("r") as file:
|
||||||
|
pre_commit_text = file.read()
|
||||||
|
|
||||||
|
updated = False
|
||||||
|
for req in type_reqs:
|
||||||
|
pre_commit_text, req_updated = replace_dependency_version(pre_commit_text, req)
|
||||||
|
updated = updated or req_updated
|
||||||
|
|
||||||
|
if args.update and updated:
|
||||||
|
with pre_commit_file.open("w") as file:
|
||||||
|
file.write(pre_commit_text)
|
||||||
|
|
||||||
with pre_commit_file.open("r") as file:
|
with pre_commit_file.open("r") as file:
|
||||||
f = yaml.load(file, Loader=yaml.SafeLoader)
|
f = yaml.load(file, Loader=yaml.SafeLoader)
|
||||||
|
|
||||||
@@ -40,12 +72,20 @@ for hook in hooks:
|
|||||||
|
|
||||||
for req in type_reqs:
|
for req in type_reqs:
|
||||||
if req not in hooks:
|
if req not in hooks:
|
||||||
errors.append(f"{req} is missing in pre-config file.")
|
errors.append(f"{req} is missing in pre-commit config file.")
|
||||||
|
|
||||||
|
if updated:
|
||||||
|
if args.update:
|
||||||
|
errors.append(".pre-commit-config.yaml was updated to match the requirements files.")
|
||||||
|
else:
|
||||||
|
errors.append(
|
||||||
|
".pre-commit-config.yaml is outdated. Run build_helpers/pre_commit_update.py --update."
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
if errors:
|
if errors:
|
||||||
for e in errors:
|
for e in errors:
|
||||||
print(e)
|
print(e)
|
||||||
sys.exit(1)
|
sys.exit(1 if not (args.update and updated) else 0)
|
||||||
|
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
|
|||||||
Reference in New Issue
Block a user