Switch install.sh to GNU Stow for symlinking

Manual ln -sfn loop replaced with stow zsh gnupg, matching the repo's
existing per-package-directory convention. Still backs up/removes any
conflicting file or foreign symlink at the target before stowing.
This commit is contained in:
2026-07-25 23:38:05 +03:00
parent a48be5af09
commit 9370afd396
2 changed files with 41 additions and 22 deletions
+30 -17
View File
@@ -1,19 +1,16 @@
#!/usr/bin/env bash
# Bootstraps zsh config on a new machine: symlinks dotfiles into $HOME and
# clones oh-my-zsh + the custom theme/plugins referenced by .zshrc.
# Bootstraps dotfiles on a new machine: installs oh-my-zsh + the custom
# theme/plugins .zshrc expects, then symlinks packages into $HOME via
# GNU Stow (each top-level dir is a package mirroring $HOME, e.g.
# zsh/.zshrc -> ~/.zshrc). Add a new package by adding a new top-level dir.
set -euo pipefail
DOTFILES_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
ZSH_CUSTOM="${ZSH_CUSTOM:-$HOME/.oh-my-zsh/custom}"
link() {
local src="$1" dst="$2"
if [ -e "$dst" ] && [ ! -L "$dst" ]; then
mv "$dst" "$dst.bak.$(date +%s)"
echo "Backed up existing $dst"
fi
ln -sfn "$src" "$dst"
echo "Linked $dst -> $src"
command -v stow >/dev/null || {
echo "GNU Stow is required: sudo pacman -S stow (or your distro's equivalent)" >&2
exit 1
}
clone_if_missing() {
@@ -34,14 +31,30 @@ clone_if_missing https://github.com/zsh-users/zsh-history-substring-search "$ZSH
clone_if_missing https://github.com/zsh-users/zsh-completions "$ZSH_CUSTOM/plugins/zsh-completions"
clone_if_missing https://github.com/MichaelAquilina/zsh-you-should-use "$ZSH_CUSTOM/plugins/you-should-use"
link "$DOTFILES_DIR/zsh/.zshrc" "$HOME/.zshrc"
link "$DOTFILES_DIR/zsh/.zshenv" "$HOME/.zshenv"
link "$DOTFILES_DIR/zsh/.zprofile" "$HOME/.zprofile"
link "$DOTFILES_DIR/zsh/.p10k.zsh" "$HOME/.p10k.zsh"
# Stow refuses to link over a real (non-symlink) file, so move any
# conflicting pre-existing file aside first (e.g. the .zshrc oh-my-zsh's
# own installer just wrote above).
stow_package() {
local pkg="$1" f rel target
while IFS= read -r -d '' f; do
rel="${f#"$DOTFILES_DIR/$pkg/"}"
target="$HOME/$rel"
if [ -L "$target" ]; then
rm "$target"
elif [ -e "$target" ]; then
mkdir -p "$(dirname "$target")"
mv "$target" "$target.bak.$(date +%s)"
echo "Backed up existing $target"
fi
done < <(find "$DOTFILES_DIR/$pkg" -type f -print0)
stow --dir="$DOTFILES_DIR" --target="$HOME" --restow "$pkg"
echo "Stowed $pkg"
}
mkdir -p "$HOME/.gnupg"
chmod 700 "$HOME/.gnupg"
link "$DOTFILES_DIR/gnupg/.gnupg/gpg-agent.conf" "$HOME/.gnupg/gpg-agent.conf"
mkdir -p "$HOME/.gnupg" && chmod 700 "$HOME/.gnupg"
stow_package zsh
stow_package gnupg
gpgconf --kill gpg-agent 2>/dev/null || true
cat <<'EOF'