about summary refs log tree commit diff stats
path: root/misc
diff options
context:
space:
mode:
Diffstat (limited to 'misc')
-rwxr-xr-xmisc277
1 files changed, 277 insertions, 0 deletions
diff --git a/misc b/misc new file mode 100755 index 0000000..f9aae4c --- /dev/null +++ b/misc
@@ -0,0 +1,277 @@
1#!/usr/bin/env bash
2# Manually Installed and Source-Compiled
3
4usage() {
5 cat >&2 <<EOF
6misc: install programs from source
7--- Usage:
8 misc -h
9 misc [-d] [-n] [-r DIR] [-p DIR] REPO ...
10--- Parameters:
11 REPO A program to pull from upstream, build, and install locally.
12--- Flags:
13 -h Show this help and exit.
14 -d DRY RUN: Don't do anything, just print what would happen.
15 -n NUKE: Delete REPO, then re-download and build.
16--- Options:
17 -r DIR Change the misc repo directory to DIR
18 (default: $MISC_REPO_ROOT).
19 -p DIR Change the directory to search for install plans
20 (default: $MISC_PLAN_ROOT).
21 -i DIR Change the PREFIX to use when installing programs
22 (default: $MISC_INSTALL_PREFIX).
23EOF
24}
25
26## Entry point
27
28main() {
29 config "$@"
30 shift $((OPTIND - 1))
31
32 (($# > 0)) || usage 1
33
34 [[ "$DEBUG" ]] && set -x
35
36 # Variables
37 MISC_PLAN="$1"
38 shift
39
40 MISC_FULL_PLAN="$MISC_PLAN_ROOT/$MISC_PLAN"
41 MISC_REPO="$MISC_REPO_ROOT/$MISC_PLAN"
42 MISC_DONE=
43
44 SOURCE=
45 CHECKOUT=master
46 CONFIGURE_ARGS=()
47 MISC_DEPENDENCIES=()
48 APT_DEPENDENCIES=(
49 build-essential
50 git
51 )
52
53 export LD_LIBRARY_PATH="$MISC_INSTALL_PREFIX/lib:$LD_LIBRARY_PATH"
54 export PKG_CONFIG_PATH="$MISC_INSTALL_PREFIX/lib/pkgconfig:$PKG_CONFIG_PATH"
55
56 # Check that plan exists
57 [[ -r "$MISC_FULL_PLAN" ]] ||
58 die 2 "Plan not found: \"$MISC_PLAN\""
59
60 _MISC_PREVIOUS_DIR="$PWD"
61 trap finish EXIT INT
62
63 if [[ ! "$PWD" == "$MISC_REPO_ROOT" ]]; then
64 mkdir -p "$MISC_REPO_ROOT"
65 run cd "$MISC_REPO_ROOT"
66 fi
67
68 . "$MISC_FULL_PLAN" ||
69 die "$?" "Error executing plan: \"$MISC_PLAN\""
70
71 # If the recipe is just variables, run the default plan
72 if [[ -z "$MISC_DONE" ]]; then
73 install_deps
74 repo_pull
75 repo_ready
76 configure || true # Not always have configure
77 make install
78 fi
79}
80
81config() {
82 MISC_CONFIG="${XDG_CONFIG_HOME:-$HOME/.config}/misc/misc.sh"
83 [[ -f "$MISC_CONFIG" ]] && . "$MISC_CONFIG"
84
85 MISC_REPO_ROOT="${MISC_ROOT:-$XDG_DATA_HOME/misc}"
86 MISC_PLAN_ROOT="${MISC_PLAN_ROOT:-$XDG_CONFIG_HOME/misc}"
87 MISC_INSTALL_PREFIX="${MISC_INSTALL_PREFIX:-$HOME/.local}"
88 _ARGS=()
89 _DRY_RUN=false
90 _NUKE=false
91 DEBUG=
92 while getopts :hdnvr:p:i: opt; do
93 case "$opt" in
94 h) usage ;;
95 n)
96 _NUKE=true
97 _ARGS+=(-n)
98 ;;
99 d)
100 _DRY_RUN=true
101 _ARGS+=(-d)
102 ;;
103 v)
104 DEBUG=true
105 _ARGS+=(-v)
106 ;;
107 r)
108 MISC_REPO_ROOT="$OPTARG"
109 _ARGS+=(-r "$OPTARG")
110 ;;
111 p)
112 MISC_PLAN_ROOT="$OPTARG"
113 _ARGS+=(-p "$OPTARG")
114 ;;
115 i)
116 MISC_INSTALL_PREFIX="$OPTARG"
117 _ARGS+=(-i "$OPTARG")
118 ;;
119 \?)
120 log "Unknown flag \"-$OPTARG\""
121 usage 1
122 ;;
123 esac
124 done
125}
126
127finish() {
128 cd "$_MISC_PREVIOUS_DIR"
129}
130
131## Utilities
132
133say() { # say WORD ...
134 printf '%s\n' "$*"
135}
136
137log() { # log WORD ...
138 say "$@" >&2
139}
140
141die() { # die CODE WORD ...
142 code="$1"
143 shift
144 log "$@"
145 exit "$code"
146}
147
148run() { # run COMMAND ...
149 log "$@"
150 if ! "$_DRY_RUN"; then
151 eval "$@"
152 fi
153}
154
155cmd() { # cmd COMMAND ...
156 log "$@"
157 if ! "$_DRY_RUN"; then
158 command "$@"
159 fi
160}
161
162with_repo() { # with_repo COMMAND ...
163 ## Run COMMAND in $MISC_REPO.
164 run cd "$MISC_REPO" || die 4 "No such directory \"$MISC_REPO\""
165 run "$@"
166}
167
168## Library
169
170install_deps() { # install_deps
171 for dep in "${MISC_DEPENDENCIES[@]}"; do
172 misc "${_ARGS[@]}" "$dep" ||
173 die 60 "Error installing dependency: \"$dep\""
174 done
175 if command -v apt >/dev/null 2>&1; then
176 for dep in "${APT_DEPENDENCIES[@]}"; do
177 # XXX: I don't like how hacky this is.
178 if [[ "$(apt list --installed "$dep" 2>/dev/null | wc -l)" -lt 2 ]]; then
179 sudo apt install "$dep" ||
180 die 65 "Error installing dependency: \"$dep\""
181 fi
182 done
183 fi
184}
185
186repo_pull() { # repo_pull [CHECKOUT]
187 ## Pull the latest CHECKOUT from $REPO.
188 MISC_DONE=1
189 local source checkout
190 checkout="${1:-$CHECKOUT}"
191
192 { [[ -n "$SOURCE" ]] || "$_DRY_RUN"; } ||
193 die 10 "No source specified for \"$MISC_PLAN\""
194
195 if [[ -d "$MISC_REPO" ]]; then
196 git pull origin "$checkout" ||
197 die "$?" "Error running 'git pull'"
198 git checkout "$checkout" ||
199 die "$?" "Error running 'git checkout'"
200 else
201 _git clone -b "$checkout" "$SOURCE" "$MISC_REPO" ||
202 die "$?" "Error running 'git clone'"
203 fi
204}
205
206repo_download_extract() { # repo_download_extract
207 run 'curl -RL "$SOURCE" | tar -zxf-'
208}
209
210repo_ready() { # repo_ready [TARGET ...]
211 ## Ready $MISC_ for building.
212 ## If TARGET ... is specified, they're passed to make; otherwise `make
213 ## clean` is run in the repo directory.
214 MISC_DONE=1
215 { [[ -d "$MISC_REPO" ]] || "$_DRY_RUN"; } ||
216 die 20 "No directory for \"$MISC_PLAN\""
217 make "${@:-clean}"
218 if git status >/dev/null 2>&1; then
219 git clean -dxf
220 fi
221}
222
223repo_nuke() { # repo_nuke
224 ## Fully remove $MISC_FULL_PLAN
225 { [[ -n "$MISC_REPO" ]] || "$_DRY_RUN"; } ||
226 die 40 "No directory to remove"
227 run rm -rf "$MISC_REPO"
228}
229
230## Commands (with arguments)
231
232make() {
233 MISC_DONE=1
234 cmd make \
235 -C "$MISC_REPO" \
236 PREFIX="$MISC_INSTALL_PREFIX" \
237 "$@"
238}
239_make() { cmd make "$@"; }
240
241make_install() {
242 MISC_DONE=1
243 if make "$@"; then
244 make install
245 else
246 die 23 "Make error in \"$MISC_PLAN\": $@"
247 fi
248}
249
250configure() {
251 MISC_DONE=1
252 if (($# == 0)); then
253 with_repo ./configure "${CONFIGURE_ARGS[@]}"
254 else
255 with_repo ./configure "$@"
256 fi
257}
258
259git() {
260 cmd git \
261 -C "$MISC_REPO" \
262 "$@"
263}
264_git() { cmd git "$@"; }
265
266tar() {
267 cmd tar \
268 -C "$MISC_REPO" \
269 "$@"
270}
271_tar() { cmd tar "$@"; }
272
273## Finally ...
274
275if [[ "${BASH_SOURCE[0]}" == "$0" ]]; then
276 main "$@"
277fi