Files

248 lines
6.5 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
repo_root="$(cd "${script_dir}/.." && pwd)"
default_repo_url="https://github.com/Qortal/qortal.git"
target_path="${repo_root}/../qortal"
repo_url="${default_repo_url}"
refresh="0"
branch=""
GIT_SUDO_PREFIX=()
run_git() {
"${GIT_SUDO_PREFIX[@]}" git -C "${target_path}" "$@"
}
fail_git_step() {
local step="$1"
echo "Failed during Qortal repo step: ${step}"
exit 1
}
run_git_clone() {
"${GIT_SUDO_PREFIX[@]}" git clone "$@"
}
run_mkdir() {
"${GIT_SUDO_PREFIX[@]}" mkdir -p "$@"
}
enable_git_sudo_if_needed() {
local parent_dir=""
local need_sudo="0"
parent_dir="$(dirname "${target_path}")"
if [[ -d "${target_path}/.git" ]]; then
if [[ ! -w "${target_path}" || ! -w "${target_path}/.git" ]]; then
need_sudo="1"
fi
elif [[ -e "${target_path}" ]]; then
if [[ ! -w "${target_path}" ]]; then
need_sudo="1"
fi
elif [[ ! -w "${parent_dir}" ]]; then
need_sudo="1"
fi
if [[ "${need_sudo}" != "1" ]]; then
return 0
fi
if ! command -v sudo >/dev/null 2>&1; then
echo "Qortal repo path requires elevated filesystem permissions, but sudo is unavailable."
exit 1
fi
if sudo -n true >/dev/null 2>&1; then
GIT_SUDO_PREFIX=(sudo)
echo "Using sudo for Qortal repo filesystem operations in ${target_path}"
return 0
fi
echo "Qortal repo path requires elevated filesystem permissions."
echo "You may be prompted for your sudo password."
if sudo true >/dev/null 2>&1; then
GIT_SUDO_PREFIX=(sudo)
echo "Using sudo for Qortal repo filesystem operations in ${target_path}"
return 0
fi
echo "Unable to obtain sudo for Qortal repo filesystem operations."
exit 1
}
usage() {
cat <<USAGE
Usage: scripts/ensure-qortal-core-repo.sh [options]
Options:
--target-path <path> Target clone path (default: ../qortal relative to repo root)
--repo-url <url> Repo URL to clone (default: https://github.com/Qortal/qortal.git)
--branch <name> Branch to clone/refresh (default: origin default branch)
--refresh Fetch latest from origin and hard-reset to selected branch
-h, --help Show this help
USAGE
}
normalize_repo_url() {
local raw="${1:-}"
local lower
lower="$(echo "${raw}" | tr '[:upper:]' '[:lower:]')"
lower="${lower%.git}"
if [[ "${lower}" == git@github.com:qortal/qortal ]]; then
lower="https://github.com/qortal/qortal"
fi
echo "${lower}"
}
is_primary_qortal_repo_url() {
local normalized
normalized="$(normalize_repo_url "${1:-}")"
[[ "${normalized}" == "https://github.com/qortal/qortal" || "${normalized}" == "http://github.com/qortal/qortal" ]]
}
resolve_path() {
local raw="${1:-}"
if [[ "${raw}" == /* ]]; then
echo "${raw}"
else
echo "${repo_root}/${raw}"
fi
}
while [[ $# -gt 0 ]]; do
case "$1" in
--target-path)
target_path="${2:-}"
shift 2
;;
--target-path=*)
target_path="${1#*=}"
shift
;;
--repo-url)
repo_url="${2:-}"
shift 2
;;
--repo-url=*)
repo_url="${1#*=}"
shift
;;
--refresh)
refresh="1"
shift
;;
--branch)
branch="${2:-}"
shift 2
;;
--branch=*)
branch="${1#*=}"
shift
;;
-h|--help)
usage
exit 0
;;
*)
echo "Unknown argument: $1"
usage
exit 1
;;
esac
done
target_path="$(resolve_path "${target_path}")"
enable_git_sudo_if_needed
if [[ -z "${target_path}" ]]; then
echo "Target path is required."
exit 1
fi
if [[ -n "${branch}" ]] && ! git check-ref-format --branch "${branch}" >/dev/null 2>&1; then
echo "Invalid branch name: ${branch}"
exit 1
fi
run_mkdir "$(dirname "${target_path}")"
if [[ -e "${target_path}" && ! -d "${target_path}/.git" ]]; then
echo "Qortal context exists but is not a git repo: ${target_path}"
echo "Move/remove it, then rerun."
exit 1
fi
if [[ ! -d "${target_path}/.git" ]]; then
if [[ -n "${branch}" ]]; then
echo "Cloning Qortal Core branch '${branch}' into ${target_path}"
run_git_clone --depth 1 --branch "${branch}" --single-branch "${repo_url}" "${target_path}"
else
echo "Cloning Qortal Core from primary repo into ${target_path}"
run_git_clone --depth 1 "${repo_url}" "${target_path}"
fi
else
echo "Using existing Qortal Core repo at ${target_path}"
fi
if [[ "${refresh}" != "1" ]]; then
exit 0
fi
current_origin="$(run_git remote get-url origin 2>/dev/null || true)"
if ! is_primary_qortal_repo_url "${current_origin}"; then
echo "Updating Qortal origin remote to primary repo for refresh (was: ${current_origin:-<none>})"
if run_git remote get-url origin >/dev/null 2>&1; then
run_git remote set-url origin "${repo_url}"
else
run_git remote add origin "${repo_url}"
fi
fi
target_branch="${branch:-}"
echo "Refreshing Qortal Core checkout from primary upstream..."
if [[ -n "${target_branch}" ]]; then
echo "Fetching branch origin/${target_branch}..."
if ! run_git fetch --depth 1 origin "refs/heads/${target_branch}:refs/remotes/origin/${target_branch}"; then
echo "Origin branch not found: ${target_branch}"
exit 1
fi
else
echo "Fetching origin default branch..."
run_git fetch --depth 1 origin
default_branch="$(run_git symbolic-ref --short refs/remotes/origin/HEAD 2>/dev/null | sed 's#^origin/##' || true)"
if [[ -z "${default_branch}" ]]; then
default_branch="$(run_git remote show origin 2>/dev/null | sed -n '/HEAD branch/s/.*: //p' | head -n1 || true)"
fi
if [[ -z "${default_branch}" ]]; then
if run_git show-ref --verify --quiet refs/remotes/origin/main; then
default_branch="main"
elif run_git show-ref --verify --quiet refs/remotes/origin/master; then
default_branch="master"
else
echo "Could not determine default branch from origin for ${target_path}"
exit 1
fi
fi
target_branch="${default_branch}"
fi
if ! run_git show-ref --verify --quiet "refs/remotes/origin/${target_branch}"; then
echo "Origin branch not found: ${target_branch}"
exit 1
fi
echo "Checking out local branch ${target_branch} from origin/${target_branch}..."
run_git checkout -B "${target_branch}" "origin/${target_branch}" || fail_git_step "checkout ${target_branch}"
echo "Resetting working tree to origin/${target_branch}..."
run_git reset --hard "origin/${target_branch}" || fail_git_step "reset --hard origin/${target_branch}"
echo "Cleaning untracked files in ${target_path}..."
run_git clean -fd || fail_git_step "clean -fd"
echo "Qortal Core refreshed to origin/${target_branch}."