5851974b20
Release fork infrastructure: - REDBEAR_RELEASE=0.1.1 with offline enforcement (fetch/distclean/unfetch blocked) - 195 BLAKE3-verified source archives in standard format - Atomic provisioning via provision-release.sh (staging + .complete sentry) - 5-phase improvement plan: restore format auto-detection, source tree validation (validate-source-trees.py), archive-map.json, REPO_BINARY fallback Archive normalization: - Removed 87 duplicate/unversioned archives from shared pool - Regenerated all archives in consistent format with source/ + recipe.toml - BLAKE3SUMS and manifest.json generated from stable tarball set Patch management: - verify-patches.sh: pre-sync dry-run report (OK/REVERSED/CONFLICT) - 121 upstream-absorbed patches moved to absorbed/ directories - 43 active patches verified clean against rebased sources - Stress test: base updated to upstream HEAD, relibc reset and patched Compilation fixes: - relibc: Vec imports in redox-rt (proc.rs, lib.rs, sys.rs) - relibc: unsafe from_raw_parts in mod.rs (2024 edition) - fetch.rs: rev comparison handles short/full hash prefixes - kibi recipe: corrected rev mismatch New scripts: restore-sources.sh, provision-release.sh, verify-sources-archived.sh, check-upstream-releases.sh, validate-source-trees.py, verify-patches.sh, repair-archive-format.sh, generate-manifest.py Documentation: AGENTS.md, README.md, local/AGENTS.md updated for release fork model
76 lines
2.3 KiB
Python
Executable File
76 lines
2.3 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
"""Validate that all source trees required by a build config exist."""
|
|
import sys, tomllib
|
|
from pathlib import Path
|
|
|
|
PROJECT_ROOT = Path(__file__).resolve().parents[2]
|
|
CONFIG = sys.argv[1] if len(sys.argv) > 1 else "redbear-full"
|
|
|
|
def build_lookup():
|
|
lookup = {}
|
|
for root in (Path("recipes"), Path("local/recipes")):
|
|
for rt in root.rglob("recipe.toml"):
|
|
parts = rt.parts
|
|
if "source" in parts or "target" in parts:
|
|
continue
|
|
pkg = rt.parent.name
|
|
if pkg not in lookup:
|
|
lookup[pkg] = rt.parent
|
|
return lookup
|
|
|
|
def resolve_config(cp, visited=None):
|
|
if visited is None: visited = set()
|
|
cp = cp.resolve()
|
|
if cp in visited: return {}
|
|
visited.add(cp)
|
|
with open(cp, "rb") as f: c = tomllib.load(f)
|
|
pkgs = dict(c.get("packages", {}))
|
|
for inc in c.get("include", []):
|
|
ip = cp.parent / inc
|
|
if ip.exists():
|
|
incd = resolve_config(ip, visited)
|
|
for k, v in pkgs.items(): incd[k] = v
|
|
pkgs = incd
|
|
return pkgs
|
|
|
|
def main():
|
|
config_path = Path("config") / f"{CONFIG}.toml"
|
|
if not config_path.exists():
|
|
print(f"Config not found: {config_path}", file=sys.stderr)
|
|
return 1
|
|
|
|
lookup = build_lookup()
|
|
pkgs = resolve_config(config_path)
|
|
|
|
print(f"=== Validating source trees for config: {CONFIG} ===")
|
|
missing = 0
|
|
present = 0
|
|
for pkg_name, pkg_conf in sorted(pkgs.items()):
|
|
if str(pkg_conf) == "ignore": continue
|
|
# Meta packages have no source requirement
|
|
if pkg_name in ("libgcc", "libstdcxx"):
|
|
continue
|
|
rd = lookup.get(pkg_name)
|
|
if not rd:
|
|
print(f" NOT FOUND: {pkg_name}")
|
|
missing += 1
|
|
continue
|
|
src = rd / "source"
|
|
if src.is_dir() and any(src.iterdir()):
|
|
present += 1
|
|
else:
|
|
print(f" MISSING: {str(rd)}")
|
|
missing += 1
|
|
|
|
print(f"\n Total (config): {present + missing}")
|
|
print(f" Present: {present}")
|
|
print(f" Missing: {missing}")
|
|
if missing:
|
|
print("\nTo restore: ./local/scripts/restore-sources.sh --release=0.1.0")
|
|
return 1
|
|
print("All source trees present.")
|
|
return 0
|
|
|
|
if __name__ == "__main__":
|
|
sys.exit(main())
|