85 lines
1.7 KiB
Bash
Executable File
85 lines
1.7 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
|
|
set -euo pipefail
|
|
|
|
harness_candidate_shells() {
|
|
local shell
|
|
local -a shells=()
|
|
if [ -n "${SHELL:-}" ]; then
|
|
shells+=("$SHELL")
|
|
fi
|
|
shells+=(zsh bash)
|
|
|
|
local seen=""
|
|
for shell in "${shells[@]}"; do
|
|
if [ -z "$shell" ]; then
|
|
continue
|
|
fi
|
|
if ! command -v "$shell" >/dev/null 2>&1; then
|
|
continue
|
|
fi
|
|
shell="$(command -v "$shell")"
|
|
case ":$seen:" in
|
|
*":$shell:"*) continue ;;
|
|
esac
|
|
seen="${seen:+$seen:}$shell"
|
|
printf "%s\n" "$shell"
|
|
done
|
|
}
|
|
|
|
harness_find_cmd() {
|
|
local cmd="$1"
|
|
if [[ ! "$cmd" =~ ^[A-Za-z0-9_.+-]+$ ]]; then
|
|
printf "invalid command name: %s\n" "$cmd" >&2
|
|
return 2
|
|
fi
|
|
|
|
local found=""
|
|
found="$(command -v "$cmd" 2>/dev/null || true)"
|
|
if [ -n "$found" ] && [ -x "$found" ]; then
|
|
printf "%s\n" "$found"
|
|
return 0
|
|
fi
|
|
|
|
local shell
|
|
while IFS= read -r shell; do
|
|
found="$("$shell" -lic "command -v $cmd" 2>/dev/null | sed -n '1p' || true)"
|
|
if [ -n "$found" ] && [ -x "$found" ]; then
|
|
printf "%s\n" "$found"
|
|
return 0
|
|
fi
|
|
done < <(harness_candidate_shells)
|
|
|
|
return 1
|
|
}
|
|
|
|
harness_require_tool() {
|
|
local cmd="$1"
|
|
local found
|
|
if ! found="$(harness_find_cmd "$cmd")"; then
|
|
printf "missing required command: %s\n" "$cmd" >&2
|
|
printf "looked in the current non-interactive PATH and login interactive shells\n" >&2
|
|
return 1
|
|
fi
|
|
harness_prepend_tool_dir "$found"
|
|
printf "%s\n" "$found"
|
|
}
|
|
|
|
harness_prepend_tool_dir() {
|
|
local path="$1"
|
|
local dir
|
|
dir="$(dirname "$path")"
|
|
case ":$PATH:" in
|
|
*":$dir:"*) ;;
|
|
*)
|
|
PATH="$dir:$PATH"
|
|
export PATH
|
|
;;
|
|
esac
|
|
}
|
|
|
|
harness_run() {
|
|
printf "+ %s\n" "$*" >&2
|
|
"$@"
|
|
}
|