106 lines
3.3 KiB
Bash
Executable File
106 lines
3.3 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
#
|
|
# setup.sh — bootstrap entrypoint.
|
|
# Detects distro/arch, lists modular steps, asks y/N per step, runs them.
|
|
#
|
|
# Flags:
|
|
# --yes run all steps without prompting
|
|
# --only NAME run only the step matching NAME
|
|
# --skip NAME run all steps except NAME
|
|
# --create-user force creating a sudo user (otherwise Arch auto-creates, Debian asks)
|
|
# --username NAME override the sudo user name (default: mk)
|
|
# -h|--help usage
|
|
|
|
set -euo pipefail
|
|
|
|
# Default config target = whoever is running this. The create-user step
|
|
# (05-create-user) may override these to point at a freshly-created sudoer.
|
|
export TARGET_USER="$USER"
|
|
export TARGET_HOME="$HOME"
|
|
|
|
BOOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
|
|
# shellcheck disable=SC1091
|
|
source "$BOOT_DIR/lib/detect.sh"
|
|
source "$BOOT_DIR/lib/log.sh"
|
|
source "$BOOT_DIR/lib/prompt.sh"
|
|
|
|
# helper: resolve the target user's real home even when we're root operating
|
|
# on a created user (whose home isn't $HOME).
|
|
target_home() { getent passwd "${TARGET_USER:-$USER}" | cut -d: -f6; }
|
|
|
|
ALL=0; ONLY=""; SKIP=""; CREATE_USER=0; USERNAME_ARG=""
|
|
while (( $# )); do
|
|
case "$1" in
|
|
--yes|-y) ALL=1; shift ;;
|
|
--only) ONLY="${2:-}"; shift 2 ;;
|
|
--skip) SKIP="${2:-}"; shift 2 ;;
|
|
--create-user) CREATE_USER=1; shift ;;
|
|
--username) USERNAME_ARG="${2:-}"; shift 2 ;;
|
|
-h|--help)
|
|
grep -E '^# --' "$0" | sed 's/^# //'
|
|
exit 0 ;;
|
|
*) echo "unknown arg: $1" >&2; shift ;;
|
|
esac
|
|
done
|
|
export CREATE_USER USERNAME_ARG
|
|
|
|
# ---------------------------------------------------------------- collect steps
|
|
NAMES=(); DESCS=(); RUNS=()
|
|
for f in "$BOOT_DIR"/modules/*.sh; do
|
|
step_name=""; step_desc=""; step_run=""
|
|
# shellcheck disable=SC1090
|
|
source "$f"
|
|
[[ -z "$step_name" ]] && continue
|
|
NAMES+=("$step_name")
|
|
DESCS+=("$step_desc")
|
|
RUNS+=("$step_run")
|
|
done
|
|
|
|
# ----------------------------------------------------------------- print plan
|
|
echo
|
|
printf 'Detected: \033[1mdistro\033[0m=%s \033[1march\033[0m=%s \033[1muser\033[0m=%s\n' "$DISTRO" "$ARCH" "$USER"
|
|
echo
|
|
echo "Steps:"
|
|
for i in "${!NAMES[@]}"; do
|
|
printf ' [%02d] %-12s — %s\n' "$((i+1))" "${NAMES[$i]}" "${DESCS[$i]}"
|
|
done
|
|
echo
|
|
|
|
# ----------------------------------------------------------------- decide run
|
|
run_step() { # name
|
|
local n="$1" i
|
|
for i in "${!NAMES[@]}"; do
|
|
if [[ "${NAMES[$i]}" == "$n" ]]; then
|
|
echo; echo "── ${NAMES[$i]} ──────────────────────────────────────────────"
|
|
# shellcheck disable=SCSC2086
|
|
"${RUNS[$i]}"
|
|
return $?
|
|
fi
|
|
done
|
|
err "no step named '$n'"; return 1
|
|
}
|
|
|
|
if [[ -n "$ONLY" ]]; then
|
|
run_step "$ONLY"
|
|
elif (( ALL )); then
|
|
for n in "${NAMES[@]}"; do
|
|
[[ -n "$SKIP" && "$n" == "$SKIP" ]] && continue
|
|
run_step "$n"
|
|
done
|
|
else
|
|
for i in "${!NAMES[@]}"; do
|
|
local_run=1
|
|
[[ -n "$SKIP" && "${NAMES[$i]}" == "$SKIP" ]] && local_run=0
|
|
if (( local_run )) && yn "Run step [$(printf %02d $((i+1)))] ${NAMES[$i]}?" y; then
|
|
run_step "${NAMES[$i]}" || warn "step ${NAMES[$i]} had an error (continuing)"
|
|
else
|
|
echo " skip ${NAMES[$i]}"
|
|
fi
|
|
done
|
|
fi
|
|
|
|
echo
|
|
ok "bootstrap done."
|
|
echo " re-run any step: bash $BOOT_DIR/setup.sh --only <name>"
|
|
echo " run everything: bash $BOOT_DIR/setup.sh --yes" |