#!/usr/bin/env bash
# pgh-experimental + pgh-experimental-sidecar installer (bare runtime).
#
# Bare runtime is bundled inside each tarball — NO system node, npm, or
# bare required on the target machine. Works on a fresh install.
#
# Usage:
# curl -sSfL https://7rnx.net/git/bootstrap/install.sh | sh
# curl -sSfL https://7rnx.net/git/bootstrap/install.sh | sh -s -- --prefix ~/opt
#
# Flags:
# --prefix <dir> install prefix (default: ~/.local)
# --base <url> override download base URL
# --from-dir <path> use local tarballs from <path> (skip download)
# --no-path-warn skip the PATH-not-set warning
#
# After install:
# pgh-experimental --help
# pgh-experimental init # one-time
# pgh-experimental app install pgh://<reg>/pear-git-v3-experimental
# pgh-experimental app start pear-git-v3-experimental
#
# NOTE: This is the version-controlled SOURCE of the bootstrap installer
# (the served copy lives in the daemon's <storage>/bootstrap/ dir). Keep
# them in sync when changing this.
set -eu
DEFAULT_BASE="${PGH_DOWNLOAD_BASE:-https://7rnx.net/git/bootstrap}"
PREFIX="${HOME}/.local"
BASE=""
LOCAL_DIR=""
SKIP_PATH_WARN=0
while [ $# -gt 0 ]; do
case "$1" in
--prefix) PREFIX="$2"; shift 2 ;;
--base) BASE="$2"; shift 2 ;;
--from-dir) LOCAL_DIR="$2"; shift 2 ;;
--no-path-warn) SKIP_PATH_WARN=1; shift ;;
-h|--help) sed -n '2,21p' "$0"; exit 0 ;;
*) echo "unknown flag: $1" >&2; exit 1 ;;
esac
done
BASE="${BASE:-$DEFAULT_BASE}"
SHARE_DIR="${PREFIX}/share/pgh-experimental"
BIN_DIR="${PREFIX}/bin"
# Detect platform
os_raw="$(uname -s)"
case "$os_raw" in
Linux) OS="linux" ;;
Darwin) OS="darwin" ;;
*) echo "unsupported OS: $os_raw" >&2; exit 1 ;;
esac
arch_raw="$(uname -m)"
case "$arch_raw" in
x86_64|amd64) ARCH="x64" ;;
aarch64|arm64) ARCH="arm64" ;;
*) echo "unsupported arch: $arch_raw" >&2; exit 1 ;;
esac
LABEL="${OS}-${ARCH}"
PKGS="pgh-experimental pgh-experimental-sidecar"
echo "pgh-experimental installer (bare runtime)"
echo " target: ${LABEL}"
echo " prefix: ${PREFIX}"
echo
fetch () {
local url="$1" out="$2"
if [ -n "$LOCAL_DIR" ]; then
cp "${LOCAL_DIR}/$(basename "$url")" "$out"
elif command -v curl >/dev/null 2>&1; then
curl -sSfL "$url" -o "$out"
elif command -v wget >/dev/null 2>&1; then
wget -qO "$out" "$url"
else
echo "neither curl nor wget available — install one and rerun" >&2
exit 1
fi
}
mkdir -p "$SHARE_DIR" "$BIN_DIR"
for PKG in $PKGS; do
TARBALL="${PKG}-bootstrap-bare-${LABEL}.tar.gz"
STAGE="${SHARE_DIR}/${PKG}"
TMP="$(mktemp -t "${TARBALL}.XXXXXX")"
echo "${PKG}:"
echo " fetching ${BASE}/${TARBALL}"
fetch "${BASE}/${TARBALL}" "$TMP"
echo " extracting to ${STAGE}"
rm -rf "${STAGE}.new" 2>/dev/null || true
mkdir -p "${STAGE}.new"
tar -xzf "$TMP" -C "${STAGE}.new"
rm -f "$TMP"
# Tarball extracts to <stage>.new/<pkg>-bootstrap-bare/; move it into place.
INNER="${STAGE}.new/${PKG}-bootstrap-bare"
if [ ! -d "$INNER" ]; then
echo " unexpected tarball layout in ${STAGE}.new" >&2
ls -la "${STAGE}.new" >&2
exit 1
fi
if [ -d "$STAGE" ]; then
# Existing install: replace atomically by swap-rename.
mv "$STAGE" "${STAGE}.old"
fi
mv "$INNER" "$STAGE"
rm -rf "${STAGE}.new" "${STAGE}.old" 2>/dev/null || true
# Symlink the launcher (bare shell wrapper).
ln -sf "${STAGE}/bin/${PKG}" "${BIN_DIR}/${PKG}"
chmod +x "${STAGE}/bin/${PKG}"
echo " installed ${BIN_DIR}/${PKG}"
echo
done
# PATH check
if [ "$SKIP_PATH_WARN" -ne 1 ]; then
case ":$PATH:" in
*":${BIN_DIR}:"*) : ;;
*)
echo "WARNING: ${BIN_DIR} is not on your PATH."
echo "Add this line to your shell rc:"
echo
echo " export PATH=\"${BIN_DIR}:\$PATH\""
echo
;;
esac
fi
# Register the sidecar as a MANAGED app (supervised + autostart) instead of a
# bare `&` process — so it survives crashes/reboots and can be driven via
# `pgh-experimental app {start,stop,restart}` and `app boot`. Without this the
# sidecar is unmanaged: it dies and nothing respawns it, and it can't be
# `app start`ed (no .pgh-install.json). Route to the experimental sidecar by
# sourcing its env if present (set up out-of-band on experimental machines).
if [ -f "${HOME}/.pgh-experimental.env" ]; then . "${HOME}/.pgh-experimental.env"; fi
echo "Registering pgh-experimental-sidecar as a managed app..."
if "${BIN_DIR}/pgh-experimental" app adopt "${SHARE_DIR}/pgh-experimental-sidecar" --name pgh-experimental-sidecar >/dev/null 2>&1 \
&& "${BIN_DIR}/pgh-experimental" app autostart pgh-experimental-sidecar on >/dev/null 2>&1; then
echo " adopted + autostart enabled"
else
echo " (could not adopt automatically — run:"
echo " pgh-experimental app adopt ${SHARE_DIR}/pgh-experimental-sidecar --name pgh-experimental-sidecar"
echo " pgh-experimental app autostart pgh-experimental-sidecar on )"
fi
cat <<EOF
Installed.
Next steps:
pgh-experimental app start pgh-experimental-sidecar # bring up the (adopted) sidecar
pgh-experimental init # one-time local registry setup
pgh-experimental app install pgh://<registry-key>/pear-git-v3-experimental
pgh-experimental app start pear-git-v3-experimental
EOF