(root: pathlib.Path)
| 374 | |
| 375 | |
| 376 | def discover_archives(root: pathlib.Path) -> dict[str, pathlib.Path]: |
| 377 | try: |
| 378 | root_status = root.lstat() |
| 379 | except FileNotFoundError as error: |
| 380 | raise ContractError(f"archive directory does not exist: {root}") from error |
| 381 | if not stat.S_ISDIR(root_status.st_mode): |
| 382 | raise ContractError(f"archive path is not a regular directory: {root}") |
| 383 | |
| 384 | discovered: dict[str, pathlib.Path] = {} |
| 385 | archive_like: list[pathlib.Path] = [] |
| 386 | for directory, names, files in os.walk(root, followlinks=False): |
| 387 | parent = pathlib.Path(directory) |
| 388 | for name in names: |
| 389 | child = parent / name |
| 390 | if child.is_symlink(): |
| 391 | raise ContractError(f"symlinked directory in archive tree: {child}") |
| 392 | for name in files: |
| 393 | child = parent / name |
| 394 | if child.is_symlink(): |
| 395 | raise ContractError(f"symlinked file in archive tree: {child}") |
| 396 | if name.endswith((".tar.gz", ".zip", ".mcpb")): |
| 397 | archive_like.append(child) |
| 398 | if name in discovered: |
| 399 | raise ContractError(f"duplicate archive basename: {name}") |
| 400 | discovered[name] = child |
| 401 | actual_names = set(discovered) |
| 402 | expected_names = set(ARCHIVES) |
| 403 | if actual_names != expected_names or len(archive_like) != len(expected_names): |
| 404 | missing = sorted(expected_names - actual_names) |
| 405 | surplus = sorted(actual_names - expected_names) |
| 406 | raise ContractError( |
| 407 | f"archive namespace is not the exact canonical set; missing={missing}, surplus={surplus}" |
| 408 | ) |
| 409 | return discovered |
| 410 | |
| 411 | |
| 412 | def main(argv: Sequence[str]) -> None: |
no test coverage detected