Atlas - metadata.py

Home / npkg-testing / tools / npkg Lines: 1 | Size: 3680 bytes [Download] [Show on GitHub] [Search similar files] [Raw] [Raw (proxy)]
[FILE BEGIN]
1import os 2from pathlib import Path 3from typing import Any, Dict, Optional 4 5try: 6 import tomllib 7except ModuleNotFoundError: # pragma: no cover 8 tomllib = None 9 10from .paths import workspace_root 11from .types import Package 12 13 14def normalize_command(raw: Optional[str]) -> Optional[str]: 15 if raw is None: 16 return None 17 command = raw.strip() 18 return command or None 19 20 21def as_dict(value: Any) -> Dict[str, Any]: 22 return value if isinstance(value, dict) else {} 23 24 25def load_raw_package(meta_path: Path) -> Dict[str, Any]: 26 if tomllib is None: 27 raise ValueError("TOML metadata requires Python 3.11+ (tomllib not available)") 28 with meta_path.open("rb") as handle: 29 parsed = tomllib.load(handle) 30 if not isinstance(parsed, dict): 31 raise ValueError(f"Invalid metadata in {meta_path}: expected top-level table") 32 return parsed 33 34 35def load_package(meta_path: Path) -> Package: 36 data = load_raw_package(meta_path) 37 38 default_name = meta_path.parent.name.replace("_", "-") 39 name = str(data.get("name") or default_name).strip() 40 version = str(data.get("version") or "0.1.0").strip() 41 description = str(data.get("description") or "").strip() 42 install_path = str(data.get("install_path") or "/usr/bin/").strip() 43 44 build = as_dict(data.get("build", {})) 45 package_section = as_dict(data.get("package", {})) 46 clean = as_dict(data.get("clean", {})) 47 48 if not name or not version: 49 raise ValueError(f"Invalid metadata in {meta_path}: missing name/version") 50 51 if install_path and not install_path.startswith("/"): 52 install_path = f"/{install_path}" 53 54 return Package( 55 name=name, 56 version=version, 57 description=description, 58 package_dir=meta_path.parent, 59 install_path=install_path, 60 build_command=normalize_command(build.get("command")), 61 package_command=normalize_command(package_section.get("command")), 62 clean_command=normalize_command(clean.get("command")), 63 ) 64 65 66def metadata_file_in_dir(package_dir: Path) -> Optional[Path]: 67 meta = package_dir / "npkg.conf" 68 return meta if meta.exists() else None 69 70 71def discover_packages() -> Dict[str, Package]: 72 root = workspace_root() 73 packages: Dict[str, Package] = {} 74 search_roots = [ 75 root / "bin", 76 root / "sbin", 77 root / "toolkits", 78 root / "lib" / "public", 79 root / "lib" / "private", 80 root / "lab", 81 root / "systems", 82 ] 83 84 for top in search_roots: 85 if not top.exists(): 86 continue 87 for dirpath, _, filenames in os.walk(top): 88 if "npkg.conf" not in set(filenames): 89 continue 90 package_dir = Path(dirpath) 91 meta = metadata_file_in_dir(package_dir) 92 if meta is None: 93 continue 94 package = load_package(meta) 95 if package.name in packages: 96 first = packages[package.name].package_dir 97 raise ValueError( 98 f"Duplicate package name '{package.name}' in {first} and {package.package_dir}" 99 ) 100 packages[package.name] = package 101 102 return dict(sorted(packages.items(), key=lambda item: item[0])) 103 104 105def select_package(packages: Dict[str, Package], selector: str) -> Package: 106 if selector in packages: 107 return packages[selector] 108 109 root = workspace_root() 110 normalized = selector.strip().strip("/") 111 if normalized: 112 selector_path = (root / normalized).resolve() 113 for pkg in packages.values(): 114 if pkg.package_dir.resolve() == selector_path: 115 return pkg 116 117 raise KeyError(selector) 118
[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.