about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--examples/emacs37
-rw-r--r--examples/golang2
-rw-r--r--examples/keepassxc27
-rw-r--r--examples/lieer21
-rw-r--r--examples/notmuch8
-rw-r--r--examples/tree-sitter4
-rwxr-xr-xmisc277
7 files changed, 376 insertions, 0 deletions
diff --git a/examples/emacs b/examples/emacs new file mode 100644 index 0000000..e7348db --- /dev/null +++ b/examples/emacs
@@ -0,0 +1,37 @@
1# misc :: Emacs -*- bash-ts -*-
2
3# Variables
4
5SOURCE=git://git.sv.gnu.org/emacs.git
6CHECKOUT=emacs-29
7
8CONFIGURE_ARGS=(
9 --prefix="$MISC_INSTALL_PREFIX"
10 --with-cairo
11 --with-file-notification=inotify
12 --with-imagemagick
13 --with-json
14 --with-native-compilation=aot # Emacs 29
15 --with-tree-sitter=yes # requires tree-sitter
16 --with-x
17 --with-x-toolkit=lucid
18 --with-xinput2
19 --with-xml2
20 # --with-xwidgets # requires gtk3
21 --without-gconf
22 --without-gsettings
23)
24
25MISC_DEPENDENCIES=(
26 tree-sitter
27)
28
29# Plan
30
31install_deps
32repo_pull
33repo_ready extraclean
34
35with_repo ./autogen.sh
36configure
37make_install bootstrap
diff --git a/examples/golang b/examples/golang new file mode 100644 index 0000000..65265be --- /dev/null +++ b/examples/golang
@@ -0,0 +1,2 @@
1# golang -*- bash-ts -*-
2
diff --git a/examples/keepassxc b/examples/keepassxc new file mode 100644 index 0000000..cd3cf42 --- /dev/null +++ b/examples/keepassxc
@@ -0,0 +1,27 @@
1# keepassxc -*- bash-ts -*-
2
3SOURCE=https://github.com/keepassxreboot/keepassxc.git
4
5# This is a cmake program
6
7CMAKE_ARGS=(
8 -DCMAKE_INSTALL_PREFIX="$MISC_INSTALL_PREFIX"
9 -DCMAKE_BUILD_TYPE="Release"
10 # Features
11 -DWITH_XC_AUTOTYPE="ON" # Auto-Type
12 -DWITH_XC_YUBIKEY="OFF" # YubiKey HMAC-SHA1 authentication support
13 -DWITH_XC_BROWSER="ON" # KeePassXC-Browser extension support
14 -DWITH_XC_NETWORKING="ON" # Networking support
15 -DWITH_XC_SSHAGENT="ON" # SSHAgent support
16 -DWITH_XC_FDOSECRETS="ON" # Freedesktop.org Secrets Service support
17 -DWITH_XC_KEESHARE="OFF" # KeeShare group synchronization extension
18 -DWITH_XC_UPDATECHECK="OFF" # Enable/Disable automatic updating checking
19)
20
21# Plan
22
23repo_pull latest
24repo_ready
25
26with_repo '{ mkdir build; cd build; cmake "${CMAKE_ARGS[@]}" ..; }'
27_make install
diff --git a/examples/lieer b/examples/lieer new file mode 100644 index 0000000..6c90e64 --- /dev/null +++ b/examples/lieer
@@ -0,0 +1,21 @@
1# lieer -*- bash-ts -*-
2
3SOURCE=https://github.com/gauteh/lieer
4
5APT_DEPENDENCIES=(
6 python3
7 libnotmuch-dev
8 # hopefully pip will install the rest
9)
10
11# Don't error when we don't have a virtualenv.
12export PIP_REQUIRE_VIRTUALENV=false
13
14# Plan
15
16install_deps
17repo_pull
18repo_ready
19
20with_repo pip3 install --user .
21
diff --git a/examples/notmuch b/examples/notmuch new file mode 100644 index 0000000..00db730 --- /dev/null +++ b/examples/notmuch
@@ -0,0 +1,8 @@
1# notmuch -*- bash-ts -*-
2
3SOURCE=https://git.notmuchmail.org/git/notmuch
4
5CONFIGURE_ARGS=(
6 --prefix="$MISC_INSTALL_PREFIX"
7)
8
diff --git a/examples/tree-sitter b/examples/tree-sitter new file mode 100644 index 0000000..55c723e --- /dev/null +++ b/examples/tree-sitter
@@ -0,0 +1,4 @@
1# Tree-sitter -*- bash-ts -*-
2
3SOURCE="https://github.com/tree-sitter/tree-sitter.git"
4
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