diff --git a/sync.sh b/sync.sh index 1ac51e3..a961ded 100755 --- a/sync.sh +++ b/sync.sh @@ -1,42 +1,48 @@ -#!/bin/bash -# Sync ARAs from source project repos into this aggregator. -# Uses git sparse-checkout to pull only the ara/ subdirectory. -# Run after PRs are merged. +#!/usr/bin/env python3 +""" +ARA Aggregator Sync +Reads catalog.yaml and sparse-checkouts ara/ from each source repo. +Run this after PRs merge to update the aggregator from canonical sources. +""" +import yaml, subprocess, shutil, os, sys -set -e -GITEA="https://git.wylab.me" +with open(os.path.join(os.path.dirname(__file__), "catalog.yaml")) as f: + catalog = yaml.safe_load(f) -sync_ara() { - local id=$1 - local repo=$2 - local branch=$3 - local src_path=$4 - local dest="$id" +errors = [] +for artifact in catalog["artifacts"]: + if artifact["status"] == "aggregator-only": + print(f" skip {artifact['id']} (aggregator-only)") + continue + if "pr-open" in artifact["status"] or "stub" in artifact["status"]: + print(f" skip {artifact['id']} (PR not yet merged: {artifact.get('pr','')})") + continue - echo "Syncing $id from $repo ($branch:$src_path)..." - - if [ -d "/tmp/sync-$id" ]; then - rm -rf "/tmp/sync-$id" - fi - - git clone --no-checkout --filter=blob:none --depth=1 \ - -b "$branch" "$repo" "/tmp/sync-$id" 2>/dev/null - - cd "/tmp/sync-$id" - git sparse-checkout init --cone - git sparse-checkout set "$src_path" - git checkout - - cd - - rm -rf "$dest" - cp -r "/tmp/sync-$id/$src_path" "$dest" - echo " Done: $id" -} + id, repo, branch, path = ( + artifact["id"], artifact["repo"], + artifact["branch"], artifact["path"].rstrip("/"), + ) + print(f"syncing {id} from {repo} ({branch}:{path}) ...") + tmp = f"/tmp/ara-sync-{id}" + try: + shutil.rmtree(tmp, ignore_errors=True) + subprocess.run( + ["git","clone","--no-checkout","--filter=blob:none","--depth=1","-b",branch,repo,tmp], + check=True, capture_output=True, + ) + subprocess.run(["git","sparse-checkout","init","--cone"], cwd=tmp, check=True, capture_output=True) + subprocess.run(["git","sparse-checkout","set",path], cwd=tmp, check=True, capture_output=True) + subprocess.run(["git","checkout"], cwd=tmp, check=True, capture_output=True) + dest = id + shutil.rmtree(dest, ignore_errors=True) + shutil.copytree(f"{tmp}/{path}", dest) + shutil.rmtree(tmp, ignore_errors=True) + print(f" ok: {id}") + except Exception as e: + errors.append((id, str(e))) + print(f" ERROR: {id}: {e}", file=sys.stderr) -# Sync after PRs merge: -# sync_ara "nanobot" "$GITEA/wylab/nanobot.git" "main" "ara" -# sync_ara "ss14-cicd" "$GITEA/wylab/WS14-Docker-Linux-Server.git" "main" "ara" -# sync_ara "wylab-station-14" "$GITEA/wylab/wylab-station-14.git" "master" "ara" - -# traefik stays aggregator-only (no project repo) -echo "Sync complete." +if errors: + print(f"\nFailed: {[e[0] for e in errors]}", file=sys.stderr) + sys.exit(1) +print("Sync complete.")