Files
IfcOpenShell/nix/cache_dependencies.py
T

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

83 lines
2.5 KiB
Python
Raw Normal View History

# /// script
# ///
2025-10-21 12:42:56 +05:00
"""
Cache built dependencies for builds.
This script is finding common install directory and either
packs each folder into a tar.gz archive, if it wasn't packed before,
or unpacks existing archives.
2026-02-20 10:56:06 +05:00
Expected to be executed from 'build' directory (e.g. that might contain 'Linux/x86_64/install').
2025-10-21 12:42:56 +05:00
Usage: python cache_dependencies.py [pack|unpack]
"""
import platform
import subprocess
2025-10-21 12:42:56 +05:00
import sys
2025-12-19 18:53:04 +05:00
import tarfile
2025-10-21 12:42:56 +05:00
from pathlib import Path
from typing import Literal
2025-10-21 12:42:56 +05:00
CACHE_PREFIX = "cache-"
def get_install_dir() -> Path:
if platform.system() == "Darwin":
pattern = "Darwin/*/*/install"
else:
pattern = "*/*/install"
for data in Path.cwd().glob(pattern):
2025-10-21 12:42:56 +05:00
return data
raise Exception("No install dir found")
def run(cmd: str) -> None:
print(f"Running command: `{cmd}`")
subprocess.check_call(cmd, shell=True)
2025-10-21 12:42:56 +05:00
def pack_dependencies(install_dir: Path) -> None:
# Process each install_dir
for dependency_path in install_dir.iterdir():
if not dependency_path.is_dir():
continue
dependency_name = dependency_path.name
# Skip ifcopenshell - it's a build output, not a dependency to reuse across builds.
if dependency_name == "ifcopenshell":
continue
2025-10-21 12:42:56 +05:00
tar_path = install_dir / f"{CACHE_PREFIX}{dependency_name}.tar.gz"
if tar_path.exists():
print(f"Skipping existing cache: '{tar_path}'")
else:
# Python's `tarfile` is 10x slower than `tar` cli, so we use `tar`.
run(f'tar -czf "{tar_path}" -C "{install_dir}" "{dependency_name}"')
2025-10-21 12:42:56 +05:00
print(f"Created cache: '{tar_path}'")
def unpack_dependencies(install_dir: Path) -> None:
# `filter` argument was fully introduced in 3.12
# and results in deprecation warnings in 3.12-3.13, if not provided.
2025-10-28 17:56:44 +05:00
tar_filter: dict[Literal["filter"], Literal["data"]] = (
{"filter": "data"} if bool(sys.version_info >= (3, 12)) else {}
)
2025-10-21 12:42:56 +05:00
for tar_path in install_dir.glob(f"{CACHE_PREFIX}*.tar.gz"):
with tarfile.open(tar_path, "r:gz") as tar:
tar.extractall(path=install_dir, **tar_filter)
2025-10-21 12:42:56 +05:00
print(f"Extracted cache: '{tar_path.name}'.")
if __name__ == "__main__":
2026-07-18 20:35:10 +05:00
action = None
2025-10-21 12:42:56 +05:00
if len(sys.argv) != 2 or (action := sys.argv[1].lower()) not in ("pack", "unpack"):
print(__doc__)
sys.exit(1)
install_dir = get_install_dir()
print(f"Found install dir: '{install_dir}'")
if action == "pack":
pack_dependencies(install_dir)
else:
unpack_dependencies(install_dir)