Repository navigation
Expand file tree
/
Copy pathsetup
More file actions
executable file
·78 lines (71 loc) · 2.36 KB
/
Copy pathsetup
File metadata and controls
executable file
·78 lines (71 loc) · 2.36 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
#!/bin/sh
# Visible names in home/ map to dotfiles in $HOME; shell entrypoints stay local.
set -eu
case "${1:-}" in
'') ;;
-h | --help)
printf '%s\n' 'Usage: ./setup' \
'Links home/ files into $HOME, replacing existing files and symlinks.' \
'Shell entrypoints are appended once. Software is installed separately.'
exit 0
;;
*)
printf '%s\n' 'Usage: ./setup' >&2
exit 2
;;
esac
repo_dir=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
mkdir -p "$HOME"
target_home=$(CDPATH= cd -- "$HOME" && pwd)
case "$target_home/" in
"$repo_dir/"*)
printf '%s\n' 'HOME must be outside the repository.' >&2
exit 1
;;
esac
find "$repo_dir/home" -type f | sort | while IFS= read -r source; do
relative=${source#"$repo_dir/home/"}
# Only the first component gains a dot: config/nvim -> .config/nvim.
target=$target_home/.$relative
case "$relative" in
bashrc | profile | zshrc) target=$target_home/.config/shell/$relative ;;
esac
# Do not follow directory links into an old checkout or another config tree.
parent=${target%/*}
while [ "$parent" != "$target_home" ]; do
if [ -L "$parent" ]; then
printf 'Directory symlink needs manual migration: %s\n' "$parent" >&2
exit 1
fi
parent=${parent%/*}
done
mkdir -p "${target%/*}"
if [ -L "$target" ] && [ "$(readlink "$target")" = "$source" ]; then
continue
fi
# rm -f deliberately refuses to remove an actual directory.
rm -f "$target"
ln -s "$source" "$target"
printf 'LINK %s\n' "$target"
done
# Keep writable machine entrypoints separate from repository configuration.
for shell_file in bashrc profile zshrc; do
target=$target_home/.$shell_file
if [ -L "$target" ]; then
temporary=$(mktemp "$target.setup.XXXXXX")
if [ -f "$target" ]; then cat "$target" >"$temporary"; fi
mv -f "$temporary" "$target"
fi
touch "$target"
loader='.'
if [ "$shell_file" = zshrc ]; then loader=source; fi
{
printf '%s "$HOME/.config/shell/%s"\n' "$loader" "$shell_file"
printf '[ -f "$HOME/.%s.local" ] && %s "$HOME/.%s.local"\n' "$shell_file" "$loader" "$shell_file"
} | while IFS= read -r line; do
if ! grep -Fqx -- "$line" "$target"; then
printf '\n%s\n' "$line" >>"$target"
fi
done
printf 'LOAD %s\n' "$target"
done