mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-06 07:51:47 +00:00
83 lines
2.5 KiB
Python
83 lines
2.5 KiB
Python
# /// script
|
|
# ///
|
|
"""
|
|
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.
|
|
|
|
Expected to be executed from 'build' directory (e.g. that might contain 'Linux/x86_64/install').
|
|
|
|
Usage: python cache_dependencies.py [pack|unpack]
|
|
"""
|
|
|
|
import platform
|
|
import subprocess
|
|
import sys
|
|
import tarfile
|
|
from pathlib import Path
|
|
from typing import Literal
|
|
|
|
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):
|
|
return data
|
|
raise Exception("No install dir found")
|
|
|
|
|
|
def run(cmd: str) -> None:
|
|
print(f"Running command: `{cmd}`")
|
|
subprocess.check_call(cmd, shell=True)
|
|
|
|
|
|
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
|
|
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}"')
|
|
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.
|
|
tar_filter: dict[Literal["filter"], Literal["data"]] = (
|
|
{"filter": "data"} if bool(sys.version_info >= (3, 12)) else {}
|
|
)
|
|
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)
|
|
print(f"Extracted cache: '{tar_path.name}'.")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
action = None
|
|
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)
|