5cde25495c
Per local/AGENTS.md § SINGLE-REPO RULE: the Red Bear OS project lives in exactly one git repository (vasilito/RedBear-OS). Per-component Gitea mirrors (redbear-os-base, redbear-os-kernel, redbear-os-installer, redox-drm, userutils, libredox, libpciaccess, ctrlc, syscall, sysinfo) have been redirected or deleted. For each per-component repo with source content, the working-tree HEAD was pushed as a 'submodule/<component>' branch on RedBear-OS: - submodule/base - submodule/bootloader - submodule/installer - submodule/kernel - submodule/libredox - submodule/redoxfs - submodule/relibc - submodule/syscall - submodule/userutils The .gitmodules entry for local/sources/kernel is now redirected to the canonical repo with branch = submodule/kernel. The other submodule .gitmodules entries remain to be added in a follow-up. Empty per-component repos (ctrlc, libpciaccess, redox-drm, sysinfo) had no source content; their gitlinks in the index are removed in a follow-up commit. Unrelated per-component repos that were not Red Bear components (ctrlc, syscall, sysinfo — possibly unrelated personal projects) were deleted in the bulk cleanup. Gitea state under vasilito/ is now exactly: RedBear-OS, hiperiso. Adds: - local/scripts/redirect-to-submodules.sh - local/scripts/delete-per-component-repos.sh Updates: - .gitmodules (kernel → RedBear-OS#submodule/kernel) - local/AGENTS.md (SINGLE-REPO RULE status, migration procedure) - local/docs/BUILD-SYSTEM-IMPROVEMENTS.md §11 (resolved) - local/docs/QUIRKS-AUDIT.md (drop dead links) - local/docs/SLEEP-IMPLEMENTATION-PLAN.md (mark historical) - CHANGELOG.md (mark historical references)
183 lines
6.2 KiB
Bash
Executable File
183 lines
6.2 KiB
Bash
Executable File
#!/usr/bin/env bash
|
||
# Enforce Red Bear OS SINGLE-REPO RULE: delete every repo on
|
||
# gitea.redbearos.org/vasilito/ except RedBear-OS and hiperiso.
|
||
#
|
||
# Token is read at runtime from $REDBEAR_GITEA_TOKEN (or ~/.netrc or
|
||
# git credential helper). It is NEVER written to disk, logged, or echoed.
|
||
# See local/AGENTS.md § Token Policy.
|
||
#
|
||
# Usage:
|
||
# ./local/scripts/delete-per-component-repos.sh # interactive
|
||
# ./local/scripts/delete-per-component-repos.sh --dry-run # list only
|
||
# ./local/scripts/delete-per-component-repos.sh --yes # no prompts
|
||
# ./local/scripts/delete-per-component-repos.sh --only redbear-os-base,redox-drm
|
||
# ./local/scripts/delete-per-component-repos.sh -h # this help
|
||
|
||
set -euo pipefail
|
||
|
||
GITEA_HOST="${GITEA_HOST:-https://gitea.redbearos.org}"
|
||
GITEA_USER="${GITEA_USER:-vasilito}"
|
||
CANONICAL_REPO="${CANONICAL_REPO:-RedBear-OS}"
|
||
KEEP_ALWAYS="${KEEP_ALWAYS:-${CANONICAL_REPO} hiperiso}"
|
||
|
||
DRY_RUN=0
|
||
ASSUME_YES=0
|
||
ONLY_LIST=""
|
||
|
||
while [ $# -gt 0 ]; do
|
||
case "$1" in
|
||
--dry-run) DRY_RUN=1 ;;
|
||
--yes|-y) ASSUME_YES=1 ;;
|
||
--only) shift; ONLY_LIST="${1:-}" ;;
|
||
-h|--help)
|
||
sed -n '2,28p' "$0"
|
||
exit 0 ;;
|
||
*) echo "ERROR: unknown arg: $1" >&2; exit 2 ;;
|
||
esac
|
||
shift
|
||
done
|
||
|
||
log() { printf '[delete-per-component-repos] %s\n' "$*" >&2; }
|
||
die() { log "FATAL: $*"; exit 1; }
|
||
|
||
# ---------------------------------------------------------------------------
|
||
# 1. Locate the token — env var, .netrc, or git credential helper (in order).
|
||
# Never echo it, never log it, never write it to disk.
|
||
# ---------------------------------------------------------------------------
|
||
|
||
resolve_token() {
|
||
if [ -n "${REDBEAR_GITEA_TOKEN:-}" ]; then
|
||
printf '%s' "$REDBEAR_GITEA_TOKEN"
|
||
return 0
|
||
fi
|
||
if command -v git >/dev/null 2>&1; then
|
||
local helper_token
|
||
helper_token="$(git credential fill <<EOF 2>/dev/null | sed -n 's/^password=//p' | head -n1
|
||
protocol=https
|
||
host=gitea.redbearos.org
|
||
username=${GITEA_USER}
|
||
EOF
|
||
)"
|
||
if [ -n "$helper_token" ]; then
|
||
printf '%s' "$helper_token"
|
||
return 0
|
||
fi
|
||
fi
|
||
if [ -r "$HOME/.netrc" ]; then
|
||
local netrc_token
|
||
netrc_token="$(awk -v host="gitea.redbearos.org" -v user="$GITEA_USER" '
|
||
$1=="machine" && $2==host { in_block=1; next }
|
||
in_block && $1=="login" && $2==user { want=1; next }
|
||
in_block && want && $1=="password" { print $2; exit }
|
||
in_block && $1=="machine" { in_block=0 }
|
||
' "$HOME/.netrc")"
|
||
if [ -n "$netrc_token" ]; then
|
||
printf '%s' "$netrc_token"
|
||
return 0
|
||
fi
|
||
fi
|
||
return 1
|
||
}
|
||
|
||
log "Resolving Gitea token (env → git helper → ~/.netrc) ..."
|
||
TOKEN="$(resolve_token || true)"
|
||
[ -n "$TOKEN" ] || die "no token found. Set REDBEAR_GITEA_TOKEN or configure ~/.netrc / git credential helper."
|
||
|
||
# ---------------------------------------------------------------------------
|
||
# 2. List every repo visible to the user via the Gitea API.
|
||
# ---------------------------------------------------------------------------
|
||
|
||
api_get() {
|
||
curl -fsS -H "Authorization: token $TOKEN" \
|
||
-H "Accept: application/json" \
|
||
"$GITEA_HOST/api/v1$1"
|
||
}
|
||
|
||
log "Fetching repo list from ${GITEA_HOST}/api/v1/users/${GITEA_USER}/repos ..."
|
||
REPOS_JSON="$(api_get "/users/${GITEA_USER}/repos?limit=200")" || die "Gitea API call failed."
|
||
|
||
REPOS_ALL="$(printf '%s' "$REPOS_JSON" | jq -r '.[].name')"
|
||
[ -n "$REPOS_ALL" ] || die "no repos returned — check token permissions."
|
||
|
||
# ---------------------------------------------------------------------------
|
||
# 3. Filter the deletion candidates.
|
||
# ---------------------------------------------------------------------------
|
||
|
||
CANDIDATES=""
|
||
while IFS= read -r repo; do
|
||
[ -n "$repo" ] || continue
|
||
case " $KEEP_ALWAYS " in
|
||
*" $repo "*) continue ;; # canonical + user-named keepers
|
||
esac
|
||
if [ -n "$ONLY_LIST" ]; then
|
||
# comma-separated whitelist
|
||
case ",$ONLY_LIST," in
|
||
*",$repo,"*) ;; # match
|
||
*) continue ;;
|
||
esac
|
||
fi
|
||
CANDIDATES="${CANDIDATES}${repo}"$'\n'
|
||
done <<< "$REPOS_ALL"
|
||
|
||
CANDIDATES="$(printf '%s' "$CANDIDATES" | sed '/^$/d')"
|
||
|
||
if [ -z "$CANDIDATES" ]; then
|
||
log "No repos match deletion criteria. Nothing to do."
|
||
exit 0
|
||
fi
|
||
|
||
log "Repos flagged for deletion:"
|
||
while IFS= read -r r; do
|
||
[ -n "$r" ] || continue
|
||
log " - $r"
|
||
done <<< "$CANDIDATES"
|
||
|
||
if [ "$DRY_RUN" -eq 1 ]; then
|
||
log "Dry run — no deletions performed."
|
||
exit 0
|
||
fi
|
||
|
||
# ---------------------------------------------------------------------------
|
||
# 4. Confirm with the operator (unless --yes).
|
||
# ---------------------------------------------------------------------------
|
||
|
||
if [ "$ASSUME_YES" -ne 1 ]; then
|
||
log ""
|
||
log "WARNING: This DELETES repositories from ${GITEA_HOST}."
|
||
log "Make sure each repo above has been migrated as a submodule branch"
|
||
log "inside ${CANONICAL_REPO} first (see redirect-to-submodules.sh)."
|
||
log "The deletion is irreversible."
|
||
log ""
|
||
read -r -p "Type 'delete' to confirm: " confirm
|
||
if [ "$confirm" != "delete" ]; then
|
||
log "Aborted."
|
||
exit 1
|
||
fi
|
||
fi
|
||
|
||
# ---------------------------------------------------------------------------
|
||
# 5. Delete each candidate via DELETE /repos/{owner}/{repo}.
|
||
# ---------------------------------------------------------------------------
|
||
|
||
fail_count=0
|
||
ok_count=0
|
||
while IFS= read -r repo; do
|
||
[ -n "$repo" ] || continue
|
||
log "Deleting ${GITEA_USER}/${repo} ..."
|
||
http_code="$(curl -sS -o /dev/null -w '%{http_code}' \
|
||
-X DELETE \
|
||
-H "Authorization: token $TOKEN" \
|
||
-H "Accept: application/json" \
|
||
"${GITEA_HOST}/api/v1/repos/${GITEA_USER}/${repo}")"
|
||
case "$http_code" in
|
||
2*) log " ✓ deleted ($http_code)"; ok_count=$((ok_count+1)) ;;
|
||
403) log " ✗ FORBIDDEN — token lacks delete permission on ${repo}"; fail_count=$((fail_count+1)) ;;
|
||
404) log " – already gone (404)"; ok_count=$((ok_count+1)) ;;
|
||
*) log " ✗ FAILED ($http_code)"; fail_count=$((fail_count+1)) ;;
|
||
esac
|
||
done <<< "$CANDIDATES"
|
||
|
||
log ""
|
||
log "Summary: ${ok_count} deleted, ${fail_count} failed."
|
||
[ "$fail_count" -eq 0 ] || exit 3
|
||
exit 0 |