#!/usr/bin/env bash set -euo pipefail MOSAIC_HOME="${MOSAIC_HOME:-$HOME/.config/mosaic}" BOOTSTRAP_CMD="$MOSAIC_HOME/bin/mosaic-bootstrap-repo" roots=("$HOME/src") apply=0 usage() { cat < Add a search root (repeatable). Default: $HOME/src --apply Execute upgrades. Without this flag, script is dry-run. -h, --help Show this help USAGE } while [[ $# -gt 0 ]]; do case "$1" in --root) [[ $# -lt 2 ]] && { echo "Missing value for --root" >&2; exit 1; } roots+=("$2") shift 2 ;; --apply) apply=1 shift ;; -h|--help) usage exit 0 ;; *) echo "Unknown argument: $1" >&2 usage >&2 exit 1 ;; esac done if [[ ! -x "$BOOTSTRAP_CMD" ]]; then echo "[mosaic-upgrade] Missing bootstrap command: $BOOTSTRAP_CMD" >&2 echo "[mosaic-upgrade] Install/refresh framework first: ~/.config/mosaic/install.sh" >&2 exit 1 fi # De-duplicate roots while preserving order. uniq_roots=() for r in "${roots[@]}"; do skip=0 for e in "${uniq_roots[@]}"; do [[ "$r" == "$e" ]] && { skip=1; break; } done [[ $skip -eq 0 ]] && uniq_roots+=("$r") done candidates=() for root in "${uniq_roots[@]}"; do [[ -d "$root" ]] || continue while IFS= read -r marker; do repo_dir="$(dirname "$(dirname "$marker")")" if [[ -d "$repo_dir/.git" ]]; then candidates+=("$repo_dir") fi done < <(find "$root" -type f -path '*/.mosaic/README.md' 2>/dev/null) done # De-duplicate repos while preserving order. repos=() for repo in "${candidates[@]}"; do skip=0 for existing in "${repos[@]}"; do [[ "$repo" == "$existing" ]] && { skip=1; break; } done [[ $skip -eq 0 ]] && repos+=("$repo") done count_total=${#repos[@]} count_ok=0 count_fail=0 mode="DRY-RUN" [[ $apply -eq 1 ]] && mode="APPLY" echo "[mosaic-upgrade] Mode: $mode" echo "[mosaic-upgrade] Roots: ${uniq_roots[*]}" echo "[mosaic-upgrade] Linked repos found: $count_total" if [[ $count_total -eq 0 ]]; then exit 0 fi for repo in "${repos[@]}"; do if [[ $apply -eq 1 ]]; then if "$BOOTSTRAP_CMD" "$repo" --force >/dev/null; then echo "[mosaic-upgrade] upgraded: $repo" count_ok=$((count_ok + 1)) else echo "[mosaic-upgrade] FAILED: $repo" >&2 count_fail=$((count_fail + 1)) fi else echo "[mosaic-upgrade] would upgrade: $repo" fi done if [[ $apply -eq 1 ]]; then echo "[mosaic-upgrade] complete: ok=$count_ok failed=$count_fail total=$count_total" [[ $count_fail -gt 0 ]] && exit 1 fi