-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbootstrap.sh
More file actions
executable file
·114 lines (99 loc) · 3.62 KB
/
Copy pathbootstrap.sh
File metadata and controls
executable file
·114 lines (99 loc) · 3.62 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
#!/usr/bin/env bash
# dotfiles-guid: 4e079e8c-dadd-47fc-9582-0914483981ea
# =============================================================================
# bootstrap.sh — bootstrap dotfiles by symlinking them into $HOME
# =============================================================================
# Usage:
# ./bootstrap.sh # dry run (shows what would happen)
# ./bootstrap.sh --apply # actually create symlinks
#
# What it does:
# • Symlinks every file listed in FILES below from this repo into $HOME
# • Backs up any existing files to <file>.backup.<timestamp>
# • Is idempotent — safe to run multiple times
#
# Alternative tools to consider for managing dotfiles:
# • GNU Stow — https://www.gnu.org/software/stow/ (simple, symlink-based)
# • chezmoi — https://www.chezmoi.io/ (templates, encryption)
# • YADM — https://yadm.io/ (git wrapper)
# • Dotbot — https://github.com/anishathalye/dotbot (YAML config)
# • Mackup — https://github.com/lra/mackup (syncs app settings too)
# =============================================================================
set -euo pipefail
DOTFILES_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
BACKUP_SUFFIX=".backup.$(date +%Y%m%d_%H%M%S)"
APPLY=false
# Colour helpers
RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'
CYAN='\033[0;36m'; BOLD='\033[1m'; RESET='\033[0m'
info() { echo -e "${CYAN} →${RESET} $*"; }
success() { echo -e "${GREEN} ✓${RESET} $*"; }
warning() { echo -e "${YELLOW} !${RESET} $*"; }
error() { echo -e "${RED} ✗${RESET} $*" >&2; }
# Parse args
for arg in "$@"; do
case "$arg" in
--apply|-a) APPLY=true ;;
--help|-h)
echo "Usage: $(basename "$0") [--apply]"
echo " Without --apply, performs a dry run."
exit 0
;;
*) error "Unknown argument: $arg"; exit 1 ;;
esac
done
# =============================================================================
# FILES TO SYMLINK (source path relative to DOTFILES_DIR → target in $HOME)
# =============================================================================
declare -A FILES=(
[".zshrc"]=".zshrc"
[".zshenv"]=".zshenv"
[".gitconfig"]=".gitconfig"
[".gitignore_global"]=".gitignore_global"
[".npmrc"]=".npmrc"
[".editorconfig"]=".editorconfig"
)
# =============================================================================
# MAIN
# =============================================================================
echo
echo -e "${BOLD}dotfiles installer${RESET} — ${DOTFILES_DIR}"
if [[ "${APPLY}" == false ]]; then
echo -e "${YELLOW}DRY RUN — pass --apply to make changes${RESET}"
fi
echo
link_file() {
local src="${DOTFILES_DIR}/${1}"
local dst="${HOME}/${2}"
if [[ ! -e "$src" ]]; then
error "Source not found: $src"
return
fi
# Already correctly linked
if [[ -L "$dst" && "$(readlink "$dst")" == "$src" ]]; then
success "${dst} → already linked"
return
fi
# Backup existing file/symlink
if [[ -e "$dst" || -L "$dst" ]]; then
warning "Backing up ${dst} → ${dst}${BACKUP_SUFFIX}"
if [[ "${APPLY}" == true ]]; then
mv "$dst" "${dst}${BACKUP_SUFFIX}"
fi
fi
info "Linking ${dst} → ${src}"
if [[ "${APPLY}" == true ]]; then
ln -sf "$src" "$dst"
fi
}
for src in "${!FILES[@]}"; do
link_file "$src" "${FILES[$src]}"
done
echo
if [[ "${APPLY}" == true ]]; then
echo -e "${GREEN}${BOLD}Done!${RESET} Dotfiles installed."
echo " Reload your shell: source ~/.zshrc"
else
echo -e "Run ${BOLD}./bootstrap.sh --apply${RESET} to apply the above changes."
fi
echo