]>
Commit | Line | Data |
---|---|---|
1 | #!/bin/sh | |
2 | ||
3 | # install location and source files | |
4 | : ${DEST:=$(realpath "$HOME")} | |
5 | : ${SRC:=$(dirname "$(realpath "$0")")} | |
6 | ||
7 | # confirm XDG vars we care about are set up | |
8 | : ${LOCAL:=.local} # NOTE: needed for bin, which has no xdg var | |
9 | : ${XDG_DATA_HOME:=$DEST/$LOCAL/share} | |
10 | : ${XDG_CONFIG_HOME:=$DEST/.config} | |
11 | : ${XDG_STATE_HOME:=$DEST/$LOCAL/state} | |
12 | : ${XDG_CACHE_HOME:=$DEST/.cache} | |
13 | ||
14 | # these are the vars we actually use | |
15 | share="${XDG_DATA_HOME#$DEST/}" | |
16 | etc="${XDG_CONFIG_HOME#$DEST/}" | |
17 | state="${XDG_STATE_HOME#$DEST/}" | |
18 | cache="${XDG_CACHE_HOME#$DEST/}" | |
19 | ||
20 | # test | |
21 | devnull=/dev/null | |
22 | if [ "$1" = "test" ]; then | |
23 | echo "Running test -- no changes will be applied" | |
24 | devnull=/dev/stdout | |
25 | _cd() { | |
26 | echo "-- cd $* --> $PWD"; | |
27 | cd $*; | |
28 | } | |
29 | alias cd="_cd" | |
30 | alias mkdir="echo -- mkdir" | |
31 | alias rmdir="echo -- rmdir" | |
32 | alias ln="echo -- ln" | |
33 | alias rm="echo -- rm" | |
34 | alias mv="echo -- mv" | |
35 | alias sh="echo -- sh" | |
36 | fi | |
37 | ||
38 | # ensure ostype | |
39 | # NOTE: copied from .zshenv | |
40 | if [ -z "$OSTYPE" ]; then | |
41 | OSTYPE=$(uname -s | tr '[:upper:]' '[:lower:]') | |
42 | fi | |
43 | ||
44 | # accomodate multiple userlands | |
45 | # XXX: assuming GNU by default | |
46 | # TODO: test for GNU, fallback to POSIX instead (no -n) | |
47 | lnargs=-sfnv | |
48 | case "$OSTYPE" in | |
49 | freebsd*) lnargs=-sFhv;; | |
50 | netbsd|openbsd*) lnargs=-sfhv;; | |
51 | esac | |
52 | ||
53 | # save pwd | |
54 | old_pwd="$PWD" | |
55 | ||
56 | cd "$DEST" | |
57 | ||
58 | # create preferred folder structure | |
59 | mkdir -pm 760 "$share" "$etc" "$state" "$cache" | |
60 | ln $lnargs "$DEST/$etc" "$LOCAL/etc" | |
61 | mkdir -p "$LOCAL/bin" "$share/fonts" "$share/themes" "$share/icons" | |
62 | ||
63 | # clean out old links | |
64 | # TODO: doesn't remove dead links if realpath fails; this happens if the link | |
65 | # target doesn't exist under busybox | |
66 | find . "$share" "$etc" \ | |
67 | "$LOCAL/bin" "$share/fonts" "$share/themes" "$share/icons" \ | |
68 | "$etc/gnupg" .ssh .termux \ | |
69 | -xdev -mindepth 1 -maxdepth 1 -type l -exec sh -c ' | |
70 | r="$(realpath "{}")" | |
71 | [ "${r#'"$SRC"'/}" != "$r" ] && | |
72 | '"$([ "$1" = test ] && echo 'echo +++ ')"'unlink "{}"' \; | |
73 | ||
74 | cd "$SRC" >$devnull | |
75 | ||
76 | l() { | |
77 | # TODO: use install? | |
78 | d="$DEST/${1:-$x}" | |
79 | [ -L "$d" -o \! -e "$d" ] && ln $lnargs "$SRC/${2:-$x}" "$d" || | |
80 | echo "!!! File exists and is not a link: $1" | |
81 | } | |
82 | ||
83 | # generic links | |
84 | find base -mindepth 1 -maxdepth 1 | while read -r x; do l "${x#base/}"; done | |
85 | find bin -mindepth 1 -maxdepth 1 | while read -r x; do l "$LOCAL/$x"; done | |
86 | find share -mindepth 1 -maxdepth 1 | while read -r x; do l "$share${x#share}"; done | |
87 | find etc -mindepth 1 -maxdepth 1 | while read -r x; do l "$etc${x#etc}"; done | |
88 | ||
89 | # xorg/wayland resources | |
90 | find gui -mindepth 1 -maxdepth 1 | while read -r y; do | |
91 | case "${y#gui/}" in | |
92 | icons|themes) | |
93 | find "$y" -mindepth 1 -maxdepth 2 -type d | while read -r x; do | |
94 | [ ! -e "$x/index.theme" ] && continue | |
95 | command -v gtk-update-icon-cache >$devnull 2>&1 && | |
96 | gtk-update-icon-cache -f "$x" | |
97 | l "$share${y#gui}/$(basename "$x")" | |
98 | done | |
99 | ;; | |
100 | fonts) | |
101 | find "$y" -mindepth 1 -maxdepth 2 -type d | while read -r x; do | |
102 | command -v mkfontscale >$devnull 2>&1 && mkfontscale "$x" | |
103 | command -v mkfontdir >$devnull 2>&1 && mkfontdir "$x" | |
104 | [ "$(head -1 "$x/fonts.scale" >$devnull 2>&1)" = 0 ] && | |
105 | rm "$x/fonts.scale" | |
106 | [ "$(head -1 "$x/fonts.dir" >$devnull 2>&1)" = 0 ] && | |
107 | rm "$x/fonts.dir" | |
108 | l "$share${y#gui}/$(basename "$x")" | |
109 | done | |
110 | ;; | |
111 | *) | |
112 | find "$y" -mindepth 1 -maxdepth 1 | while read -r x; do | |
113 | l "$share${x#gui}" | |
114 | done | |
115 | ;; | |
116 | esac | |
117 | done | |
118 | ||
119 | # gpg | |
120 | if command -v gpg >$devnull 2>&1; then | |
121 | mkdir -pm 700 "$DEST/$etc/gnupg" | |
122 | find gnupg -mindepth 1 -maxdepth 1 \! -name '*.gpg' | while read -r x; do | |
123 | l "$etc/$x" | |
124 | done | |
125 | find gnupg -mindepth 1 -maxdepth 1 -name '*.gpg' | while read -r x; do | |
126 | gpg --import "$x" | |
127 | done | |
128 | fi | |
129 | ||
130 | # ssh | |
131 | if command -v ssh >$devnull 2>&1; then | |
132 | mkdir -pm 700 "$DEST/.ssh" | |
133 | find ssh -mindepth 1 -maxdepth 1 | while read -r x; do | |
134 | l ".$x"; done | |
135 | fi | |
136 | ||
137 | # termux, assume it if android | |
138 | if [ $(uname -o) = 'Android' ]; then | |
139 | mkdir -p "$DEST/.termux" | |
140 | find termux -mindepth 1 -maxdepth 1 | while read -r x; do l ".$x"; done | |
141 | l '.termux/font.ttf' "gui/fonts/Dina-ttf/Dina.ttf" | |
142 | fi | |
143 | ||
144 | cd "$DEST" >$devnull | |
145 | ||
146 | # ensure xdg user dirs, and move old to new while we're at it | |
147 | source $etc/user-dirs.dirs | |
148 | function fixup_xdg_home { | |
149 | if [ -z "$1" -o "${1#/}" = "$1" -o "$(realpath "$1")" = "$(realpath "$HOME")" ]; then | |
150 | return; | |
151 | fi | |
152 | mkdir -p "$1" | |
153 | if [ $? -eq 0 -a -n "$2" -a -d "$2" ]; then | |
154 | mv "$2"/* $1 | |
155 | rmdir "$2" | |
156 | fi | |
157 | } | |
158 | fixup_xdg_home $XDG_DESKTOP_DIR Desktop | |
159 | fixup_xdg_home $XDG_DOWNLOAD_DIR Downloads | |
160 | fixup_xdg_home $XDG_TEMPLATES_DIR | |
161 | fixup_xdg_home $XDG_PUBLICSHARE_DIR Public | |
162 | fixup_xdg_home $XDG_DOCUMENTS_DIR Documents | |
163 | fixup_xdg_home $XDG_MUSIC_DIR Music | |
164 | fixup_xdg_home $XDG_PICTURES_DIR Pictures | |
165 | fixup_xdg_home $XDG_VIDEOS_DIR Videos | |
166 | ||
167 | cd "$old_pwd" |