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)
185 lines
6.7 KiB
Bash
Executable File
185 lines
6.7 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Redirect each existing per-component Gitea repo into a branch on the
|
|
# canonical RedBear-OS repo, then point the matching git submodule(s) at
|
|
# that branch. After this, the per-component Gitea repos can be deleted
|
|
# without breaking any submodule resolution.
|
|
#
|
|
# What this script does, for each per-component Gitea repo:
|
|
# 1. Fetches the repo's HEAD into a temp clone.
|
|
# 2. Pushes that HEAD as a `submodule/<component>` branch on RedBear-OS.
|
|
# 3. Rewrites `.gitmodules` so any submodule entry pointing at the
|
|
# per-component URL now points at RedBear-OS with the new branch.
|
|
#
|
|
# What it does NOT do:
|
|
# - It does not move source content between repositories (source already
|
|
# lives in the per-component repo; we just push it under a new branch
|
|
# name in the canonical repo).
|
|
# - It does not delete the per-component Gitea repos. Use
|
|
# delete-per-component-repos.sh afterwards.
|
|
# - It does not touch recipe.toml files (none reference the per-component
|
|
# URLs as far as the current tree shows).
|
|
#
|
|
# Token is read at runtime from $REDBEAR_GITEA_TOKEN (or ~/.netrc). It is
|
|
# NEVER written to disk, logged, or echoed.
|
|
|
|
set -euo pipefail
|
|
|
|
GITEA_HOST="${GITEA_HOST:-https://gitea.redbearos.org}"
|
|
GITEA_USER="${GITEA_USER:-vasilito}"
|
|
CANONICAL_REPO="${CANONICAL_REPO:-RedBear-OS}"
|
|
CANONICAL_URL="${CANONICAL_URL:-${GITEA_HOST}/${GITEA_USER}/${CANONICAL_REPO}.git}"
|
|
|
|
# Per-component Gitea repos to redirect. The actual Gitea slug is
|
|
# discovered at runtime via the API, so this list contains the canonical
|
|
# component names only.
|
|
DEFAULT_COMPONENTS=(base kernel installer redox-drm userutils libredox libpciaccess)
|
|
|
|
DRY_RUN=0
|
|
SKIP_PUSH=0
|
|
COMPONENTS=()
|
|
|
|
while [ $# -gt 0 ]; do
|
|
case "$1" in
|
|
--dry-run) DRY_RUN=1 ;;
|
|
--skip-push) SKIP_PUSH=1 ;;
|
|
-h|--help) sed -n '2,28p' "$0"; exit 0 ;;
|
|
--) shift; while [ $# -gt 0 ]; do COMPONENTS+=("$1"); shift; done ;;
|
|
-*) echo "ERROR: unknown arg: $1" >&2; exit 2 ;;
|
|
*) COMPONENTS+=("$1") ;;
|
|
esac
|
|
shift
|
|
done
|
|
|
|
[ "${#COMPONENTS[@]}" -gt 0 ] || COMPONENTS=("${DEFAULT_COMPONENTS[@]}")
|
|
|
|
log() { printf '[redirect-to-submodules] %s\n' "$*" >&2; }
|
|
die() { log "FATAL: $*"; exit 1; }
|
|
|
|
resolve_token() {
|
|
if [ -n "${REDBEAR_GITEA_TOKEN:-}" ]; then
|
|
printf '%s' "$REDBEAR_GITEA_TOKEN"
|
|
return 0
|
|
fi
|
|
if [ -r "$HOME/.netrc" ]; then
|
|
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"
|
|
fi
|
|
}
|
|
|
|
TOKEN="$(resolve_token || true)"
|
|
[ -n "$TOKEN" ] || die "no token found. Set REDBEAR_GITEA_TOKEN or configure ~/.netrc."
|
|
|
|
command -v git >/dev/null || die "git not found in PATH"
|
|
command -v jq >/dev/null || die "jq not found in PATH"
|
|
git rev-parse --is-inside-work-tree >/dev/null 2>&1 || die "must be run from inside the ${CANONICAL_REPO} working tree"
|
|
|
|
current_branch="$(git rev-parse --abbrev-ref HEAD)"
|
|
log "Working tree : $(git rev-parse --show-toplevel)"
|
|
log "Branch : ${current_branch}"
|
|
log "Canonical URL: ${CANONICAL_URL}"
|
|
|
|
if [ "$DRY_RUN" -eq 0 ] && [ "$SKIP_PUSH" -eq 0 ]; then
|
|
log ""
|
|
log "This script PUSHES branches to ${CANONICAL_URL} and modifies .gitmodules."
|
|
read -r -p "Type 'redirect' to confirm: " confirm
|
|
[ "$confirm" = "redirect" ] || { log "Aborted."; exit 1; }
|
|
fi
|
|
|
|
api_get() {
|
|
curl -fsS -H "Authorization: token $TOKEN" \
|
|
-H "Accept: application/json" \
|
|
"$GITEA_HOST/api/v1$1"
|
|
}
|
|
|
|
log "Verifying Gitea credentials ..."
|
|
api_get "/user" >/dev/null || die "token rejected by Gitea API"
|
|
|
|
log "Fetching Gitea repo list ..."
|
|
REPO_NAMES_API="$(api_get "/users/${GITEA_USER}/repos?limit=200" | jq -r '.[].name')"
|
|
[ -n "${REPO_NAMES_API}" ] || die "no repos returned — check token permissions."
|
|
|
|
find_slug() {
|
|
local component="$1"
|
|
# Try the legacy redbear-os-<component> convention first, then the bare name.
|
|
for candidate in "redbear-os-${component}" "${component}"; do
|
|
if printf '%s\n' "${REPO_NAMES_API}" | grep -qx "${candidate}"; then
|
|
printf '%s' "${candidate}"
|
|
return 0
|
|
fi
|
|
done
|
|
return 1
|
|
}
|
|
|
|
redirect_component() {
|
|
local component="$1"
|
|
local gitea_slug
|
|
if ! gitea_slug="$(find_slug "${component}")"; then
|
|
log ""
|
|
log "=== ${component} ==="
|
|
die "no Gitea repo found for component '${component}' (tried: redbear-os-${component}, ${component})"
|
|
fi
|
|
local branch="submodule/${component}"
|
|
|
|
log ""
|
|
log "=== ${component} ==="
|
|
log " source Gitea repo : ${gitea_slug}"
|
|
log " target branch : ${branch}"
|
|
|
|
if [ "$DRY_RUN" -eq 1 ]; then
|
|
log " [dry-run] would fetch HEAD, push as ${branch}, rewrite .gitmodules"
|
|
return 0
|
|
fi
|
|
|
|
local tmp
|
|
tmp="$(mktemp -d)"
|
|
trap 'rm -rf "$tmp"' EXIT
|
|
|
|
log " cloning ${gitea_slug} ..."
|
|
local src_url="https://${TOKEN}@${GITEA_HOST#https://}/${GITEA_USER}/${gitea_slug}.git"
|
|
git clone --quiet "${src_url}" "${tmp}/src" \
|
|
|| die "clone failed for ${gitea_slug}"
|
|
|
|
local src_default
|
|
src_default="$(git -C "${tmp}/src" symbolic-ref --short HEAD 2>/dev/null || echo "")"
|
|
local src_commit_count
|
|
src_commit_count="$(git -C "${tmp}/src" rev-list --all --count 2>/dev/null || echo 0)"
|
|
if [ -z "${src_commit_count}" ] || [ "${src_commit_count}" = "0" ]; then
|
|
log " source repo is empty (0 commits) — skipping push"
|
|
rm -rf "${tmp}"
|
|
trap - EXIT
|
|
log " ✓ ${component} (no-op)"
|
|
return 0
|
|
fi
|
|
log " source default branch: ${src_default} (${src_commit_count} commits)"
|
|
log " pushing ${branch} to ${CANONICAL_URL} ..."
|
|
local push_url="https://${TOKEN}@${GITEA_HOST#https://}/${GITEA_USER}/${CANONICAL_REPO}.git"
|
|
git -C "${tmp}/src" push --quiet "${push_url}" "refs/heads/${src_default}:refs/heads/${branch}" \
|
|
|| die "push failed for ${branch}"
|
|
|
|
log " rewriting .gitmodules ..."
|
|
if grep -q "url = .*${gitea_slug}\.git" .gitmodules 2>/dev/null; then
|
|
sed -i.bak "s|url = .*${gitea_slug}\.git|url = ${CANONICAL_URL}|" .gitmodules
|
|
sed -i "s|^ branch = .*| branch = ${branch}|" .gitmodules
|
|
rm -f .gitmodules.bak
|
|
log " updated"
|
|
else
|
|
log " no .gitmodules entry references ${gitea_slug}; left untouched"
|
|
fi
|
|
|
|
rm -rf "${tmp}"
|
|
trap - EXIT
|
|
log " ✓ ${component} redirected"
|
|
}
|
|
|
|
for c in "${COMPONENTS[@]}"; do
|
|
redirect_component "$c"
|
|
done
|
|
|
|
log ""
|
|
log "Done. Verify with: git submodule status"
|
|
log "Then run ./local/scripts/delete-per-component-repos.sh to delete the"
|
|
log "now-unused per-component repos on Gitea." |