#!/bin/sh -

dflt=".:$HOME/git/devops:$HOME/git/devops/gcp-iac/apps"
RUNME_PATH="${RUNME_PATH-$dflt}"

# runme - run an executable found relative to a base
# Steve Kinzler, steve@kinzler.com, Jun 23
# https://kinzler.com/me/home.html#unix

export RUNME_PATH="$RUNME_PATH_PRE:$RUNME_PATH:$RUNME_PATH_POST"

verbose=; nodo=; bad=
while :
do
	case $# in
	0)	break;;
	*)	case "$1" in
		-v)	verbose=$1;;
		-n)	nodo=here;;
		-N)	nodo=there;;

		--)	shift; break;;
		-h)	bad=t; break;;
		-*)	bad=t; echo "$0: unknown option ($1)" 1>&2;;
		*)	break;;
		esac
		shift;;
	esac
done

case "$#,$bad" in
0,*|*,?*)	cat <<EOF 1>&2
usage: $0 [ -v ] [ -n | -N ] base [ exec [ arg ... ] ]
	-v	print the command to be run
	-n	do not actually run the command
	-N	run the command but with RUNME_NODO set
path: $RUNME_PATH
If needed, the base is searched for in the above path, built from
RUNME_PATH_PRE:RUNME_PATH:RUNME_PATH_POST.  Relative to the first found
base, exec is the first executable file among (in this order):
	<base>/runme/<exec>
	<base>/runme-<exec>
	<base>/.runme-<exec>
	<base>/<exec>
	<basename>/runme/<exec>
	<basename>/runme-<exec>
	<basename>/.runme-<exec>
	<basename>/<exec>
basename is base without dot-suffixes.  exec is run with any given args,
RUNME_BASE set to the base, and RUNME_BASENAME set to the basename.
If no exec is supplied, the available ones will be listed.
EOF
		exit 1;;
*)		arg_base="$1"; shift;;
esac

base=`	case "$arg_base" in
	/*)	echo "$arg_base";;
	*)	echo "$RUNME_PATH" | tr : '\012' |
		while read dir
		do
			test -z "$dir" && continue
			test -e "$dir/$arg_base" && { echo "$dir/$arg_base";
						      break; }
		done;;
	esac`
test -n "$base" -a -e "$base" ||
	{ echo "$0: aborting, no base found ($arg_base)" 1>&2; exit 2; }
basename=`echo "$base" | sed 's/\([^\/]\)\.[^\/]*/\1/'`
export RUNME_BASE="$base" RUNME_BASENAME="$basename"

case "$#,$1" in
0,*|*,)	for e in "$base"/runme/*      "$base"/runme-*	  \
		 "$base"/.runme-*     "$base"/*
	do
		case "$e" in *\*) continue;; esac
		test -f "$e" -a -x "$e" && echo "$e"
	done
	test "$base" = "$basename" && exit
	for e in "$basename"/runme/*  "$basename"/runme-* \
		 "$basename"/.runme-* "$basename"/*
	do
		case "$e" in *\*) continue;; esac
		test -f "$e" -a -x "$e" && echo "$e"
	done
	exit;;
*)	arg_exe="$1"; shift;;
esac

exe=
for e in "$base/runme/$arg_exe"      "$base/runme-$arg_exe"	\
	 "$base/.runme-$arg_exe"     "$base/$arg_exe"		\
	 "$basename/runme/$arg_exe"  "$basename/runme-$arg_exe"	\
	 "$basename/.runme-$arg_exe" "$basename/$arg_exe"
do
	test -f "$e" -a -x "$e" && { exe="$e"; break; }
done

case "$exe" in
?*)	test -n "$verbose" && echo "$exe" "$@"
	case "$nodo" in
	here)	;;
	there)	export RUNME_NODO=true; exec "$exe" "$@";;
	*)				exec "$exe" "$@";;
	esac;;
*)	echo "$0: aborting, no exec found ($base $arg_exe)" 1>&2; exit 3;;
esac
