yage
91780024f0
===================================================================== --- New Features ------------------------- - adding variables of the format `^SCWRYPTS_GROUP_LOADERS__[a-z_]\+=` will let those files be explicitly sourced during run (this should allow custom group usage in CI)
337 lines
8.8 KiB
Bash
Executable File
337 lines
8.8 KiB
Bash
Executable File
#!/bin/zsh
|
|
export EXECUTION_DIR=$(pwd)
|
|
source "${0:a:h}/zsh/lib/import.driver.zsh" || exit 42
|
|
|
|
#####################################################################
|
|
|
|
__RUN() {
|
|
local USAGE='
|
|
usage: scwrypts [OPTIONS ...] SCRIPT -- [SCRIPT OPTIONS ...]
|
|
|
|
OPTIONS
|
|
-g, --group <group-name> only use scripts from the indicated group
|
|
-t, --type <type-name> only use scripts of the indicated type
|
|
-m, --name <scwrypt-name> only run the script if there is an exact match
|
|
(requires type and group)
|
|
|
|
-e, --env <env-name> set environment; overwrites SCWRYPTS_ENV
|
|
-n, --no-log skip logging and run in quiet mode
|
|
|
|
--update update scwrypts library to latest version
|
|
|
|
-v, --version print out scwrypts version and exit
|
|
-l, --list print out command list and exit
|
|
-h, --help display this message and exit
|
|
'
|
|
cd "$SCWRYPTS_ROOT"
|
|
|
|
local ENV_NAME="$SCWRYPTS_ENV"
|
|
local SEARCH_PATTERNS=()
|
|
|
|
local VARSPLIT SEARCH_GROUP SEARCH_TYPE SEARCH_NAME
|
|
|
|
local ERROR=0
|
|
|
|
while [[ $# -gt 0 ]]
|
|
do
|
|
case $1 in
|
|
-t | --type )
|
|
[ ! $2 ] && ERROR "missing value for argument $1" && break
|
|
SEARCH_TYPE=$2
|
|
shift 2
|
|
;;
|
|
-g | --group )
|
|
[ ! $2 ] && ERROR "missing value for argument $1" && break
|
|
SEARCH_GROUP=$2
|
|
shift 2
|
|
;;
|
|
-m | --name )
|
|
[ ! $2 ] && ERROR "missing value for argument $1" && break
|
|
SEARCH_NAME=$2
|
|
shift 2
|
|
;;
|
|
|
|
-[a-z][a-z]* )
|
|
VARSPLIT=$(echo "$1 " | sed 's/^\(-.\)\(.*\) /\1 -\2/')
|
|
set -- $(echo " $VARSPLIT ") ${@:2}
|
|
;;
|
|
-h | --help )
|
|
USAGE
|
|
return 0
|
|
;;
|
|
-n | --no-log )
|
|
[ ! $SUBSCWRYPT ] && SUBSCWRYPT=0
|
|
shift 1
|
|
;;
|
|
-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 2
|
|
;;
|
|
-l | --list )
|
|
SCWRYPTS__GET_AVAILABLE_SCWRYPTS
|
|
return 0
|
|
;;
|
|
-v | --version )
|
|
echo scwrypts $(cd "$SCWRYPTS__ROOT__scwrypts"; git describe --tags)
|
|
return 0
|
|
;;
|
|
--update )
|
|
cd "$SCWRYPTS__ROOT__scwrypts"
|
|
git fetch --quiet origin main
|
|
git fetch --quiet origin main --tags
|
|
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)'"
|
|
}
|
|
}
|
|
return 0
|
|
;;
|
|
-- )
|
|
shift 1
|
|
break # pass arguments after '--' to the scwrypt
|
|
;;
|
|
--* )
|
|
ERROR "unrecognized argument '$1'"
|
|
shift 1
|
|
;;
|
|
* )
|
|
SEARCH_PATTERNS+=($1)
|
|
shift 1
|
|
;;
|
|
esac
|
|
done
|
|
|
|
[ $SEARCH_NAME ] && {
|
|
[ ! $SEARCH_TYPE ] && ERROR '--name requires --type argument'
|
|
[ ! $SEARCH_GROUP ] && ERROR '--name requires --group argument'
|
|
}
|
|
|
|
CHECK_ERRORS
|
|
|
|
##########################################
|
|
|
|
local SCWRYPTS_AVAILABLE
|
|
local POTENTIAL_ERROR="no such scwrypt exists:"
|
|
|
|
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"
|
|
|
|
[[ $(echo $SCWRYPTS_AVAILABLE | wc -l) -eq 2 ]] \
|
|
&& SCWRYPT_SELECTION=$(echo $SCWRYPTS_AVAILABLE | tail -n1) \
|
|
|| SCWRYPT_SELECTION=$(echo $SCWRYPTS_AVAILABLE | FZF "select a script to run" --header-lines 1)
|
|
[ $SCWRYPT_SELECTION ] || exit 2
|
|
|
|
SCWRYPTS__SEPARATE_SCWRYPT_SELECTION $SCWRYPT_SELECTION
|
|
|
|
export SCWRYPT_NAME=$NAME
|
|
export SCWRYPT_TYPE=$TYPE
|
|
export SCWRYPT_GROUP=$GROUP
|
|
|
|
##########################################
|
|
|
|
local ENV_REQUIRED=$(__CHECK_ENV_REQUIRED && echo 1 || echo 0)
|
|
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)"
|
|
}
|
|
|
|
[[ $ENV_REQUIRED -eq 1 ]] && {
|
|
[ ! $ENV_NAME ] && ENV_NAME=$(SCWRYPTS__SELECT_ENV)
|
|
|
|
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'"
|
|
|
|
for f in $(eval 'echo $SCWRYPTS_STATIC_CONFIG__'$GROUP)
|
|
do
|
|
source "$f" || FAIL 5 "invalid static config '$f'"
|
|
done
|
|
done
|
|
|
|
export ENV_NAME
|
|
}
|
|
|
|
[ $REQUIRED_ENVIRONMENT_REGEX ] && {
|
|
[[ $ENV_NAME =~ $REQUIRED_ENVIRONMENT_REGEX ]] \
|
|
|| FAIL 5 "group '$SCWRYPT_GROUP' requires current environment to match '$REQUIRED_ENVIRONMENT_REGEX' (currently $ENV_NAME)"
|
|
}
|
|
|
|
##########################################
|
|
|
|
[ ! $SUBSCWRYPT ] \
|
|
&& [[ $ENV_NAME =~ prod ]] \
|
|
&& { __VALIDATE_UPSTREAM_TIMELINE || ABORT; }
|
|
|
|
##########################################
|
|
|
|
local RUN_STRING=$(SCWRYPTS__GET_RUNSTRING $SCWRYPT_NAME $SCWRYPT_TYPE $SCWRYPT_GROUP)
|
|
[ ! $RUN_STRING ] && exit 3
|
|
|
|
##########################################
|
|
|
|
local LOGFILE=$(__GET_LOGFILE)
|
|
|
|
local HEADER=$(
|
|
[ $SUBSCWRYPT ] && return 0
|
|
echo '====================================================================='
|
|
echo "script : $SCWRYPT_GROUP $SCWRYPT_TYPE $SCWRYPT_NAME"
|
|
echo "run at : $(date)"
|
|
echo "config : $ENV_NAME"
|
|
[ ! $LOGFILE ] && echo '\033[1;33m------------------------------------------\033[0m'
|
|
)
|
|
|
|
[ ! $LOGFILE ] && {
|
|
[ $HEADER ] && echo $HEADER
|
|
[ $SUBSCWRYPT ] && {
|
|
eval "$RUN_STRING $(printf "%q " "$@")"
|
|
exit $?
|
|
} || {
|
|
eval "$RUN_STRING $(printf "%q " "$@")" </dev/tty >/dev/tty 2>&1
|
|
exit $?
|
|
}
|
|
}
|
|
|
|
{
|
|
[ $HEADER ] && echo $HEADER
|
|
echo '\033[1;33m--- BEGIN OUTPUT -------------------------\033[0m'
|
|
(eval "$RUN_STRING $(printf "%q " "$@")")
|
|
EXIT_CODE=$?
|
|
echo '\033[1;33m--- END OUTPUT ---------------------------\033[0m'
|
|
|
|
[[ $EXIT_CODE -eq 0 ]] && EXIT_COLOR='32m' || EXIT_COLOR='31m'
|
|
|
|
echo "terminated with\\033[1;$EXIT_COLOR code $EXIT_CODE\\033[0m"
|
|
} 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
|
|
|
|
echo $SCWRYPT_NAME | grep -q 'scwrypts/logs/' && return 1
|
|
echo $SCWRYPT_NAME | grep -q 'scwrypts/environment/' && return 1
|
|
|
|
return 0
|
|
}
|
|
|
|
__VALIDATE_UPSTREAM_TIMELINE() {
|
|
STATUS "on '$ENV_NAME'; checking diff against origin/main"
|
|
|
|
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 ]] && {
|
|
SUCCESS 'up-to-date with origin/main'
|
|
} || {
|
|
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
|
|
|
|
yN 'continue?' || return 1
|
|
}
|
|
}
|
|
|
|
__GET_LOGFILE() {
|
|
[ $SUBSCWRYPT ] \
|
|
|| [[ $SCWRYPT_NAME =~ scwrypts/logs ]] \
|
|
|| [[ $SCWRYPT_NAME =~ interactive ]] \
|
|
&& return 0
|
|
|
|
echo "$SCWRYPTS_LOG_PATH/$(echo $GROUP/$TYPE/$NAME | sed 's/^\.\///; s/\//\%/g').log"
|
|
}
|
|
|
|
#####################################################################
|
|
__RUN $@
|