This commit is contained in:
MangoPig
2026-06-01 00:28:14 +01:00
parent 58531bf579
commit 52054493cc
8 changed files with 231 additions and 40 deletions

View File

@@ -12,6 +12,16 @@
"asset": "nvim-linux-arm64.tar.gz", "asset": "nvim-linux-arm64.tar.gz",
"binary": "nvim-linux-arm64/bin/nvim" "binary": "nvim-linux-arm64/bin/nvim"
} }
},
"macos": {
"x86_64": {
"asset": "nvim-macos-x86_64.tar.gz",
"binary": "nvim-macos-x86_64/bin/nvim"
},
"aarch64": {
"asset": "nvim-macos-arm64.tar.gz",
"binary": "nvim-macos-arm64/bin/nvim"
}
} }
}, },
"eza": { "eza": {
@@ -27,6 +37,9 @@
"asset": "eza_aarch64-unknown-linux-gnu.tar.gz", "asset": "eza_aarch64-unknown-linux-gnu.tar.gz",
"binary": "eza" "binary": "eza"
} }
},
"macos": {
"formula": "eza"
} }
} }
} }

View File

@@ -18,11 +18,15 @@ echo -e "${BLUE} LOG:${YELLOW} Initializing Base System Layer...${NC}"
# Confirm Architecture # Confirm Architecture
ARCH=$(uname -m) ARCH=$(uname -m)
if [ "$ARCH" != "x86_64" ] && [ "$ARCH" != "aarch64" ]; then if [ "$ARCH" != "x86_64" ] && [ "$ARCH" != "aarch64" ] && [ "$ARCH" != "arm64" ]; then
echo -e "${RED} ERROR: Unsupported architecture: $ARCH${NC}" echo -e "${RED} ERROR: Unsupported architecture: $ARCH${NC}"
exit 1 exit 1
fi fi
is_wsl() {
[ -f /proc/version ] && grep -qEi "(Microsoft|WSL)" /proc/version
}
# Package Installation # Package Installation
PACKAGES=( PACKAGES=(
curl wget git sudo curl wget git sudo
@@ -51,6 +55,8 @@ for pkg in "${PACKAGES[@]}"; do
FINAL_PACKAGES+=(build-essential) FINAL_PACKAGES+=(build-essential)
elif is_fedora_family; then elif is_fedora_family; then
FINAL_PACKAGES+=(gcc gcc-c++ make patch) FINAL_PACKAGES+=(gcc gcc-c++ make patch)
elif is_macos; then
:
fi fi
continue continue
;; ;;
@@ -61,6 +67,8 @@ for pkg in "${PACKAGES[@]}"; do
FINAL_PACKAGES+=(python3 python3-pip python3-venv) FINAL_PACKAGES+=(python3 python3-pip python3-venv)
elif is_fedora_family; then elif is_fedora_family; then
FINAL_PACKAGES+=(python3 python3-pip) FINAL_PACKAGES+=(python3 python3-pip)
elif is_macos; then
FINAL_PACKAGES+=(python)
fi fi
continue continue
;; ;;
@@ -83,6 +91,8 @@ for pkg in "${PACKAGES[@]}"; do
FINAL_PACKAGES+=(libssl-dev) FINAL_PACKAGES+=(libssl-dev)
elif is_fedora_family; then elif is_fedora_family; then
FINAL_PACKAGES+=(openssl openssl-devel) FINAL_PACKAGES+=(openssl openssl-devel)
elif is_macos; then
FINAL_PACKAGES+=(openssl@3)
fi fi
continue continue
;; ;;
@@ -93,6 +103,8 @@ for pkg in "${PACKAGES[@]}"; do
FINAL_PACKAGES+=(dnsutils) FINAL_PACKAGES+=(dnsutils)
elif is_fedora_family; then elif is_fedora_family; then
FINAL_PACKAGES+=(bind-utils) FINAL_PACKAGES+=(bind-utils)
elif is_macos; then
FINAL_PACKAGES+=(bind)
fi fi
continue continue
;; ;;
@@ -101,6 +113,8 @@ for pkg in "${PACKAGES[@]}"; do
FINAL_PACKAGES+=(ninja) FINAL_PACKAGES+=(ninja)
elif is_debian_family || is_fedora_family; then elif is_debian_family || is_fedora_family; then
FINAL_PACKAGES+=(ninja-build) FINAL_PACKAGES+=(ninja-build)
elif is_macos; then
FINAL_PACKAGES+=(ninja)
fi fi
continue continue
;; ;;
@@ -111,12 +125,16 @@ for pkg in "${PACKAGES[@]}"; do
FINAL_PACKAGES+=(libcurl4-openssl-dev) FINAL_PACKAGES+=(libcurl4-openssl-dev)
elif is_fedora_family; then elif is_fedora_family; then
FINAL_PACKAGES+=(libcurl-devel) FINAL_PACKAGES+=(libcurl-devel)
elif is_macos; then
FINAL_PACKAGES+=(curl)
fi fi
continue continue
;; ;;
"gnupg") "gnupg")
if is_fedora_family; then if is_fedora_family; then
FINAL_PACKAGES+=(gnupg2) FINAL_PACKAGES+=(gnupg2)
elif is_macos; then
FINAL_PACKAGES+=(gnupg)
else else
FINAL_PACKAGES+=(gnupg) FINAL_PACKAGES+=(gnupg)
fi fi
@@ -137,6 +155,18 @@ if is_fedora_family; then
FINAL_PACKAGES+=(R-core gcc-gfortran bzip2 bzip2-devel readline-devel sqlite sqlite-devel tk-devel libffi-devel xz xz-devel ncurses-devel zlib-devel findutils llvm) FINAL_PACKAGES+=(R-core gcc-gfortran bzip2 bzip2-devel readline-devel sqlite sqlite-devel tk-devel libffi-devel xz xz-devel ncurses-devel zlib-devel findutils llvm)
fi fi
if is_macos; then
FINAL_PACKAGES=(
curl wget git zsh tmux unzip
python bison mercurial
ripgrep fd bat fzf jq
btop httpie gnupg
zoxide stow direnv
bind nmap socat
hexyl ninja just
)
fi
echo -e "${BLUE} LOG:${YELLOW} Installing: ${NC}${FINAL_PACKAGES[*]}" echo -e "${BLUE} LOG:${YELLOW} Installing: ${NC}${FINAL_PACKAGES[*]}"
install_status=0 install_status=0
@@ -160,11 +190,15 @@ bash "$REPO_ROOT/Scripts/bin/install.sh" --all
if ! command -v rclone &> /dev/null; then if ! command -v rclone &> /dev/null; then
echo -e "${BLUE} LOG:${YELLOW} Installing Rclone CLI...${NC}" echo -e "${BLUE} LOG:${YELLOW} Installing Rclone CLI...${NC}"
if is_macos; then
brew install rclone
else
case "$ARCH" in case "$ARCH" in
x86_64) x86_64)
RCLONE_ARCH="amd64" RCLONE_ARCH="amd64"
;; ;;
aarch64) aarch64|arm64)
RCLONE_ARCH="arm64" RCLONE_ARCH="arm64"
;; ;;
esac esac
@@ -177,15 +211,20 @@ if ! command -v rclone &> /dev/null; then
install -m 755 "$TEMP_DIR"/rclone-*-linux-"${RCLONE_ARCH}"/rclone "$HOME/.local/bin/rclone" install -m 755 "$TEMP_DIR"/rclone-*-linux-"${RCLONE_ARCH}"/rclone "$HOME/.local/bin/rclone"
rm -rf "$TEMP_DIR" rm -rf "$TEMP_DIR"
fi fi
fi
if ! command -v earthly &> /dev/null; then if ! command -v earthly &> /dev/null; then
echo -e "${BLUE} LOG:${YELLOW} Installing Earthly CLI...${NC}" echo -e "${BLUE} LOG:${YELLOW} Installing Earthly CLI...${NC}"
if is_macos; then
brew install earthly
else
case "$ARCH" in case "$ARCH" in
x86_64) x86_64)
EARTHLY_ARCH="amd64" EARTHLY_ARCH="amd64"
;; ;;
aarch64) aarch64|arm64)
EARTHLY_ARCH="arm64" EARTHLY_ARCH="arm64"
;; ;;
esac esac
@@ -194,14 +233,17 @@ if ! command -v earthly &> /dev/null; then
-o "$HOME/.local/bin/earthly" -o "$HOME/.local/bin/earthly"
chmod +x "$HOME/.local/bin/earthly" chmod +x "$HOME/.local/bin/earthly"
fi fi
fi
# Docker Installation # Docker Installation
if command -v docker &> /dev/null; then if command -v docker &> /dev/null; then
echo -e "${GREEN} LOG: Docker is already installed.${NC}" echo -e "${GREEN} LOG: Docker is already installed.${NC}"
else else
if grep -qEi "(Microsoft|WSL)" /proc/version &> /dev/null; then if is_wsl; then
echo -e "${RED} LOG: WSL Detected! Skipping Native Docker.${NC}" echo -e "${RED} LOG: WSL Detected! Skipping Native Docker.${NC}"
echo -e "${RED} >>> Please install Docker Desktop on Windows.${NC}" echo -e "${RED} >>> Please install Docker Desktop on Windows.${NC}"
elif is_macos; then
echo -e "${YELLOW} NOTE:${NC} Docker is not installed. Please install Docker Desktop for macOS manually."
else else
echo -e "${BLUE} LOG:${YELLOW} Installing Native Docker...${NC}" echo -e "${BLUE} LOG:${YELLOW} Installing Native Docker...${NC}"
if is_arch_family; then if is_arch_family; then
@@ -220,7 +262,7 @@ else
fi fi
# Add user to group # Add user to group
if getent group docker >/dev/null 2>&1; then if command -v getent >/dev/null 2>&1 && getent group docker >/dev/null 2>&1; then
sudo usermod -aG docker $(whoami) sudo usermod -aG docker $(whoami)
fi fi
fi fi
@@ -239,7 +281,7 @@ mkdir -p "$ZSH_CUSTOM/plugins"
[ ! -d "$ZSH_CUSTOM/plugins/zsh-autosuggestions" ] && git clone https://github.com/zsh-users/zsh-autosuggestions "$ZSH_CUSTOM/plugins/zsh-autosuggestions" [ ! -d "$ZSH_CUSTOM/plugins/zsh-autosuggestions" ] && git clone https://github.com/zsh-users/zsh-autosuggestions "$ZSH_CUSTOM/plugins/zsh-autosuggestions"
# 5. Git Credentials (WSL Bridge) # 5. Git Credentials (WSL Bridge)
if grep -qEi "(Microsoft|WSL)" /proc/version &> /dev/null; then if is_wsl; then
GCM_WIN="/mnt/c/Program Files/Git/mingw64/bin/git-credential-manager.exe" GCM_WIN="/mnt/c/Program Files/Git/mingw64/bin/git-credential-manager.exe"
[ -f "$GCM_WIN" ] && git config --global credential.helper "! \"$GCM_WIN\"" [ -f "$GCM_WIN" ] && git config --global credential.helper "! \"$GCM_WIN\""
else else
@@ -253,10 +295,21 @@ touch "$REPO_ROOT/Zsh/.zsh_secrets"
# 7. Set Shell # 7. Set Shell
TARGET_SHELL="$(command -v zsh)" TARGET_SHELL="$(command -v zsh)"
CURRENT_LOGIN_SHELL=""
if command -v getent >/dev/null 2>&1; then
CURRENT_LOGIN_SHELL="$(getent passwd "$(whoami)" | cut -d: -f7)" CURRENT_LOGIN_SHELL="$(getent passwd "$(whoami)" | cut -d: -f7)"
elif is_macos && command -v dscl >/dev/null 2>&1; then
CURRENT_LOGIN_SHELL="$(dscl . -read "/Users/$(whoami)" UserShell 2>/dev/null | awk '{print $2}')"
fi
if [ "$CURRENT_LOGIN_SHELL" != "$TARGET_SHELL" ]; then if [ "$CURRENT_LOGIN_SHELL" != "$TARGET_SHELL" ]; then
if command -v chsh >/dev/null 2>&1; then if [ ! -t 0 ]; then
echo -e "${YELLOW} NOTE:${NC} Non-interactive session detected. Skipping login shell change to $TARGET_SHELL."
echo -e "${YELLOW} NOTE:${NC} Run 'chsh -s $TARGET_SHELL' manually later if you want zsh as your login shell."
elif is_macos && command -v chsh >/dev/null 2>&1; then
chsh -s "$TARGET_SHELL"
elif command -v chsh >/dev/null 2>&1; then
sudo chsh -s "$TARGET_SHELL" "$(whoami)" sudo chsh -s "$TARGET_SHELL" "$(whoami)"
elif command -v usermod >/dev/null 2>&1; then elif command -v usermod >/dev/null 2>&1; then
sudo usermod -s "$TARGET_SHELL" "$(whoami)" sudo usermod -s "$TARGET_SHELL" "$(whoami)"

