|
| 1 | +#!/usr/bin/env bash |
| 2 | +# SPDX-License-Identifier: PMPL-1.0-or-later |
| 3 | +# deploy-clade-a2ml.sh — Batch deploy CLADE.a2ml to all repos in the seed file |
| 4 | +# |
| 5 | +# Reads verisimdb/seed/repos.a2ml, extracts repo name + clade assignments, |
| 6 | +# writes .machine_readable/CLADE.a2ml to each repo, commits, and pushes. |
| 7 | +# |
| 8 | +# Usage: ./sync/deploy-clade-a2ml.sh [--dry-run] |
| 9 | + |
| 10 | +set -uo pipefail |
| 11 | + |
| 12 | +REPOS_DIR="/var/mnt/eclipse/repos" |
| 13 | +SEED_FILE="$REPOS_DIR/gv-clade-index/verisimdb/seed/repos.a2ml" |
| 14 | +DRY_RUN="${1:-}" |
| 15 | +COMMIT_MSG="feat: add CLADE.a2ml — clade taxonomy declaration |
| 16 | +
|
| 17 | +Part of gv-clade-index Phase 1: every repo declares its identity, |
| 18 | +primary clade, and forge mappings for the VeriSimDB central registry. |
| 19 | +
|
| 20 | +Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>" |
| 21 | + |
| 22 | +SUCCESS=0 |
| 23 | +SKIPPED=0 |
| 24 | +FAILED=0 |
| 25 | +ALREADY=0 |
| 26 | + |
| 27 | +# Parse repos.a2ml using the standalone parser |
| 28 | +parse_repos() { |
| 29 | + bash "$REPOS_DIR/gv-clade-index/sync/parse-repos.sh" "$SEED_FILE" |
| 30 | +} |
| 31 | + |
| 32 | +deploy_clade() { |
| 33 | + local repo_name="$1" |
| 34 | + local primary="$2" |
| 35 | + local secondary="$3" |
| 36 | + local lineage="$4" |
| 37 | + local parent="$5" |
| 38 | + local description="$6" |
| 39 | + |
| 40 | + local repo_path="$REPOS_DIR/$repo_name" |
| 41 | + |
| 42 | + # Skip if repo doesn't exist on disk |
| 43 | + if [[ ! -d "$repo_path" ]]; then |
| 44 | + echo "SKIP (not on disk): $repo_name" |
| 45 | + ((SKIPPED++)) |
| 46 | + return |
| 47 | + fi |
| 48 | + |
| 49 | + # Skip if not a git repo |
| 50 | + if [[ ! -d "$repo_path/.git" ]]; then |
| 51 | + echo "SKIP (not git): $repo_name" |
| 52 | + ((SKIPPED++)) |
| 53 | + return |
| 54 | + fi |
| 55 | + |
| 56 | + # Skip gv-clade-index itself (already has CLADE.a2ml) |
| 57 | + if [[ "$repo_name" == "gv-clade-index" ]]; then |
| 58 | + echo "SKIP (self): $repo_name" |
| 59 | + ((SKIPPED++)) |
| 60 | + return |
| 61 | + fi |
| 62 | + |
| 63 | + # Skip if CLADE.a2ml already exists |
| 64 | + if [[ -f "$repo_path/.machine_readable/CLADE.a2ml" ]]; then |
| 65 | + echo "ALREADY: $repo_name" |
| 66 | + ((ALREADY++)) |
| 67 | + return |
| 68 | + fi |
| 69 | + |
| 70 | + # Generate deterministic UUID v5 |
| 71 | + local uuid |
| 72 | + uuid=$(uuidgen --sha1 --namespace @url --name "github.com/hyperpolymath/$repo_name") |
| 73 | + |
| 74 | + # Determine prefixed name |
| 75 | + local prefixed="${primary}-${repo_name}" |
| 76 | + |
| 77 | + # Ensure .machine_readable/ exists |
| 78 | + mkdir -p "$repo_path/.machine_readable" |
| 79 | + |
| 80 | + # Write CLADE.a2ml |
| 81 | + cat > "$repo_path/.machine_readable/CLADE.a2ml" <<CLADE_EOF |
| 82 | +# SPDX-License-Identifier: PMPL-1.0-or-later |
| 83 | +# Clade declaration — part of the gv-clade-index registry |
| 84 | +# See: https://github.com/hyperpolymath/gv-clade-index |
| 85 | +
|
| 86 | +[identity] |
| 87 | +uuid = "$uuid" |
| 88 | +primary-forge = "github" |
| 89 | +primary-owner = "hyperpolymath" |
| 90 | +canonical-name = "$repo_name" |
| 91 | +prefixed-name = "$prefixed" |
| 92 | +
|
| 93 | +[clade] |
| 94 | +primary = "$primary" |
| 95 | +secondary = $secondary |
| 96 | +assigned = "2026-03-16" |
| 97 | +rationale = "$description" |
| 98 | +
|
| 99 | +[forges] |
| 100 | +github = "hyperpolymath/$repo_name" |
| 101 | +gitlab = "hyperpolymath/$repo_name" |
| 102 | +bitbucket = "hyperpolymath/$repo_name" |
| 103 | +
|
| 104 | +[lineage] |
| 105 | +type = "$lineage" |
| 106 | +parent = "$parent" |
| 107 | +born = "2026-03-16" |
| 108 | +CLADE_EOF |
| 109 | + |
| 110 | + if [[ "$DRY_RUN" == "--dry-run" ]]; then |
| 111 | + echo "DRY-RUN: would deploy to $repo_name (clade: $primary)" |
| 112 | + rm "$repo_path/.machine_readable/CLADE.a2ml" |
| 113 | + ((SUCCESS++)) |
| 114 | + return |
| 115 | + fi |
| 116 | + |
| 117 | + # Git add, commit, push |
| 118 | + cd "$repo_path" |
| 119 | + git add .machine_readable/CLADE.a2ml |
| 120 | + if git diff --cached --quiet; then |
| 121 | + echo "SKIP (no changes): $repo_name" |
| 122 | + ((SKIPPED++)) |
| 123 | + return |
| 124 | + fi |
| 125 | + |
| 126 | + git commit -m "$COMMIT_MSG" --quiet 2>/dev/null |
| 127 | + if git push --quiet 2>/dev/null; then |
| 128 | + echo "OK: $repo_name (clade: $primary)" |
| 129 | + ((SUCCESS++)) |
| 130 | + else |
| 131 | + echo "FAIL (push): $repo_name" |
| 132 | + ((FAILED++)) |
| 133 | + fi |
| 134 | + cd "$REPOS_DIR/gv-clade-index" |
| 135 | +} |
| 136 | + |
| 137 | +echo "=== gv-clade-index Phase 1: Deploy CLADE.a2ml ===" |
| 138 | +echo "Seed file: $SEED_FILE" |
| 139 | +echo "Repos dir: $REPOS_DIR" |
| 140 | +[[ "$DRY_RUN" == "--dry-run" ]] && echo "MODE: DRY RUN" |
| 141 | +echo "" |
| 142 | + |
| 143 | +while IFS=$'\t' read -r name primary secondary lineage parent description; do |
| 144 | + deploy_clade "$name" "$primary" "$secondary" "$lineage" "$parent" "$description" |
| 145 | +done < <(parse_repos) |
| 146 | + |
| 147 | +echo "" |
| 148 | +echo "=== Summary ===" |
| 149 | +echo "Success: $SUCCESS" |
| 150 | +echo "Already: $ALREADY" |
| 151 | +echo "Skipped: $SKIPPED" |
| 152 | +echo "Failed: $FAILED" |
0 commit comments