3Compile any `requirements.in` files into a list of exact versions
6* If you pass the `--upgrade` flag, it will upgrade all the requirements
8* If you pass `--upgrade-package <package>`, it will upgrade only that
16from pathlib import Path
19def compile_requirements_file(
20 in_file: str, *, upgrade: bool, upgrade_packages: list[str] | None, no_cache: bool
23 Compile a single requirements file.
25 assert in_file.endswith(".in")
26 txt_file = in_file.replace(".in", ".txt")
27 assert in_file != txt_file
29 # If this `.in` file doesn't exist.
30 if not Path(in_file).exists():
33 # Construct the `uv pip compile` command.
39 f"--output-file={txt_file}",
41 # Exclude dependencies which are less than 7 days old; this is
42 # a mitigation against supply chain attacks and installing
43 # recently-published malicious code on my computer.
44 "--exclude-newer=P7D",
46 # Allow installing new versions of my own packages
47 "--exclude-newer-package",
48 "alexwlchan-chives=false",
52 cmd.append("--upgrade")
55 for pkg in upgrade_packages:
56 cmd.extend(["--upgrade-package", pkg])
57 cmd.extend(["--exclude-newer-package", f"{pkg}=false"])
60 cmd.append("--no-cache")
62 # Actually run the command, and print a debug entry for it.
64 # `uv pip compile` prints the generated `requirements.txt` file to
65 # stdout, so we pipe that to /dev/null -- we're writing it to a file.
66 subprocess.check_call(
67 ["/Users/alexwlchan/repos/scripts/debug/print_info", f"-> {shlex.join(cmd)}"]
69 subprocess.check_call(cmd, stdout=subprocess.DEVNULL)
72def parse_args() -> argparse.Namespace:
73 parser = argparse.ArgumentParser(
74 description="Compile requirements.in files into requirements.txt"
79 help="Upgrade all packages to their latest versions",
84 dest="upgrade_packages",
86 help="Upgrade a specific package (can be passed multiple times)",
91 help="Disable caching in uv",
93 return parser.parse_args()
96if __name__ == "__main__":
99 for f in ["requirements.in", "dev_requirements.in"]:
100 compile_requirements_file(
102 upgrade=args.upgrade,
103 upgrade_packages=args.upgrade_packages,
104 no_cache=args.no_cache,