diff options
-rw-r--r-- | Makefile | 10 | ||||
-rw-r--r-- | bash/bash_logout (renamed from bootstrap/bash_logout) | 0 | ||||
-rw-r--r-- | bash/bash_profile (renamed from bootstrap/bash_profile) | 0 | ||||
-rw-r--r-- | bash/bashrc (renamed from bootstrap/bashrc) | 0 | ||||
-rw-r--r-- | bootstrap.manifest | 19 | ||||
-rwxr-xr-x | bootstrap.sh | 195 | ||||
-rw-r--r-- | profile/profile (renamed from bootstrap/profile) | 10 |
7 files changed, 219 insertions, 15 deletions
diff --git a/Makefile b/Makefile deleted file mode 100644 index 712877b..0000000 --- a/Makefile +++ /dev/null | |||
@@ -1,10 +0,0 @@ | |||
1 | # ~/etc/ Makefile | ||
2 | |||
3 | BOOTSTRAPS:=$(wildcard bootstrap/*) | ||
4 | BOOTSTRAPS_OUT:=$(foreach b,$(BOOTSTRAPS),$(patsubst bootstrap/%,~/.%,$(b))) | ||
5 | |||
6 | .PHONY: bootstrap | ||
7 | bootstrap: $(BOOTSTRAPS_OUT) | ||
8 | |||
9 | ~/.%: bootstrap/% | ||
10 | ln -sf etc/$< $@ | ||
diff --git a/bootstrap/bash_logout b/bash/bash_logout index d6c9b7a..d6c9b7a 100644 --- a/bootstrap/bash_logout +++ b/bash/bash_logout | |||
diff --git a/bootstrap/bash_profile b/bash/bash_profile index 4439ca7..4439ca7 100644 --- a/bootstrap/bash_profile +++ b/bash/bash_profile | |||
diff --git a/bootstrap/bashrc b/bash/bashrc index 4966e75..4966e75 100644 --- a/bootstrap/bashrc +++ b/bash/bashrc | |||
diff --git a/bootstrap.manifest b/bootstrap.manifest new file mode 100644 index 0000000..7c83a5c --- /dev/null +++ b/bootstrap.manifest | |||
@@ -0,0 +1,19 @@ | |||
1 | ### bootstrap.manifest -*- conf -*- | ||
2 | # TAB-separated SOURCEs and DESTINATIONs for configuration-file links to ~. | ||
3 | # see bootstrap.sh for details. | ||
4 | |||
5 | # Custom XDG Directories (just in case they're hardcoded somewhere) | ||
6 | ~/etc ~/.config | ||
7 | ~/usr ~/.local | ||
8 | |||
9 | # Bash | ||
10 | bash/bashrc ~/.bashrc | ||
11 | bash/bash_profile ~/.bash_profile | ||
12 | bash/bash_logout ~/.bash_logout | ||
13 | |||
14 | # Profile | ||
15 | profile/profile ~/.profile | ||
16 | |||
17 | # Local Variables: | ||
18 | # indent-tabs-mode: t | ||
19 | # End: | ||
diff --git a/bootstrap.sh b/bootstrap.sh new file mode 100755 index 0000000..d37ef6a --- /dev/null +++ b/bootstrap.sh | |||
@@ -0,0 +1,195 @@ | |||
1 | #!/bin/sh | ||
2 | # Bootstrap file for XDG_CONFIG_HOME | ||
3 | # by Case Duckworth <acdw@acdw.net> | ||
4 | |||
5 | ### License: | ||
6 | |||
7 | # Everyone is permitted to do whatever with this software, without | ||
8 | # limitation. This software comes without any warranty whatsoever, | ||
9 | # but with two pieces of advice: | ||
10 | # - Don't hurt yourself. | ||
11 | # - Make good choices. | ||
12 | |||
13 | ### Commentary: | ||
14 | |||
15 | # For some time now, there has been a standard place to put configuration files | ||
16 | # for various programs: $XDG_CONFIG_HOME. Slowly but surely, programs have | ||
17 | # been adapting to that standard for their configuration files, but there have | ||
18 | # been some stubborn holdouts. Examples include shells such as sh, bash, and | ||
19 | # zsh. | ||
20 | |||
21 | # Luckily, the filesystem can help us. This script takes input from a file in | ||
22 | # its $PWD, bootstrap.manifest, and reads linking directions from tab-delimited | ||
23 | # lines in that file. Then, it creates links from within the cozy confines of | ||
24 | # $XDG_CONFIG_HOME to the wild west of ~, so that everyone is happy: you have | ||
25 | # your zen garden of configuration, and misbehaving programs have their bazaar. | ||
26 | |||
27 | ### Code: | ||
28 | |||
29 | ### Main entry point | ||
30 | |||
31 | main() { | ||
32 | ## Sanity checking | ||
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 | ||
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 | ||
37 | # you're doing! | ||
38 | |||
39 | case "$0" in | ||
40 | ./*) ;; # this is the way bootstrap.sh /should/ be run. | ||
41 | *) | ||
42 | printf >&2 'Weird invocation! %s\n' "$*" | ||
43 | printf >&2 'Try: cd <bootstrap-dir>; ./bootstrap.sh\n' | ||
44 | exit 127 | ||
45 | ;; | ||
46 | esac | ||
47 | |||
48 | ## Variables | ||
49 | |||
50 | # option: -d/--dry-run | ||
51 | : "${BOOTSTRAP_ACTION:=link}" | ||
52 | # option: -v/--verbose | ||
53 | : "${BOOTSTRAP_DEBUG:=false}" | ||
54 | # option: -k/--keep-going | ||
55 | : "${BOOTSTRAP_QUIT_ON_ERROR:=true}" | ||
56 | # option: -m/--manifest FILE | ||
57 | : "${BOOTSTRAP_MANIFEST_FILE:=bootstrap.manifest}" | ||
58 | # option: -- (rest are passed to ln) | ||
59 | : "${BOOTSTRAP_LN_ARGS:=-s}" | ||
60 | |||
61 | ## Handle command-line flags | ||
62 | # Basically an easier way of setting the above variables. | ||
63 | while [ -n "$1" ]; do | ||
64 | case "$1" in | ||
65 | -h|--help) | ||
66 | cat >&2 <<END_HELP | ||
67 | Usage: ./bootstrap.sh [-d] [-v] [-k] [-m FILE] [-f] [-- LN_OPTS] | ||
68 | OPTIONS: | ||
69 | -d, --dry-run | ||
70 | Only print what would happen. | ||
71 | -v, --verbose | ||
72 | Be more verbose about things. | ||
73 | -k, --keep-going | ||
74 | Keep going after an error. | ||
75 | -f, --force | ||
76 | Force linking. Passes -f to ln. | ||
77 | -m FILE, --manifest FILE | ||
78 | Use FILE as manifest. | ||
79 | Default: bootstrap.manifest. | ||
80 | -- Signify end of options. The rest are passed to ln. | ||
81 | END_HELP | ||
82 | exit | ||
83 | ;; | ||
84 | -d|--dry-run) | ||
85 | BOOTSTRAP_ACTION=print | ||
86 | shift 1 | ||
87 | ;; | ||
88 | -v|--verbose) | ||
89 | BOOTSTRAP_DEBUG=true | ||
90 | shift 1 | ||
91 | ;; | ||
92 | -k|--keep-going) | ||
93 | BOOTSTRAP_QUIT_ON_ERROR=false | ||
94 | shift 1 | ||
95 | ;; | ||
96 | -m|--manifest) | ||
97 | case "$2" in | ||
98 | ''|-*) | ||
99 | printf >&2 "Bad argument: '$2'" | ||
100 | exit 129 | ||
101 | ;; | ||
102 | esac | ||
103 | BOOTSTRAP_MANIFEST_FILE="$2" | ||
104 | shift 2 | ||
105 | ;; | ||
106 | -f|--force) | ||
107 | BOOTSTRAP_LN_ARGS="$BOOTSTRAP_LN_ARGS -f" | ||
108 | shift 1 | ||
109 | ;; | ||
110 | --) | ||
111 | BOOTSTRAP_LN_ARGS="$@" | ||
112 | break | ||
113 | ;; | ||
114 | esac | ||
115 | done | ||
116 | |||
117 | ## Main loop | ||
118 | while IFS=' ' read -r source destination; do | ||
119 | # Ignore lines beginning with '#' | ||
120 | case "$source" in | ||
121 | '#'*) | ||
122 | if "$BOOTSTRAP_DEBUG"; then | ||
123 | printf >&2 'Skipping comment: %s %s\n' \ | ||
124 | "$source" "$destination" | ||
125 | fi | ||
126 | continue | ||
127 | ;; | ||
128 | esac | ||
129 | |||
130 | # Ignore empty lines, or lines with only SOURCE or DESTINATION | ||
131 | if [ -z "$source" ] || [ -z "$destination" ]; then | ||
132 | if "$BOOTSTRAP_DEBUG"; then | ||
133 | printf >&2 'Skipping line: %s\t%s\n' \ | ||
134 | "$source" "$destination" | ||
135 | fi | ||
136 | continue | ||
137 | fi | ||
138 | |||
139 | # Do the thing | ||
140 | if ! dispatch "$source" "$destination"; then | ||
141 | printf >&2 'ERROR: %s -> %s\n' \ | ||
142 | "$source" "$destination" | ||
143 | if "$BOOTSTRAP_QUIT_ON_ERROR"; then | ||
144 | exit "$dispatch_error" | ||
145 | fi | ||
146 | fi | ||
147 | done < "$BOOTSTRAP_MANIFEST_FILE" | ||
148 | } | ||
149 | |||
150 | |||
151 | ### Functions | ||
152 | |||
153 | dispatch() { # dispatch SOURCE DESTINATION | ||
154 | # Depending on environment variables, do the linking or displaying or | ||
155 | # whatever of a source and a destination. | ||
156 | |||
157 | ## Variables | ||
158 | |||
159 | src="$1" | ||
160 | dest="$2" | ||
161 | dispatch_error=0 # success | ||
162 | |||
163 | ## Sanitize pathnames | ||
164 | |||
165 | # If the SOURCE starts with ~, /, or $, keep it as-is; otherwise, | ||
166 | # prepend "$PWD/". | ||
167 | case "$src" in | ||
168 | '/'* | '~'* | '$'* ) ;; | ||
169 | *) src="$PWD/$src" ;; | ||
170 | esac | ||
171 | |||
172 | # Convert ~ to $HOME in SOURCE and DESTINATION, to get around shell | ||
173 | # quoting rules. | ||
174 | src="$(printf '%s\n' "$src" | sed "s#^~#$HOME#")" | ||
175 | dest="$(printf '%s\n' "$dest" | sed "s#^~#$HOME#")" | ||
176 | |||
177 | ## Do the thing | ||
178 | |||
179 | # /Always/ tell the user what we're doing. | ||
180 | printf >&2 "ln %s %s %s\n" "$BOOTSTRAP_LN_ARGS" "$src" "$dest" | ||
181 | |||
182 | case "$BOOTSTRAP_ACTION" in | ||
183 | link) # actually ... do the links | ||
184 | ln $BOOTSTRAP_LN_ARGS "$src" "$dest" || | ||
185 | dispatch_error="$?" | ||
186 | ;; | ||
187 | print) ;; # already printed. | ||
188 | esac | ||
189 | |||
190 | return "$dispatch_error" | ||
191 | } | ||
192 | |||
193 | ### Do the thing | ||
194 | |||
195 | main "$@" | ||
diff --git a/bootstrap/profile b/profile/profile index 4cb459d..7a86c76 100644 --- a/bootstrap/profile +++ b/profile/profile | |||
@@ -1,5 +1,5 @@ | |||
1 | # profile | 1 | # ~/.profile -*- sh -*- |
2 | # vim:ft=sh | 2 | # vim: ft=sh |
3 | 3 | ||
4 | # XDG directories | 4 | # XDG directories |
5 | export XDG_CONFIG_HOME="$HOME/etc" | 5 | export XDG_CONFIG_HOME="$HOME/etc" |
@@ -11,7 +11,7 @@ export XDG_CONFIG_DIRS="${XDG_CONFIG_DIRS:-/etc/xdg}" | |||
11 | 11 | ||
12 | # source files in $XDG_CONFIG_HOME/profile | 12 | # source files in $XDG_CONFIG_HOME/profile |
13 | if [ -d "$XDG_CONFIG_HOME/profile" ]; then | 13 | if [ -d "$XDG_CONFIG_HOME/profile" ]; then |
14 | for file in "$XDG_CONFIG_HOME"/profile/*.sh; do | 14 | for file in "$XDG_CONFIG_HOME"/profile/*.sh; do |
15 | [ -r "$file" ] && . "$file" | 15 | [ -r "$file" ] && . "$file" |
16 | done | 16 | done |
17 | fi | 17 | fi |