76 lines
2.6 KiB
Python
76 lines
2.6 KiB
Python
|
|
# Copyright 2024-2025 XMOS LIMITED.
|
||
|
|
# This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
||
|
|
|
||
|
|
"""
|
||
|
|
Wrapper around pip-tools to make life easy, Python for portability
|
||
|
|
each <file.in> in the current folder will produce a compiled <file.txt> on top-level folder
|
||
|
|
|
||
|
|
Usage:
|
||
|
|
|
||
|
|
python tools/update-requirements.py [package1 package2 ...]
|
||
|
|
|
||
|
|
Named packages are optional and will be upgraded to the latest version.
|
||
|
|
"""
|
||
|
|
|
||
|
|
import os
|
||
|
|
import sys
|
||
|
|
import subprocess
|
||
|
|
from pathlib import Path
|
||
|
|
import pip
|
||
|
|
from contextlib import contextmanager, ExitStack
|
||
|
|
from tempfile import TemporaryDirectory
|
||
|
|
|
||
|
|
cwd = Path(__file__).parent.absolute()
|
||
|
|
repo_root = cwd.parent.absolute()
|
||
|
|
|
||
|
|
|
||
|
|
def get_header_text():
|
||
|
|
py_major, py_minor = sys.version_info.major, sys.version_info.minor
|
||
|
|
pip_version_major = (pip.__version__).split(".", maxsplit=2)[0]
|
||
|
|
header_text = f"# python_version {py_major}.{py_minor}\n"
|
||
|
|
header_text += f"# pip_version {pip_version_major}.*\n"
|
||
|
|
return header_text
|
||
|
|
|
||
|
|
@contextmanager
|
||
|
|
def gen_valid_constraints(req_file):
|
||
|
|
with TemporaryDirectory() as temp_dir:
|
||
|
|
temp_dir = Path(temp_dir)
|
||
|
|
constraint_file = temp_dir / "constraints.txt"
|
||
|
|
|
||
|
|
with open(req_file, "r") as f:
|
||
|
|
with open(constraint_file, "w") as c:
|
||
|
|
for line in f:
|
||
|
|
if not line.startswith("-e") and not "git" in line:
|
||
|
|
c.write(line)
|
||
|
|
yield constraint_file
|
||
|
|
|
||
|
|
|
||
|
|
def gen(req_in, constraints=tuple(), upgrade=tuple()):
|
||
|
|
with ExitStack() as stack:
|
||
|
|
upgrade = " ".join(f"--upgrade-package {u}" for u in upgrade)
|
||
|
|
constraints = [stack.enter_context(gen_valid_constraints(c)) for c in constraints]
|
||
|
|
req_in = req_in.relative_to(repo_root) # needed for relative path output
|
||
|
|
req_dst = (repo_root / req_in.with_suffix(".txt").name).relative_to(repo_root)
|
||
|
|
opts = "--no-emit-trusted-host --no-emit-index-url"
|
||
|
|
constraints = " ".join(f"-c {c}" for c in constraints)
|
||
|
|
cmd = f"pip-compile {req_in} {constraints} {upgrade} -o {req_dst} {opts}"
|
||
|
|
subprocess.run(cmd, shell=True, check=True, cwd=repo_root, timeout=200)
|
||
|
|
# add header to req_dst
|
||
|
|
header_text = get_header_text()
|
||
|
|
req_dst.write_text(header_text + req_dst.read_text())
|
||
|
|
return req_dst
|
||
|
|
|
||
|
|
|
||
|
|
def main():
|
||
|
|
upgrade = sys.argv[1:]
|
||
|
|
|
||
|
|
# configure pip-tools header comment
|
||
|
|
os.environ["CUSTOM_COMPILE_COMMAND"] = f"./tools/update-requirements.py"
|
||
|
|
|
||
|
|
req_in = cwd/"requirements.in"
|
||
|
|
reqs = gen(req_in, upgrade=upgrade)
|
||
|
|
gen(cwd/"requirements-format.in", constraints=(reqs,))
|
||
|
|
|
||
|
|
if __name__ == "__main__":
|
||
|
|
main()
|