View File

@@ -22,6 +22,17 @@ ensure_deps() {
fi fi
} }
detect_platform() {
case "$(uname -s)" in
Linux) printf 'linux\n' ;;
Darwin) printf 'macos\n' ;;
*)
printf 'Unsupported operating system: %s\n' "$(uname -s)" >&2
exit 1
;;
esac
}
detect_arch() { detect_arch() {
case "$(uname -m)" in case "$(uname -m)" in
x86_64) printf 'x86_64\n' ;; x86_64) printf 'x86_64\n' ;;
@@ -35,8 +46,9 @@ detect_arch() {
install_tool() { install_tool() {
local tool="$1" local tool="$1"
local arch version owner repo asset binary_rel url tmp_dir archive_path extracted_path target_path local platform arch version owner repo asset binary_rel formula url tmp_dir archive_path extracted_path target_path installed_path
platform="$(detect_platform)"
arch="$(detect_arch)" arch="$(detect_arch)"
if ! jq -e --arg tool "$tool" '.[$tool]' "$MANIFEST" >/dev/null; then if ! jq -e --arg tool "$tool" '.[$tool]' "$MANIFEST" >/dev/null; then
@@ -47,11 +59,39 @@ install_tool() {
version="$(jq -r --arg tool "$tool" '.[$tool].version' "$MANIFEST")" version="$(jq -r --arg tool "$tool" '.[$tool].version' "$MANIFEST")"
owner="$(jq -r --arg tool "$tool" '.[$tool].owner' "$MANIFEST")" owner="$(jq -r --arg tool "$tool" '.[$tool].owner' "$MANIFEST")"
repo="$(jq -r --arg tool "$tool" '.[$tool].repo' "$MANIFEST")" repo="$(jq -r --arg tool "$tool" '.[$tool].repo' "$MANIFEST")"
asset="$(jq -r --arg tool "$tool" --arg arch "$arch" '.[$tool].linux[$arch].asset' "$MANIFEST")" formula="$(jq -r --arg tool "$tool" --arg platform "$platform" '.[$tool][$platform].formula // empty' "$MANIFEST")"
binary_rel="$(jq -r --arg tool "$tool" --arg arch "$arch" '.[$tool].linux[$arch].binary' "$MANIFEST")"
if [ -z "$asset" ] || [ "$asset" = "null" ] || [ -z "$binary_rel" ] || [ "$binary_rel" = "null" ]; then if [ -n "$formula" ]; then
printf 'No Linux asset mapping for %s on %s\n' "$tool" "$arch" >&2 if ! command -v brew >/dev/null 2>&1; then
printf 'Homebrew is required to install %s on macOS\n' "$tool" >&2
exit 1
fi
if ! brew list --formula "$formula" >/dev/null 2>&1; then
printf 'Installing %s via Homebrew formula %s\n' "$tool" "$formula"
brew install "$formula"
else
printf '%s already installed via Homebrew\n' "$tool"
fi
installed_path="$(command -v "$tool" || true)"
if [ -z "$installed_path" ]; then
printf 'Installed formula %s but %s is not on PATH\n' "$formula" "$tool" >&2
exit 1
fi
mkdir -p "$TARGET_DIR"
target_path="$TARGET_DIR/$tool"
ln -sf "$installed_path" "$target_path"
printf 'Linked %s -> %s\n' "$target_path" "$installed_path"
return 0
fi
asset="$(jq -r --arg tool "$tool" --arg platform "$platform" --arg arch "$arch" '.[$tool][$platform][$arch].asset // empty' "$MANIFEST")"
binary_rel="$(jq -r --arg tool "$tool" --arg platform "$platform" --arg arch "$arch" '.[$tool][$platform][$arch].binary // empty' "$MANIFEST")"
if [ -z "$asset" ] || [ -z "$binary_rel" ]; then
printf 'No %s asset mapping for %s on %s\n' "$platform" "$tool" "$arch" >&2
exit 1 exit 1
fi fi

View File

@@ -13,13 +13,14 @@ NC='\033[0m'
export GVM_ROOT="$HOME/.programming/go" export GVM_ROOT="$HOME/.programming/go"
BOOTSTRAP_GO="$GVM_ROOT/bootstrap" BOOTSTRAP_GO="$GVM_ROOT/bootstrap"
OS_NAME="$(uname -s)"
ARCH="$(uname -m)" ARCH="$(uname -m)"
case "$ARCH" in case "$ARCH" in
x86_64) x86_64)
GO_BOOTSTRAP_ARCH="amd64" GO_BOOTSTRAP_ARCH="amd64"
;; ;;
aarch64) aarch64|arm64)
GO_BOOTSTRAP_ARCH="arm64" GO_BOOTSTRAP_ARCH="arm64"
;; ;;
*) *)
@@ -28,6 +29,19 @@ case "$ARCH" in
;; ;;
esac esac
case "$OS_NAME" in
Linux)
GO_BOOTSTRAP_OS="linux"
;;
Darwin)
GO_BOOTSTRAP_OS="darwin"
;;
*)
echo -e "${RED} ERROR:${NC} Unsupported operating system for Go bootstrap: $OS_NAME"
exit 1
;;
esac
echo -e "${BLUE} LOG:${YELLOW} Setting up Go and GVM in ${GVM_ROOT}...${NC}" echo -e "${BLUE} LOG:${YELLOW} Setting up Go and GVM in ${GVM_ROOT}...${NC}"
if [ ! -d "$GVM_ROOT/scripts" ]; then if [ ! -d "$GVM_ROOT/scripts" ]; then
@@ -36,7 +50,15 @@ if [ ! -d "$GVM_ROOT/scripts" ]; then
rm -rf "$GVM_ROOT/.git" rm -rf "$GVM_ROOT/.git"
echo -e "${BLUE} LOG:${YELLOW} Configuring GVM scripts...${NC}" echo -e "${BLUE} LOG:${YELLOW} Configuring GVM scripts...${NC}"
cp "$GVM_ROOT/scripts/gvm-default" "$GVM_ROOT/scripts/gvm" cp "$GVM_ROOT/scripts/gvm-default" "$GVM_ROOT/scripts/gvm"
sed -i "s|^GVM_ROOT=.*|GVM_ROOT=\"$GVM_ROOT\"|" "$GVM_ROOT/scripts/gvm" python3 - "$GVM_ROOT/scripts/gvm" "$GVM_ROOT" <<'PY'
from pathlib import Path
import sys
path = Path(sys.argv[1])
root = sys.argv[2]
text = path.read_text()
path.write_text(text.replace('GVM_ROOT="$HOME/.gvm"', f'GVM_ROOT="{root}"', 1))
PY
echo -e "${GREEN} SUCCESS:${NC} GVM cloned and configured." echo -e "${GREEN} SUCCESS:${NC} GVM cloned and configured."
else else
@@ -47,7 +69,7 @@ if [ ! -d "$BOOTSTRAP_GO" ]; then
echo -e "${BLUE} LOG:${YELLOW} Downloading Bootstrap Go...${NC}" echo -e "${BLUE} LOG:${YELLOW} Downloading Bootstrap Go...${NC}"
mkdir -p "$BOOTSTRAP_GO" mkdir -p "$BOOTSTRAP_GO"
wget -q "https://go.dev/dl/go1.20.5.linux-${GO_BOOTSTRAP_ARCH}.tar.gz" -O /tmp/go-bootstrap.tar.gz wget -q "https://go.dev/dl/go1.20.5.${GO_BOOTSTRAP_OS}-${GO_BOOTSTRAP_ARCH}.tar.gz" -O /tmp/go-bootstrap.tar.gz
tar -C "$BOOTSTRAP_GO" -xzf /tmp/go-bootstrap.tar.gz --strip-components=1 tar -C "$BOOTSTRAP_GO" -xzf /tmp/go-bootstrap.tar.gz --strip-components=1
rm /tmp/go-bootstrap.tar.gz rm /tmp/go-bootstrap.tar.gz

