diff options
Diffstat (limited to 'bootstrap.sh')
-rwxr-xr-x | bootstrap.sh | 294 |
1 files changed, 147 insertions, 147 deletions
diff --git a/bootstrap.sh b/bootstrap.sh index 12d0b9a..b0fcb87 100755 --- a/bootstrap.sh +++ b/bootstrap.sh | |||
@@ -29,41 +29,41 @@ | |||
29 | ### Main entry point | 29 | ### Main entry point |
30 | 30 | ||
31 | main() { | 31 | main() { |
32 | ## Sanity checking | 32 | ## Sanity checking |
33 | # Since bootstrap.sh does some naive path-mangling, let's show an error | 33 | # Since bootstrap.sh does some naive path-mangling, let's show an error |
34 | # if it's not run correctly. Yes, there are other ways to run a | 34 | # if it's not run correctly. Yes, there are other ways to run a |
35 | # script. But this script should ideally be run, like, one time. Also | 35 | # script. But this script should ideally be run, like, one time. Also |
36 | # you can obviously comment this out or change it if you know what | 36 | # you can obviously comment this out or change it if you know what |
37 | # you're doing! | 37 | # you're doing! |
38 | 38 | ||
39 | case "$0" in | 39 | case "$0" in |
40 | ./*) ;; # this is the way bootstrap.sh /should/ be run. | 40 | ./*) ;; # this is the way bootstrap.sh /should/ be run. |
41 | *) | 41 | *) |
42 | printf >&2 'Weird invocation! %s\n' "$*" | 42 | printf >&2 'Weird invocation! %s\n' "$*" |
43 | printf >&2 'Try: cd <bootstrap-dir>; ./bootstrap.sh\n' | 43 | printf >&2 'Try: cd <bootstrap-dir>; ./bootstrap.sh\n' |
44 | exit 127 | 44 | exit 127 |
45 | ;; | 45 | ;; |
46 | esac | 46 | esac |
47 | 47 | ||
48 | ## Variables | 48 | ## Variables |
49 | 49 | ||
50 | # option: -d/--dry-run | 50 | # option: -d/--dry-run |
51 | : "${BOOTSTRAP_ACTION:=link}" | 51 | : "${BOOTSTRAP_ACTION:=link}" |
52 | # option: -v/--verbose | 52 | # option: -v/--verbose |
53 | : "${BOOTSTRAP_DEBUG:=false}" | 53 | : "${BOOTSTRAP_DEBUG:=false}" |
54 | # option: -k/--keep-going | 54 | # option: -k/--keep-going |
55 | : "${BOOTSTRAP_QUIT_ON_ERROR:=true}" | 55 | : "${BOOTSTRAP_QUIT_ON_ERROR:=true}" |
56 | # option: -m/--manifest FILE | 56 | # option: -m/--manifest FILE |
57 | : "${BOOTSTRAP_MANIFEST_FILE:=bootstrap.manifest}" | 57 | : "${BOOTSTRAP_MANIFEST_FILE:=bootstrap.manifest}" |
58 | # option: -- (rest are passed to ln) | 58 | # option: -- (rest are passed to ln) |
59 | : "${BOOTSTRAP_LN_ARGS:=-s}" | 59 | : "${BOOTSTRAP_LN_ARGS:=-s}" |
60 | 60 | ||
61 | ## Handle command-line flags | 61 | ## Handle command-line flags |
62 | # Basically an easier way of setting the above variables. | 62 | # Basically an easier way of setting the above variables. |
63 | while [ -n "$1" ]; do | 63 | while [ -n "$1" ]; do |
64 | case "$1" in | 64 | case "$1" in |
65 | -h|--help) | 65 | -h | --help) |
66 | cat >&2 <<END_HELP | 66 | cat >&2 <<END_HELP |
67 | Usage: ./bootstrap.sh [-d] [-v] [-k] [-m FILE] [-f] [-- LN_OPTS] | 67 | Usage: ./bootstrap.sh [-d] [-v] [-k] [-m FILE] [-f] [-- LN_OPTS] |
68 | OPTIONS: | 68 | OPTIONS: |
69 | -d, --dry-run | 69 | -d, --dry-run |
@@ -79,123 +79,123 @@ OPTIONS: | |||
79 | Default: bootstrap.manifest. | 79 | Default: bootstrap.manifest. |
80 | -- Signify end of options. The rest are passed to ln. | 80 | -- Signify end of options. The rest are passed to ln. |
81 | END_HELP | 81 | END_HELP |
82 | exit | 82 | exit |
83 | ;; | 83 | ;; |
84 | -d|--dry-run) | 84 | -d | --dry-run) |
85 | BOOTSTRAP_ACTION=print | 85 | BOOTSTRAP_ACTION=print |
86 | shift 1 | 86 | shift 1 |
87 | ;; | 87 | ;; |
88 | -v|--verbose) | 88 | -v | --verbose) |
89 | BOOTSTRAP_DEBUG=true | 89 | BOOTSTRAP_DEBUG=true |
90 | shift 1 | 90 | shift 1 |
91 | ;; | 91 | ;; |
92 | -k|--keep-going) | 92 | -k | --keep-going) |
93 | BOOTSTRAP_QUIT_ON_ERROR=false | 93 | BOOTSTRAP_QUIT_ON_ERROR=false |
94 | shift 1 | 94 | shift 1 |
95 | ;; | 95 | ;; |
96 | -m|--manifest) | 96 | -m | --manifest) |
97 | case "$2" in | 97 | case "$2" in |
98 | ''|-*) | 98 | '' | -*) |
99 | printf >&2 "Bad argument: '$2'" | 99 | printf >&2 "Bad argument: '$2'" |
100 | exit 129 | 100 | exit 129 |
101 | ;; | 101 | ;; |
102 | esac | 102 | esac |
103 | BOOTSTRAP_MANIFEST_FILE="$2" | 103 | BOOTSTRAP_MANIFEST_FILE="$2" |
104 | shift 2 | 104 | shift 2 |
105 | ;; | 105 | ;; |
106 | -f|--force) | 106 | -f | --force) |
107 | BOOTSTRAP_LN_ARGS="$BOOTSTRAP_LN_ARGS -f" | 107 | BOOTSTRAP_LN_ARGS="$BOOTSTRAP_LN_ARGS -f" |
108 | shift 1 | 108 | shift 1 |
109 | ;; | 109 | ;; |
110 | --) | 110 | --) |
111 | shift 1 | 111 | shift 1 |
112 | BOOTSTRAP_LN_ARGS="$@" | 112 | BOOTSTRAP_LN_ARGS="$@" |
113 | break | 113 | break |
114 | ;; | 114 | ;; |
115 | esac | 115 | esac |
116 | done | 116 | done |
117 | 117 | ||
118 | ## Main loop | 118 | ## Main loop |
119 | while IFS=' ' read -r source destination; do | 119 | while IFS=' ' read -r source destination; do |
120 | # Ignore lines beginning with '#' | 120 | # Ignore lines beginning with '#' |
121 | case "$source" in | 121 | case "$source" in |
122 | '#'*) | 122 | '#'*) |
123 | if "$BOOTSTRAP_DEBUG"; then | 123 | if "$BOOTSTRAP_DEBUG"; then |
124 | printf >&2 '%s %s\n' \ | 124 | printf >&2 '%s %s\n' \ |
125 | "$source" "$destination" | 125 | "$source" "$destination" |
126 | fi | 126 | fi |
127 | continue | 127 | continue |
128 | ;; | 128 | ;; |
129 | esac | 129 | esac |
130 | 130 | ||
131 | # Ignore empty lines, or lines with only SOURCE or DESTINATION | 131 | # Ignore empty lines, or lines with only SOURCE or DESTINATION |
132 | if [ -z "$source" ] || [ -z "$destination" ]; then | 132 | if [ -z "$source" ] || [ -z "$destination" ]; then |
133 | if "$BOOTSTRAP_DEBUG"; then | 133 | if "$BOOTSTRAP_DEBUG"; then |
134 | printf >&2 'Skipping line: %s\t%s\n' \ | 134 | printf >&2 'Skipping line: %s\t%s\n' \ |
135 | "$source" "$destination" | 135 | "$source" "$destination" |
136 | fi | 136 | fi |
137 | continue | 137 | continue |
138 | fi | 138 | fi |
139 | 139 | ||
140 | # Do the thing | 140 | # Do the thing |
141 | if ! dispatch "$source" "$destination"; then | 141 | if ! dispatch "$source" "$destination"; then |
142 | printf >&2 'ERROR: %s -> %s\n' \ | 142 | printf >&2 'ERROR: %s -> %s\n' \ |
143 | "$source" "$destination" | 143 | "$source" "$destination" |
144 | if "$BOOTSTRAP_QUIT_ON_ERROR"; then | 144 | if "$BOOTSTRAP_QUIT_ON_ERROR"; then |
145 | exit "$dispatch_error" | 145 | exit "$dispatch_error" |
146 | fi | 146 | fi |
147 | fi | 147 | fi |
148 | done < "$BOOTSTRAP_MANIFEST_FILE" | 148 | done <"$BOOTSTRAP_MANIFEST_FILE" |
149 | } | 149 | } |
150 | 150 | ||
151 | ### Functions | 151 | ### Functions |
152 | 152 | ||
153 | dispatch() { # dispatch SOURCE DESTINATION | 153 | dispatch() { # dispatch SOURCE DESTINATION |
154 | # Depending on environment variables, do the linking or displaying or | 154 | # Depending on environment variables, do the linking or displaying or |
155 | # whatever of a source and a destination. | 155 | # whatever of a source and a destination. |
156 | 156 | ||
157 | ## Variables | 157 | ## Variables |
158 | 158 | ||
159 | src="$1" | 159 | src="$1" |
160 | dest="$2" | 160 | dest="$2" |
161 | dispatch_error=0 # success | 161 | dispatch_error=0 # success |
162 | 162 | ||
163 | ## Sanitize pathnames | 163 | ## Sanitize pathnames |
164 | 164 | ||
165 | # If the SOURCE starts with ~, /, or $, keep it as-is; otherwise, | 165 | # If the SOURCE starts with ~, /, or $, keep it as-is; otherwise, |
166 | # prepend "$PWD/". | 166 | # prepend "$PWD/". |
167 | case "$src" in | 167 | case "$src" in |
168 | '/'* | '~'* | '$'* ) ;; | 168 | '/'* | '~'* | '$'*) ;; |
169 | *) src="$PWD/$src" ;; | 169 | *) src="$PWD/$src" ;; |
170 | esac | 170 | esac |
171 | 171 | ||
172 | # Convert ~ to $HOME in SOURCE and DESTINATION, to get around shell | 172 | # Convert ~ to $HOME in SOURCE and DESTINATION, to get around shell |
173 | # quoting rules. | 173 | # quoting rules. |
174 | src="$(printf '%s\n' "$src" | sed "s#^~#$HOME#")" | 174 | src="$(printf '%s\n' "$src" | sed "s#^~#$HOME#")" |
175 | dest="$(printf '%s\n' "$dest" | sed "s#^~#$HOME#")" | 175 | dest="$(printf '%s\n' "$dest" | sed "s#^~#$HOME#")" |
176 | 176 | ||
177 | ## Do the thing | 177 | ## Do the thing |
178 | 178 | ||
179 | # /Always/ tell the user what we're doing. | 179 | # /Always/ tell the user what we're doing. |
180 | if [ -f "$dest" ]; then | 180 | if [ -f "$dest" ]; then |
181 | printf >&2 'mv %s %s.old\n' "$dest" "$dest" | 181 | printf >&2 'mv %s %s.old\n' "$dest" "$dest" |
182 | fi | 182 | fi |
183 | printf >&2 "ln %s %s %s\n" "$BOOTSTRAP_LN_ARGS" "$src" "$dest" | 183 | printf >&2 "ln %s %s %s\n" "$BOOTSTRAP_LN_ARGS" "$src" "$dest" |
184 | 184 | ||
185 | case "$BOOTSTRAP_ACTION" in | 185 | case "$BOOTSTRAP_ACTION" in |
186 | link) # actually ... do the links | 186 | link) # actually ... do the links |
187 | # if DESTINATION exists, move it to DESTINATION.old | 187 | # if DESTINATION exists, move it to DESTINATION.old |
188 | if [ -f "$dest" ]; then | 188 | if [ -f "$dest" ]; then |
189 | mv "$dest" "$dest.old" | 189 | mv "$dest" "$dest.old" |
190 | fi | 190 | fi |
191 | 191 | ||
192 | ln $BOOTSTRAP_LN_ARGS "$src" "$dest" || | 192 | ln $BOOTSTRAP_LN_ARGS "$src" "$dest" || |
193 | dispatch_error="$?" | 193 | dispatch_error="$?" |
194 | ;; | 194 | ;; |
195 | print) ;; # already printed. | 195 | print) ;; # already printed. |
196 | esac | 196 | esac |
197 | 197 | ||
198 | return "$dispatch_error" | 198 | return "$dispatch_error" |
199 | } | 199 | } |
200 | 200 | ||
201 | ### Do the thing | 201 | ### Do the thing |