158 lines
4.5 KiB
Bash
158 lines
4.5 KiB
Bash
#!/bin/bash
|
|
|
|
set -euo pipefail
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
REPO_ROOT="$(dirname "$SCRIPT_DIR")"
|
|
REBOOT_MARKER="$REPO_ROOT/.setup-reboot-required"
|
|
REPO_SECRET_FILE="$REPO_ROOT/Zsh/.zsh_secrets"
|
|
HOME_SECRET_FILE="$HOME/.zsh_secrets"
|
|
BACKUP_ROOT="$HOME/.dotzsh-pre-stow-backup"
|
|
|
|
handle_reboot_marker() {
|
|
if [ -f "$REBOOT_MARKER" ]; then
|
|
rm -f "$REBOOT_MARKER"
|
|
echo "Package layering finished. Reboot, then rerun the same command."
|
|
exit 0
|
|
fi
|
|
}
|
|
|
|
sync_repo_managed_secret_file() {
|
|
local home_secret_resolved repo_secret_resolved
|
|
|
|
mkdir -p "$(dirname "$REPO_SECRET_FILE")"
|
|
|
|
if [ -L "$HOME_SECRET_FILE" ]; then
|
|
home_secret_resolved="$(python3 -c 'import os,sys; print(os.path.realpath(sys.argv[1]))' "$HOME_SECRET_FILE")"
|
|
repo_secret_resolved="$(python3 -c 'import os,sys; print(os.path.realpath(sys.argv[1]))' "$REPO_SECRET_FILE")"
|
|
|
|
if [ "$home_secret_resolved" = "$repo_secret_resolved" ]; then
|
|
return 0
|
|
fi
|
|
|
|
if [ -f "$home_secret_resolved" ]; then
|
|
if [ ! -f "$REPO_SECRET_FILE" ] || [ ! -s "$REPO_SECRET_FILE" ]; then
|
|
cp "$home_secret_resolved" "$REPO_SECRET_FILE"
|
|
rm -f "$HOME_SECRET_FILE"
|
|
return 0
|
|
fi
|
|
|
|
if cmp -s "$home_secret_resolved" "$REPO_SECRET_FILE"; then
|
|
rm -f "$HOME_SECRET_FILE"
|
|
return 0
|
|
fi
|
|
fi
|
|
|
|
echo "Conflict: $HOME_SECRET_FILE points to a different secret file than $REPO_SECRET_FILE."
|
|
echo "Please merge them manually, then rerun the command."
|
|
exit 1
|
|
fi
|
|
|
|
if [ -f "$HOME_SECRET_FILE" ]; then
|
|
if [ ! -f "$REPO_SECRET_FILE" ] || [ ! -s "$REPO_SECRET_FILE" ]; then
|
|
mv "$HOME_SECRET_FILE" "$REPO_SECRET_FILE"
|
|
return 0
|
|
fi
|
|
|
|
if cmp -s "$HOME_SECRET_FILE" "$REPO_SECRET_FILE"; then
|
|
rm -f "$HOME_SECRET_FILE"
|
|
return 0
|
|
fi
|
|
|
|
echo "Conflict: both $HOME_SECRET_FILE and $REPO_SECRET_FILE exist with different contents."
|
|
echo "Please merge them manually, then rerun the command."
|
|
exit 1
|
|
fi
|
|
|
|
touch "$REPO_SECRET_FILE"
|
|
}
|
|
|
|
backup_conflicting_home_files() {
|
|
local backup_dir backed_up_any=0 source_file filename target_file target_resolved source_resolved
|
|
|
|
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 [ -L "$target_file" ]; then
|
|
target_resolved="$(python3 -c 'import os,sys; print(os.path.realpath(sys.argv[1]))' "$target_file")"
|
|
source_resolved="$(python3 -c 'import os,sys; print(os.path.realpath(sys.argv[1]))' "$source_file")"
|
|
|
|
if [ "$target_resolved" = "$source_resolved" ]; then
|
|
continue
|
|
fi
|
|
|
|
mkdir -p "$backup_dir"
|
|
mv "$target_file" "$backup_dir/$filename"
|
|
echo "Backed up existing linked $target_file -> $backup_dir/$filename"
|
|
backed_up_any=1
|
|
elif [ -e "$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
|
|
}
|
|
|
|
stow_dotfiles() {
|
|
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" Zsh --target="$HOME"
|
|
}
|
|
|
|
bootstrap_only() {
|
|
rm -f "$REBOOT_MARKER"
|
|
|
|
bash "$SCRIPT_DIR/base.sh"
|
|
handle_reboot_marker
|
|
|
|
stow_dotfiles
|
|
|
|
echo "Bootstrap setup completed."
|
|
}
|
|
|
|
full_setup() {
|
|
rm -f "$REBOOT_MARKER"
|
|
|
|
bash "$SCRIPT_DIR/base.sh"
|
|
handle_reboot_marker
|
|
|
|
bash "$SCRIPT_DIR/node.sh"
|
|
bash "$SCRIPT_DIR/go.sh"
|
|
bash "$SCRIPT_DIR/rust.sh"
|
|
bash "$SCRIPT_DIR/python.sh"
|
|
handle_reboot_marker
|
|
|
|
bash "$SCRIPT_DIR/r.sh"
|
|
handle_reboot_marker
|
|
|
|
stow_dotfiles
|
|
|
|
echo "Full setup completed."
|
|
}
|
|
|
|
case "${1:-}" in
|
|
--bootstrap-only)
|
|
bootstrap_only
|
|
;;
|
|
--stow-only)
|
|
stow_dotfiles
|
|
;;
|
|
"")
|
|
full_setup
|
|
;;
|
|
*)
|
|
echo "Usage: $0 [--bootstrap-only|--stow-only]"
|
|
exit 1
|
|
;;
|
|
esac
|