View File

@@ -10,8 +10,11 @@ if [ -f /etc/os-release ]; then
. /etc/os-release . /etc/os-release
OS="${ID}" OS="${ID}"
OS_LIKE="${ID_LIKE:-}" OS_LIKE="${ID_LIKE:-}"
elif [ "$(uname -s)" = "Darwin" ]; then
OS="macos"
OS_LIKE="darwin"
else else
echo "Unable to detect operating system: /etc/os-release not found." echo "Unable to detect operating system: /etc/os-release not found and host is not macOS."
return 1 2>/dev/null || exit 1 return 1 2>/dev/null || exit 1
fi fi
@@ -27,6 +30,10 @@ is_fedora_family() {
[[ "$OS" == "fedora" || "$OS" == "bazzite" || " $OS_LIKE " == *" fedora "* || " $OS_LIKE " == *" rhel "* ]] [[ "$OS" == "fedora" || "$OS" == "bazzite" || " $OS_LIKE " == *" fedora "* || " $OS_LIKE " == *" rhel "* ]]
} }
is_macos() {
[[ "$OS" == "macos" ]]
}
is_atomic_fedora() { is_atomic_fedora() {
is_fedora_family && command -v rpm-ostree >/dev/null 2>&1 && [ -f /run/ostree-booted ] is_fedora_family && command -v rpm-ostree >/dev/null 2>&1 && [ -f /run/ostree-booted ]
} }
@@ -126,6 +133,22 @@ install_packages() {
return 0 return 0
fi fi
if is_macos; then
if ! command -v brew >/dev/null 2>&1; then
echo "Homebrew is required on macOS. Install it from https://brew.sh first."
return 1
fi
local pkg
for pkg in "${packages[@]}"; do
if brew list --formula "$pkg" >/dev/null 2>&1; then
continue
fi
brew install "$pkg"
done
return 0
fi
echo "Unsupported OS: $OS" echo "Unsupported OS: $OS"
return 1 return 1
} }

