Atlas - archive.py
Home / npkg-testing / tools / npkg Lines: 1 | Size: 2478 bytes [Download] [Show on GitHub] [Search similar files] [Raw] [Raw (proxy)][FILE BEGIN]1import shutil 2import subprocess 3import tarfile 4from pathlib import Path 5from typing import Dict, List, Optional 6 7from .console import info, ok 8from .paths import package_archive_path, package_stage_dir, workspace_root 9from .types import Package 10 11 12def command_context(pkg: Package, stage_dir: Optional[Path] = None) -> Dict[str, str]: 13 context = { 14 "workspace_root": str(workspace_root()), 15 "npkg_root": str(workspace_root()), 16 "npkg_build_root": str(workspace_root() / "npkg-build"), 17 "package_dir": str(pkg.package_dir), 18 "install_path": pkg.install_path, 19 } 20 if stage_dir is not None: 21 context["stage_dir"] = str(stage_dir) 22 return context 23 24 25def render_command(template: str, context: Dict[str, str]) -> str: 26 return template.format(**context) 27 28 29def run_shell(command: str, cwd: Path) -> None: 30 result = subprocess.run(command, cwd=str(cwd), shell=True) 31 if result.returncode != 0: 32 raise RuntimeError(f"Command failed with exit code {result.returncode}: {command}") 33 34 35def ensure_package_archive(pkg: Package) -> Path: 36 if not pkg.package_command: 37 raise RuntimeError(f"Package '{pkg.name}' does not define package.command") 38 39 stage_dir = package_stage_dir(pkg) 40 archive_path = package_archive_path(pkg) 41 42 shutil.rmtree(stage_dir, ignore_errors=True) 43 stage_dir.mkdir(parents=True, exist_ok=True) 44 45 context = command_context(pkg, stage_dir=stage_dir) 46 package_command = render_command(pkg.package_command, context) 47 48 info(f"staging {pkg.name} with: {package_command}") 49 run_shell(package_command, cwd=workspace_root()) 50 51 archive_path.parent.mkdir(parents=True, exist_ok=True) 52 with tarfile.open(archive_path, "w:gz") as tar: 53 for item in sorted(stage_dir.iterdir()): 54 tar.add(item, arcname=item.name) 55 56 ok(f"packaged {pkg.name} -> {archive_path}") 57 return archive_path 58 59 60def extract_archive_into_root(archive_path: Path, install_root: Path) -> List[str]: 61 try: 62 with tarfile.open(archive_path, "r:gz") as tar: 63 member_names = [member.name for member in tar.getmembers() if member.name and member.name != "."] 64 try: 65 tar.extractall(path=install_root, filter="data") 66 except TypeError: 67 tar.extractall(path=install_root) 68 except (tarfile.TarError, OSError) as error: 69 raise RuntimeError(f"failed to install archive: {error}") from error 70 return member_names 71[FILE END](C) 2025 0x4248 (C) 2025 4248 Media and 4248 Systems, All part of 0x4248 See LICENCE files for more information. Not all files are by 0x4248 always check Licencing.