Files
scwrypts/run
T

354 lines
9.7 KiB
Bash
Raw Normal View History

2022-08-01 15:53:40 -06:00
#!/bin/zsh
2022-08-09 17:42:31 -06:00
export EXECUTION_DIR=$(pwd)
2023-02-21 18:44:27 -07:00
source "${0:a:h}/zsh/lib/import.driver.zsh" || exit 42
2022-08-09 17:42:31 -06:00
2022-08-01 15:53:40 -06:00
#####################################################################
__RUN() {
local USAGE='
2023-12-11 17:07:09 -07:00
usage: scwrypts [... options ...] [patterns] -- [...script options...]
options:
selection
-m, --name <scwrypt-name> only run the script if there is an exact match
(requires type and group)
-g, --group <group-name> only use scripts from the indicated group
-t, --type <type-name> only use scripts of the indicated type
runtime
-y, --yes auto-accept all [yn] prompts through current scwrypt
-e, --env <env-name> set environment; overwrites SCWRYPTS_ENV
-q, --quiet run in quiet mode
-n, --no-log skip the log file and run in quiet mode
-v, --verbose override quiet mode settings and print all debug dialogue
alternate commands
-h, --help display this message and exit
-l, --list print out command list and exit
--list-envs print out environment list and exit
--update update scwrypts library to latest version
--version print out scwrypts version and exit
patterns:
- a list of glob patterns to loose-match a scwrypt by name
script options:
- everything after "--" is forwarded to the scwrypt you run
(usually "-- --help" will provide more information)
2022-08-15 18:30:37 -06:00
'
2022-08-01 15:53:40 -06:00
cd "$SCWRYPTS_ROOT"
local ENV_NAME="$SCWRYPTS_ENV"
local SEARCH_PATTERNS=()
2023-02-21 18:44:27 -07:00
local VARSPLIT SEARCH_GROUP SEARCH_TYPE SEARCH_NAME
2023-12-11 17:07:09 -07:00
local ALLOW_LOGFILE=1
local VERBOSE=1
[ $CI ] && [ ! $SCWRYPTS_CI_FORCE_NON_VERBOSE ] && VERBOSE=2
2022-08-15 18:30:37 -06:00
local ERROR=0
2022-08-01 15:53:40 -06:00
while [[ $# -gt 0 ]]
do
case $1 in
2023-02-21 18:44:27 -07:00
-[a-z][a-z]* )
VARSPLIT=$(echo "$1 " | sed 's/^\(-.\)\(.*\) /\1 -\2/')
set -- $(echo " $VARSPLIT ") ${@:2}
;;
2023-11-22 15:54:16 -07:00
2023-12-11 17:07:09 -07:00
-h | --help ) USAGE; return 0 ;;
-l | --list ) SCWRYPTS__GET_AVAILABLE_SCWRYPTS; return 0 ;;
--list-envs ) SCWRYPTS__GET_ENV_NAMES; return 0 ;;
--version )
echo scwrypts $(git -C "$SCWRYPTS__ROOT__scwrypts" describe --tags)
2022-08-01 15:53:40 -06:00
return 0
;;
2023-11-22 15:54:16 -07:00
2023-02-21 18:44:27 -07:00
--update )
cd "$SCWRYPTS__ROOT__scwrypts"
git fetch --quiet origin main
2023-08-24 17:09:30 -06:00
git fetch --quiet origin main --tags
2023-02-21 18:44:27 -07:00
local SYNC_STATUS=$?
git diff --exit-code origin/main -- . >&2
local DIFF_STATUS=$?
[[ $SYNC_STATUS -eq 0 ]] && [[ $DIFF_STATUS -eq 0 ]] && {
SUCCESS 'already up-to-date with origin/main'
} || {
git rebase --autostash origin/main \
&& SUCCESS 'up-to-date with origin/main' \
|| {
git rebase --abort
ERROR 'unable to update scwrypts; please try manual upgrade'
REMINDER "installation in '$(pwd)'"
}
}
2022-08-01 15:53:40 -06:00
return 0
;;
2023-12-11 17:07:09 -07:00
-m | --name )
[ ! $2 ] && ERROR "missing value for argument $1" && break
SEARCH_NAME=$2
2022-08-01 15:53:40 -06:00
shift 1
;;
2023-12-11 17:07:09 -07:00
-g | --group )
[ ! $2 ] && ERROR "missing value for argument $1" && break
SEARCH_GROUP=$2
2022-08-01 15:53:40 -06:00
shift 1
;;
2023-12-11 17:07:09 -07:00
-t | --type )
[ ! $2 ] && ERROR "missing value for argument $1" && break
SEARCH_TYPE=$2
2022-08-01 15:53:40 -06:00
shift 1
;;
2023-12-11 17:07:09 -07:00
-y | --yes ) export __SCWRYPTS_YES=1 ;;
-q | --quiet ) VERBOSE=0 ;;
-n | --no-log ) VERBOSE=0 ; [ ! $SUBSCWRYPT ] && SUBSCWRYPT=0 ;;
-v | --verbose ) VERBOSE=2 ;;
-e | --env )
[ ! $2 ] && ERROR "missing value for argument $1" && break
[ ! $SUBSCWRYPTS ] \
&& [ $ENV_NAME ] \
&& WARNING 'overwriting session environment' \
;
ENV_NAME="$2"
STATUS "using CLI environment '$ENV_NAME'"
shift 1
;;
-- ) shift 1; break ;; # pass arguments after '--' to the scwrypt
--* ) ERROR "unrecognized argument '$1'" ;;
* ) SEARCH_PATTERNS+=($1) ;;
2022-08-01 15:53:40 -06:00
esac
2023-12-11 17:07:09 -07:00
shift 1
2022-08-01 15:53:40 -06:00
done
2023-02-21 18:44:27 -07:00
[ $SEARCH_NAME ] && {
2023-12-11 17:07:09 -07:00
[ $SEARCH_TYPE ] || ERROR '--name requires --type argument'
[ $SEARCH_GROUP ] || ERROR '--name requires --group argument'
2023-02-21 18:44:27 -07:00
}
CHECK_ERRORS
2022-08-01 15:53:40 -06:00
##########################################
2023-02-21 18:44:27 -07:00
local SCWRYPTS_AVAILABLE
local POTENTIAL_ERROR="no such scwrypt exists:"
2023-11-22 15:54:16 -07:00
2023-02-21 18:44:27 -07:00
SCWRYPTS_AVAILABLE=$(SCWRYPTS__GET_AVAILABLE_SCWRYPTS)
[ $SEARCH_NAME ] && {
POTENTIAL_ERROR+="\n NAME : '$SEARCH_NAME'"
POTENTIAL_ERROR+="\n TYPE : '$SEARCH_TYPE'"
POTENTIAL_ERROR+="\n GROUP : '$SEARCH_GROUP'"
SCWRYPTS_AVAILABLE=$({
echo $SCWRYPTS_AVAILABLE | head -n1
echo $SCWRYPTS_AVAILABLE | sed -e 's/\x1b\[[0-9;]*m//g' | grep "^$SEARCH_NAME *$SEARCH_TYPE *$SEARCH_GROUP\$"
})
}
[ ! $SEARCH_NAME ] && {
[ $SEARCH_TYPE ] && {
POTENTIAL_ERROR+="\n TYPE : '$SEARCH_TYPE'"
SCWRYPTS_AVAILABLE=$(\
{
echo $SCWRYPTS_AVAILABLE | head -n1
echo $SCWRYPTS_AVAILABLE | grep ' [^/]*'$SEARCH_TYPE'[^/]* '
} \
| awk '{$2=""; print $0;}' \
| sed 's/ \+$/'$(printf $__COLOR_RESET)'/; s/ \+/^/g' \
| column -ts '^'
)
}
[ $SEARCH_GROUP ] && {
POTENTIAL_ERROR+="\n GROUP : '$SEARCH_GROUP'"
SCWRYPTS_AVAILABLE=$(
{
echo $SCWRYPTS_AVAILABLE | head -n1
echo $SCWRYPTS_AVAILABLE | grep "$SEARCH_GROUP"'[^/]*$'
} \
| awk '{$NF=""; print $0;}' \
| sed 's/ \+$/'$(printf $__COLOR_RESET)'/; s/ \+/^/g' \
| column -ts '^'
)
}
[[ ${#SEARCH_PATTERNS[@]} -gt 0 ]] && {
POTENTIAL_ERROR+="\n PATTERNS : $SEARCH_PATTERNS"
local P
for P in ${SEARCH_PATTERNS[@]}
do
SCWRYPTS_AVAILABLE=$(
{
echo $SCWRYPTS_AVAILABLE | head -n1
echo $SCWRYPTS_AVAILABLE | grep $P
}
)
done
}
}
[[ $(echo $SCWRYPTS_AVAILABLE | wc -l) -lt 2 ]] && ERROR "$POTENTIAL_ERROR"
CHECK_ERRORS
##########################################
local NAME="$SEARCH_NAME"
local TYPE="$SEARCH_TYPE"
local GROUP="$SEARCH_GROUP"
2023-12-11 17:07:09 -07:00
[[ $(echo $SCWRYPTS_AVAILABLE | wc -l) -eq 2 ]] && {
SCWRYPT_SELECTION=$(echo $SCWRYPTS_AVAILABLE | tail -n1)
[[ $VERBOSE -eq 2 ]] || VERBOSE=0
} || {
SCWRYPT_SELECTION=$(echo $SCWRYPTS_AVAILABLE | FZF "select a script to run" --header-lines 1)
}
2023-02-21 18:44:27 -07:00
[ $SCWRYPT_SELECTION ] || exit 2
SCWRYPTS__SEPARATE_SCWRYPT_SELECTION $SCWRYPT_SELECTION
export SCWRYPT_NAME=$NAME
export SCWRYPT_TYPE=$TYPE
export SCWRYPT_GROUP=$GROUP
##########################################
2022-08-01 15:53:40 -06:00
local ENV_REQUIRED=$(__CHECK_ENV_REQUIRED && echo 1 || echo 0)
2023-08-22 14:20:03 -06:00
local REQUIRED_ENVIRONMENT_REGEX=$(eval echo '$SCWRYPTS_REQUIRED_ENVIRONMENT_REGEX__'$SCWRYPT_GROUP)
[ $REQUIRED_ENVIRONMENT_REGEX ] && {
[[ $ENV_NAME =~ $REQUIRED_ENVIRONMENT_REGEX ]] \
|| FAIL 5 "group '$SCWRYPT_GROUP' requires current environment to match '$REQUIRED_ENVIRONMENT_REGEX' (currently $ENV_NAME)"
}
2022-08-01 15:53:40 -06:00
[[ $ENV_REQUIRED -eq 1 ]] && {
2023-02-21 18:44:27 -07:00
[ ! $ENV_NAME ] && ENV_NAME=$(SCWRYPTS__SELECT_ENV)
2023-11-13 12:20:08 -07:00
2023-06-27 05:00:06 -06:00
for GROUP in ${SCWRYPTS_GROUPS[@]}
do
local ENV_FILE=$(SCWRYPTS__GET_ENV_FILE "$ENV_NAME" "$GROUP")
source "$ENV_FILE" || FAIL 5 "missing or invalid environment '$GROUP/$ENV_NAME'"
2023-08-18 12:40:14 -06:00
for f in $(eval 'echo $SCWRYPTS_STATIC_CONFIG__'$GROUP)
do
source "$f" || FAIL 5 "invalid static config '$f'"
done
2023-06-27 05:00:06 -06:00
done
2022-08-01 15:53:40 -06:00
export ENV_NAME
}
2023-08-22 14:20:03 -06:00
[ $REQUIRED_ENVIRONMENT_REGEX ] && {
[[ $ENV_NAME =~ $REQUIRED_ENVIRONMENT_REGEX ]] \
|| FAIL 5 "group '$SCWRYPT_GROUP' requires current environment to match '$REQUIRED_ENVIRONMENT_REGEX' (currently $ENV_NAME)"
}
2023-06-22 15:48:57 -06:00
2023-02-21 18:44:27 -07:00
##########################################
2023-12-11 17:07:09 -07:00
: \
&& [ ! $SUBSCWRYPT ] \
2022-08-01 15:53:40 -06:00
&& [[ $ENV_NAME =~ prod ]] \
2023-02-21 18:44:27 -07:00
&& { __VALIDATE_UPSTREAM_TIMELINE || ABORT; }
2022-08-01 15:53:40 -06:00
2023-02-21 18:44:27 -07:00
##########################################
local RUN_STRING=$(SCWRYPTS__GET_RUNSTRING $SCWRYPT_NAME $SCWRYPT_TYPE $SCWRYPT_GROUP)
2022-08-01 15:53:40 -06:00
[ ! $RUN_STRING ] && exit 3
##########################################
2023-06-22 17:57:17 -06:00
local LOGFILE=$(__GET_LOGFILE)
2022-08-01 15:53:40 -06:00
local HEADER=$(
2023-12-11 17:07:09 -07:00
[[ $VERBOSE -gt 0 ]] || return 0
2022-08-01 15:53:40 -06:00
[ $SUBSCWRYPT ] && return 0
echo '====================================================================='
2023-02-21 18:44:27 -07:00
echo "script : $SCWRYPT_GROUP $SCWRYPT_TYPE $SCWRYPT_NAME"
2022-08-01 15:53:40 -06:00
echo "run at : $(date)"
echo "config : $ENV_NAME"
[ ! $LOGFILE ] && echo '\033[1;33m------------------------------------------\033[0m'
)
[ ! $LOGFILE ] && {
[ $HEADER ] && echo $HEADER
2022-08-09 17:42:31 -06:00
[ $SUBSCWRYPT ] && {
2023-01-11 17:09:59 -07:00
eval "$RUN_STRING $(printf "%q " "$@")"
2022-08-01 15:53:40 -06:00
exit $?
} || {
2023-01-11 17:09:59 -07:00
eval "$RUN_STRING $(printf "%q " "$@")" </dev/tty >/dev/tty 2>&1
2022-08-01 15:53:40 -06:00
exit $?
}
}
{
[ $HEADER ] && echo $HEADER
2023-12-11 17:07:09 -07:00
[[ $VERBOSE -gt 0 ]] && echo '\033[1;33m--- BEGIN OUTPUT -------------------------\033[0m'
2023-10-19 20:04:25 -06:00
(eval "$RUN_STRING $(printf "%q " "$@")")
2022-08-01 15:53:40 -06:00
EXIT_CODE=$?
2023-12-11 17:07:09 -07:00
[[ $VERBOSE -gt 0 ]] && echo '\033[1;33m--- END OUTPUT ---------------------------\033[0m'
2022-08-01 15:53:40 -06:00
[[ $EXIT_CODE -eq 0 ]] && EXIT_COLOR='32m' || EXIT_COLOR='31m'
2023-12-11 17:07:09 -07:00
[[ $VERBOSE -gt 0 ]] && echo "terminated with\\033[1;$EXIT_COLOR code $EXIT_CODE\\033[0m"
2022-08-01 15:53:40 -06:00
} 2>&1 | tee --append "$LOGFILE"
exit $(\
sed -n 's/^terminated with.*code \([0-9]*\).*$/\1/p' $LOGFILE \
| tail -n1
)
}
#####################################################################
__CHECK_ENV_REQUIRED() {
[ $CI ] && return 1
2023-02-21 18:44:27 -07:00
echo $SCWRYPT_NAME | grep -q 'scwrypts/logs/' && return 1
echo $SCWRYPT_NAME | grep -q 'scwrypts/environment/' && return 1
2022-08-01 15:53:40 -06:00
return 0
}
__VALIDATE_UPSTREAM_TIMELINE() {
2023-02-21 18:44:27 -07:00
STATUS "on '$ENV_NAME'; checking diff against origin/main"
2022-08-01 15:53:40 -06:00
git fetch --quiet origin main
local SYNC_STATUS=$?
git diff --exit-code origin/main -- . >&2
local DIFF_STATUS=$?
[[ $SYNC_STATUS -eq 0 ]] && [[ $DIFF_STATUS -eq 0 ]] && {
2023-02-21 18:44:27 -07:00
SUCCESS 'up-to-date with origin/main'
2022-08-01 15:53:40 -06:00
} || {
2023-02-21 18:44:27 -07:00
WARNING
[[ $SYNC_STATUS -ne 0 ]] && WARNING 'unable to synchronize with origin/main'
[[ $DIFF_STATUS -ne 0 ]] && WARNING 'your branch differs from origin/main (diff listed above)'
WARNING
2022-08-01 15:53:40 -06:00
2023-02-21 18:44:27 -07:00
yN 'continue?' || return 1
2022-08-01 15:53:40 -06:00
}
}
__GET_LOGFILE() {
2023-12-11 17:07:09 -07:00
[ $SUBSCWRYPT ] && return 0
[[ $SCWRYPT_NAME =~ scwrypts/logs ]] && return 0
[[ $SCWRYPT_NAME =~ interactive ]] && return 0
2022-08-01 15:53:40 -06:00
2023-02-21 18:44:27 -07:00
echo "$SCWRYPTS_LOG_PATH/$(echo $GROUP/$TYPE/$NAME | sed 's/^\.\///; s/\//\%/g').log"
2022-08-01 15:53:40 -06:00
}
#####################################################################
__RUN $@