View File

@@ -22,6 +22,9 @@ elif is_debian_family; then
elif is_fedora_family; then elif is_fedora_family; then
echo -e "${BLUE} LOG:${YELLOW} Installing Fedora build dependencies...${NC}" echo -e "${BLUE} LOG:${YELLOW} Installing Fedora build dependencies...${NC}"
PYTHON_BUILD_DEPS=(make gcc gcc-c++ patch zlib-devel bzip2 bzip2-devel readline-devel sqlite sqlite-devel openssl-devel tk-devel libffi-devel xz xz-devel ncurses-devel findutils git) PYTHON_BUILD_DEPS=(make gcc gcc-c++ patch zlib-devel bzip2 bzip2-devel readline-devel sqlite sqlite-devel openssl-devel tk-devel libffi-devel xz xz-devel ncurses-devel findutils git)
elif is_macos; then
echo -e "${BLUE} LOG:${YELLOW} Installing macOS build dependencies...${NC}"
PYTHON_BUILD_DEPS=(openssl@3 readline sqlite xz tcl-tk bzip2 zlib pkg-config git)
else else
echo -e "${RED} ERROR:${NC} Unsupported OS: $OS" echo -e "${RED} ERROR:${NC} Unsupported OS: $OS"
exit 1 exit 1

View File

