set -euo pipefail TOOLS_FILE="$HOME/.dotfiles-tools" # CLI: parse flags PROMPT_DELETE=1 INSTALL_OPTIONAL=0 while [[ $# -gt 0 ]]; do case "$1" in --no-prompt|-n) PROMPT_DELETE=0 shift ;; --prompt|-p) PROMPT_DELETE=1 shift ;; --with-optional|-w) INSTALL_OPTIONAL=1 shift ;; *) break esac done echo ">>> Bootstrapping new Debian-like machine..." # Parse tools from config file parse_tools() { local priority="$1" while IFS='|' read -r name check_cmd install_cmd prio; do [[ "$name" =~ ^#.*$ ]] && continue [[ -z "$name" ]] && continue [[ "$prio" == "$priority" ]] && echo "$name|$check_cmd|$install_cmd" done < "$TOOLS_FILE" } # Install required tools echo ">>> Installing required tools..." sudo apt update while IFS='|' read -r name check_cmd install_cmd prio; do [[ "$prio" != "required" ]] && continue if ! command -v "$name" &> /dev/null && [[ "$prio" == "required" ]]; then echo ">>> Installing $name..." eval "$install_cmd" fi done < "$TOOLS_FILE" # Ask about optional tools if [[ "$INSTALL_OPTIONAL" == "1" ]] || [[ "$PROMPT_DELETE" == "1" ]]; then echo "" echo ">>> Optional tools available:" while IFS='|' read -r name check_cmd install_cmd prio; do [[ "$prio" != "optional" ]] && continue if ! command -v "$name" &> /dev/null; then echo " - $name" fi done < "$TOOLS_FILE" echo "" if [[ "$PROMPT_DELETE" == "1" ]] && [[ -t 1 ]]; then read -r -p "Install optional tools? (y/N): " resp case "$resp" in [Yy]* ) INSTALL_OPTIONAL=1 ;; * ) INSTALL_OPTIONAL=0 ;; esac fi fi if [[ "$INSTALL_OPTIONAL" == "1" ]]; then echo ">>> Installing optional tools..." while IFS='|' read -r name check_cmd install_cmd prio; do [[ "$prio" != "optional" ]] && continue if ! command -v "$name" &> /dev/null; then echo ">>> Installing $name..." eval "$install_cmd" fi done < "$TOOLS_FILE" fi # Clone dotfiles if [ ! -d "$HOME/.dotfiles" ]; then echo ">>> Cloning dotfiles repo..." git clone --bare https://gitea.sjhl.nz/james/dotfiles $HOME/.dotfiles else echo ">>> Dotfiles repo already exists." fi dotfiles() { /usr/bin/git --git-dir="$HOME/.dotfiles/" --work-tree="$HOME" "$@" } echo ">>> Checking out dotfiles..." if ! dotfiles checkout; then echo ">>> Conflicts detected! Handling conflicting dotfiles..." mkdir -p "$HOME/.dotfiles-backup" conflicts=$(dotfiles checkout 2>&1 | grep -E "\s+\." | awk '{print $1}') if [ -n "$conflicts" ]; then if [ "$PROMPT_DELETE" = "0" ]; then while IFS= read -r f; do [ -z "$f" ] && continue mv "$f" "$HOME/.dotfiles-backup/$f" done <<< "$conflicts" else while IFS= read -r f; do [ -z "$f" ] && continue if [ -t 1 ]; then read -r -p "Move '$f' to backup? (y/N): " resp case "$resp" in [Yy]* ) mv "$f" "$HOME/.dotfiles-backup/$f" ;; * ) echo "Skipping '$f'." ;; esac else echo "Non-interactive environment detected; skipping '$f'." fi done <<< "$conflicts" fi fi dotfiles checkout fi dotfiles config --local status.showUntrackedFiles no echo ">>> Done! Bash, kitty, vim, and dotfiles are ready."