-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathinstall.sh
More file actions
executable file
·124 lines (105 loc) · 4.01 KB
/
install.sh
File metadata and controls
executable file
·124 lines (105 loc) · 4.01 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
115
116
117
118
119
120
121
122
123
124
#!/bin/bash
DOTS_DIR="$(cd "$(dirname "$0")" && pwd)"
FORCE=false
if [[ "$1" == "--force" ]]; then
FORCE=true
fi
# safe_link source destination
# If destination exists and is not already a symlink to source, show diff and abort (unless --force).
safe_link() {
local src="$1"
local dest="$2"
# If destination exists (file, dir, or symlink)
if [ -e "$dest" ] || [ -L "$dest" ]; then
# Already points to the right place — nothing to do (resolve both to absolute paths)
if [ -L "$dest" ] && [ "$(readlink -f "$dest")" = "$(readlink -f "$src")" ]; then
return 0
fi
if [ "$FORCE" = true ]; then
rm -rf "$dest"
else
echo "!! Conflict: $dest already exists and differs from $src"
if [ -L "$dest" ]; then
echo " Current symlink target: $(readlink "$dest")"
echo " Expected symlink target: $src"
fi
# Show content diff if both are readable files (resolve symlinks)
local real_dest="$dest"
[ -L "$dest" ] && real_dest="$(readlink -f "$dest")"
if [ -f "$real_dest" ] && [ -f "$src" ]; then
echo " Differences (existing → new):"
diff --color=auto -u "$real_dest" "$src" | sed 's/^/ /'
fi
echo ""
echo " Use --force to overwrite."
exit 1
fi
fi
ln -sf "$src" "$dest"
}
# Like safe_link but uses ln -sfn for directories
safe_link_dir() {
local src="$1"
local dest="$2"
if [ -e "$dest" ] || [ -L "$dest" ]; then
if [ -L "$dest" ] && [ "$(readlink -f "$dest")" = "$(readlink -f "$src")" ]; then
return 0
fi
if [ "$FORCE" = true ]; then
rm -rf "$dest"
else
echo "!! Conflict: $dest already exists and differs from $src"
if [ -L "$dest" ]; then
echo " Current symlink target: $(readlink "$dest")"
echo " Expected symlink target: $src"
fi
echo ""
echo " Use --force to overwrite."
exit 1
fi
fi
ln -sfn "$src" "$dest"
}
# Migrate legacy ~/.config/mise directory layout (directory + config.toml file)
# to a directory symlink pointing at $DOTS_DIR/mise.
prepare_mise_dir() {
local src_dir="$DOTS_DIR/mise"
local src_config="$src_dir/config.toml"
local dest_dir="$HOME/.config/mise"
local dest_config="$dest_dir/config.toml"
if [ -d "$dest_dir" ] && [ ! -L "$dest_dir" ]; then
local extra_entry
extra_entry="$(find "$dest_dir" -mindepth 1 -maxdepth 1 ! -name "config.toml" -print -quit)"
if [ -n "$extra_entry" ] && [ "$FORCE" != true ]; then
echo "!! Conflict: $dest_dir contains files other than config.toml"
echo " First unexpected entry: $extra_entry"
echo ""
echo " Use --force to overwrite."
exit 1
fi
if [ -f "$dest_config" ] && [ ! -L "$dest_config" ] && [ "$FORCE" != true ] && ! cmp -s "$dest_config" "$src_config"; then
echo "!! Conflict: $dest_config differs from $src_config"
echo " Differences (existing → new):"
diff --color=auto -u "$dest_config" "$src_config" | sed 's/^/ /'
echo ""
echo " Use --force to overwrite."
exit 1
fi
rm -rf "$dest_dir"
fi
}
# Create parent directories if needed
mkdir -p ~/.config/opencode
mkdir -p ~/.config/jj
prepare_mise_dir
# Symlink dotfiles
safe_link "$DOTS_DIR/.zshrc" ~/.zshrc
safe_link "$DOTS_DIR/.zprofile" ~/.zprofile
safe_link "$DOTS_DIR/.tmux.conf" ~/.tmux.conf
safe_link "$DOTS_DIR/opencode.json" ~/.config/opencode/opencode.json
safe_link "$DOTS_DIR/starship.toml" ~/.config/starship.toml
safe_link_dir "$DOTS_DIR/wezterm" ~/.config/wezterm
safe_link_dir "$DOTS_DIR/mise" ~/.config/mise
safe_link "$DOTS_DIR/jj/config.toml" ~/.config/jj/config.toml
safe_link "$DOTS_DIR/git/config" ~/.gitconfig
echo "Dotfiles symlinked!"