@@ -118,6 +118,19 @@ elif is_fedora_family; then
write_r_wrapper "R" 'exec "$(command -v R)"' write_r_wrapper "R" 'exec "$(command -v R)"'
write_r_wrapper "Rscript" 'exec "$(command -v Rscript)"' write_r_wrapper "Rscript" 'exec "$(command -v Rscript)"'
elif is_macos; then
echo -e "${BLUE} LOG:${YELLOW} macOS detected. Using Homebrew R...${NC}"
install_status=0
install_packages r || install_status=$?
if [ "$install_status" -ne 0 ]; then
exit "$install_status"
fi
R_BIN="R"
write_r_wrapper "R" 'exec "$(command -v R)"'
write_r_wrapper "Rscript" 'exec "$(command -v Rscript)"'
else else
echo -e "${RED} ERROR:${NC} Unsupported OS: $OS" echo -e "${RED} ERROR:${NC} Unsupported OS: $OS"
exit 1 exit 1

View File

@@ -7,6 +7,7 @@ REPO_ROOT="$(dirname "$SCRIPT_DIR")"
REBOOT_MARKER="$REPO_ROOT/.setup-reboot-required" REBOOT_MARKER="$REPO_ROOT/.setup-reboot-required"
REPO_SECRET_FILE="$REPO_ROOT/Zsh/.zsh_secrets" REPO_SECRET_FILE="$REPO_ROOT/Zsh/.zsh_secrets"
HOME_SECRET_FILE="$HOME/.zsh_secrets" HOME_SECRET_FILE="$HOME/.zsh_secrets"
BACKUP_ROOT="$HOME/.dotzsh-pre-stow-backup"
handle_reboot_marker() { handle_reboot_marker() {
if [ -f "$REBOOT_MARKER" ]; then if [ -f "$REBOOT_MARKER" ]; then
@@ -42,6 +43,28 @@ sync_repo_managed_secret_file() {
touch "$REPO_SECRET_FILE" touch "$REPO_SECRET_FILE"
} }
backup_conflicting_home_files() {
local backup_dir backed_up_any=0 source_file filename target_file
backup_dir="$BACKUP_ROOT/$(date +%Y%m%d-%H%M%S)"
while IFS= read -r source_file; do
filename="$(basename "$source_file")"
target_file="$HOME/$filename"
if [ -e "$target_file" ] && [ ! -L "$target_file" ]; then
mkdir -p "$backup_dir"
mv "$target_file" "$backup_dir/$filename"
echo "Backed up existing $target_file -> $backup_dir/$filename"
backed_up_any=1
fi
done < <(find "$REPO_ROOT/Zsh" -mindepth 1 -maxdepth 1 -type f -name '.*' ! -name '.zsh_secrets')
if [ "$backed_up_any" -eq 1 ]; then
echo "Existing unmanaged dotfiles were backed up before stowing."
fi
}
main() { main() {
rm -f "$REBOOT_MARKER" rm -f "$REBOOT_MARKER"
@@ -58,6 +81,7 @@ main() {
handle_reboot_marker handle_reboot_marker
sync_repo_managed_secret_file sync_repo_managed_secret_file
backup_conflicting_home_files
stow --dir="$REPO_ROOT" -D Zsh --target="$HOME" 2>/dev/null || true stow --dir="$REPO_ROOT" -D Zsh --target="$HOME" 2>/dev/null || true
stow --dir="$REPO_ROOT" Zsh --target="$HOME" stow --dir="$REPO_ROOT" Zsh --target="$HOME"