Skip to content

Instantly share code, notes, and snippets.

@pascaljp
Last active June 2, 2026 07:03
Show Gist options
  • Select an option

  • Save pascaljp/f3f7a70e2b845445ff286e5637eddde3 to your computer and use it in GitHub Desktop.

Select an option

Save pascaljp/f3f7a70e2b845445ff286e5637eddde3 to your computer and use it in GitHub Desktop.
pascaljp/personal private repository bootstrap installer
#!/bin/sh
set -eu
REPO_URL="${PERSONAL_REPO_URL:-git@github.com:pascaljp/personal.git}"
REPO_REF="${PERSONAL_REF:-main}"
REPO_DIR="${PERSONAL_REPO_DIR:-${HOME}/.local/share/pascaljp/personal}"
log() {
echo "==> $*"
}
have() {
command -v "$1" >/dev/null 2>&1
}
run_sudo() {
if [ "$(id -u)" -eq 0 ]; then
"$@"
return
fi
if have sudo; then
sudo "$@"
return
fi
echo "sudo is required to install missing packages. Install sudo or run as root, then rerun this script." >&2
exit 2
}
install_homebrew() {
if have brew; then
return
fi
if ! have curl; then
echo "curl is required to install Homebrew on macOS." >&2
exit 2
fi
log "Installing Homebrew"
NONINTERACTIVE=1 /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
if [ -x /opt/homebrew/bin/brew ]; then
eval "$(/opt/homebrew/bin/brew shellenv)"
elif [ -x /usr/local/bin/brew ]; then
eval "$(/usr/local/bin/brew shellenv)"
fi
}
install_macos_packages() {
packages=""
have git || packages="${packages} git"
have bash || packages="${packages} bash"
if [ -z "$packages" ]; then
return
fi
install_homebrew
log "Installing missing macOS packages:${packages}"
# shellcheck disable=SC2086
brew install $packages
}
linux_install_command() {
if have apt-get; then
echo "apt"
elif have dnf; then
echo "dnf"
elif have yum; then
echo "yum"
elif have pacman; then
echo "pacman"
elif have zypper; then
echo "zypper"
elif have apk; then
echo "apk"
else
echo ""
fi
}
install_linux_packages() {
packages=""
have git || packages="${packages} git"
have bash || packages="${packages} bash"
if [ -z "$packages" ]; then
return
fi
manager="$(linux_install_command)"
if [ -z "$manager" ]; then
echo "Could not find a supported Linux package manager. Install git and bash manually, then rerun this script." >&2
exit 2
fi
log "Installing missing Linux packages with ${manager}:${packages}"
case "$manager" in
apt)
run_sudo apt-get update
# shellcheck disable=SC2086
run_sudo apt-get install -y $packages
;;
dnf)
# shellcheck disable=SC2086
run_sudo dnf install -y $packages
;;
yum)
# shellcheck disable=SC2086
run_sudo yum install -y $packages
;;
pacman)
# shellcheck disable=SC2086
run_sudo pacman -Sy --needed --noconfirm $packages
;;
zypper)
# shellcheck disable=SC2086
run_sudo zypper --non-interactive install $packages
;;
apk)
# shellcheck disable=SC2086
run_sudo apk add $packages
;;
esac
}
ensure_basic_tools() {
if have git && have bash; then
return
fi
case "$(uname -s)" in
Darwin)
install_macos_packages
;;
Linux)
install_linux_packages
;;
*)
echo "Unsupported OS: $(uname -s). Install git and bash manually, then rerun this script." >&2
exit 2
;;
esac
if ! have git || ! have bash; then
echo "Failed to install git or bash. Install them manually, then rerun this script." >&2
exit 2
fi
}
ensure_clean_existing_checkout() {
if [ ! -d "${REPO_DIR}/.git" ]; then
return
fi
if ! git -C "$REPO_DIR" diff --quiet || ! git -C "$REPO_DIR" diff --cached --quiet; then
echo "Existing checkout has local changes: ${REPO_DIR}" >&2
echo "Commit, stash, or inspect those changes before rerunning this installer." >&2
exit 2
fi
}
clone_or_update_repo() {
if [ -d "${REPO_DIR}/.git" ]; then
log "Updating ${REPO_DIR}"
ensure_clean_existing_checkout
git -C "$REPO_DIR" remote set-url origin "$REPO_URL"
git -C "$REPO_DIR" fetch origin "$REPO_REF"
if git -C "$REPO_DIR" show-ref --verify --quiet "refs/heads/${REPO_REF}"; then
git -C "$REPO_DIR" checkout "$REPO_REF"
else
git -C "$REPO_DIR" checkout -b "$REPO_REF" "origin/${REPO_REF}"
fi
current_head="$(git -C "$REPO_DIR" rev-parse HEAD)"
remote_head="$(git -C "$REPO_DIR" rev-parse "origin/${REPO_REF}")"
if [ "$current_head" = "$remote_head" ]; then
return
fi
if git -C "$REPO_DIR" merge-base --is-ancestor "$current_head" "$remote_head"; then
git -C "$REPO_DIR" merge --ff-only "origin/${REPO_REF}"
return
fi
cat >&2 <<EOF
Existing checkout has local commits or has diverged from origin: ${REPO_DIR}
Inspect the checkout manually before rerunning this installer.
EOF
exit 2
fi
if [ -e "$REPO_DIR" ]; then
echo "Target path exists but is not a git checkout: ${REPO_DIR}" >&2
echo "Move it aside or set PERSONAL_REPO_DIR to another path, then rerun this installer." >&2
exit 2
fi
log "Cloning private repository into ${REPO_DIR}"
mkdir -p "$(dirname "$REPO_DIR")"
if ! git clone --branch "$REPO_REF" "$REPO_URL" "$REPO_DIR"; then
cat >&2 <<EOF
Failed to clone ${REPO_URL}.
This repository is private. Configure GitHub SSH access for this machine, then rerun:
ssh -T git@github.com
Alternatively set PERSONAL_REPO_URL to another authenticated clone URL.
EOF
exit 2
fi
}
ensure_basic_tools
clone_or_update_repo
log "Running repository bootstrap"
bash "${REPO_DIR}/scripts/bootstrap-home.sh"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment