lib/run.sh

2.5 KB · 111 lines · bash

1#!/usr/bin/env bash
2
3brt_run_shell() {
4 local sh="${SHELL:-/bin/bash}"
5 local base="${sh##*/}"
6
7 case "$base" in
8 zsh) zsh -ic "$1" ;;
9 bash) bash -ic "$1" ;;
10 *) bash -c "$1" ;;
11 esac
12}
13
14brt_run_split_chain() {
15 local chain="$1"
16 local part
17 local IFS=';'
18 read -ra parts <<< "$chain"
19 for part in "${parts[@]}"; do
20 part="${part#"${part%%[![:space:]]*}"}"
21 part="${part%"${part##*[![:space:]]}"}"
22 [[ -n "$part" ]] || continue
23 printf '%s\0' "$part"
24 done
25}
26
27brt_run_build_script() {
28 local -a parts=("$@")
29 local part script="" idx=1
30
31 for part in "${parts[@]}"; do
32 if [[ "$part" =~ ^wait[[:space:]]+([0-9]+(\.[0-9]+)?)$ ]]; then
33 local secs="${BASH_REMATCH[1]}"
34 script+="printf '%b\\n' '\033[36m●\033[0m Waiting ${secs}s...'; sleep ${secs};"
35 continue
36 fi
37 if [[ "$part" == wait ]]; then
38 brt_error "wait requires seconds: wait 5"
39 exit 1
40 fi
41 script+="printf '%b\\n' '\033[36m●\033[0m [${idx}] ${part//\'/\'\\\'\'}';"
42 script+="${part};"
43 script+='_brt_run_rc=$?; if (( _brt_run_rc != 0 )); then exit $_brt_run_rc; fi;'
44 ((idx++))
45 done
46
47 printf '%s' "$script"
48}
49
50brt_run_from_args() {
51 local -a parts=()
52 local buf=""
53
54 while (($#)); do
55 if [[ "$1" == "wait" ]]; then
56 [[ -n "$buf" ]] && parts+=("$buf") && buf=""
57 if (( $# < 2 )) || ! [[ "$2" =~ ^[0-9]+(\.[0-9]+)?$ ]]; then
58 brt_error "wait requires seconds: brt -run ... wait 2 ..."
59 exit 1
60 fi
61 parts+=("wait $2")
62 shift 2
63 continue
64 fi
65 if [[ -n "$buf" ]]; then
66 buf+=" $1"
67 else
68 buf="$1"
69 fi
70 shift
71 done
72 [[ -n "$buf" ]] && parts+=("$buf")
73
74 printf '%s\0' "${parts[@]}"
75}
76
77brt_run() {
78 if (($# == 0)); then
79 brt_error 'Usage: brt -run <cmd;wait N;cmd...>'
80 echo 'Examples:'
81 echo " brt -run 'echo hi;wait 2;echo bye'"
82 echo ' brt -run echo hi wait 2 echo bye'
83 echo ' brt -run my_zsh_function wait 1 other_function'
84 exit 1
85 fi
86
87 brt_info "Running command chain..."
88
89 local -a parts=()
90 if (($# == 1)) && [[ "$1" == *";"* ]]; then
91 while IFS= read -r -d '' part; do
92 parts+=("$part")
93 done < <(brt_run_split_chain "$1")
94 else
95 while IFS= read -r -d '' part; do
96 parts+=("$part")
97 done < <(brt_run_from_args "$@")
98 fi
99
100 local script status
101 script=$(brt_run_build_script "${parts[@]}")
102 brt_run_shell "$script"
103 status=$?
104 if (( status != 0 )); then
105 brt_error "Command chain failed with exit code ${status}"
106 exit "$status"
107 fi
108
109 brt_ok "Chain completed"
110}
111