diff --git a/run b/run deleted file mode 100755 index 7008a4e..0000000 --- a/run +++ /dev/null @@ -1,388 +0,0 @@ -#!/bin/zsh -export EXECUTION_DIR=$(pwd) -source "${0:a:h}/zsh/lib/import.driver.zsh" || exit 42 -##################################################################### -() { - cd "$SCWRYPTS_ROOT__scwrypts" - GIT_SCWRYPTS() { git -C "$SCWRYPTS_ROOT__scwrypts" $@; } - local ERRORS=0 - local USAGE=' - usage: scwrypts [...options...] [...patterns...] -- [...script options...] - - options: - selection - -m, --name only run the script if there is an exact match - (requires type and group) - -g, --group only use scripts from the indicated group - -t, --type only use scripts of the indicated type - - runtime - -y, --yes auto-accept all [yn] prompts through current scwrypt - -e, --env set environment; overwrites SCWRYPTS_ENV - -n shorthand for "--log-level 0" - -v, --log-level [0-4] set scwrypts log level to one of the following: - 0 : only command output and critical failures; skips logfile - 1 : add success / failure messages - 2 : (default) include status update messages - 3 : (CI default) include warning messages - 4 : include debug messages - - 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 - ("-- --help" will provide more information) - ' - - ##################################################################### - ### cli argument parsing and global configuration ################### - ##################################################################### - - local ENV_NAME="$SCWRYPTS_ENV" - local SEARCH_PATTERNS=() - - local VARSPLIT SEARCH_GROUP SEARCH_TYPE SEARCH_NAME - - [ ! $SCWRYPTS_LOG_LEVEL ] && { - local SCWRYPTS_LOG_LEVEL - [ $CI ] && SCWRYPTS_LOG_LEVEL=3 || SCWRYPTS_LOG_LEVEL=2 - } - - while [[ $# -gt 0 ]] - do - case $1 in - -[a-z][a-z]* ) - VARSPLIT=$(echo "$1 " | sed 's/^\(-.\)\(.*\) /\1 -\2/') - set -- $(echo " $VARSPLIT ") ${@:2} - ;; - - ### alternate commands ################### - - -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_SCWRYPTS describe --tags) - return 0 - ;; - - --update ) - GIT_SCWRYPTS fetch --quiet origin main - GIT_SCWRYPTS fetch --quiet origin main --tags - local SYNC_STATUS=$? - - GIT_SCWRYPTS diff --exit-code origin/main -- . >/dev/null 2>&1 - local DIFF_STATUS=$? - - [[ $SYNC_STATUS -eq 0 ]] && [[ $DIFF_STATUS -eq 0 ]] && { - SUCCESS 'already up-to-date with origin/main' - } || { - GIT_SCWRYPTS rebase --autostash origin/main \ - && SUCCESS 'up-to-date with origin/main' \ - && GIT_SCWRYPTS log -n1 \ - || { - GIT_SCWRYPTS rebase --abort - ERROR 'unable to update scwrypts; please try manual upgrade' - REMINDER "installation in '$(pwd)'" - } - } - return 0 - ;; - - ### scwrypts filters ##################### - - -m | --name ) - [ $2 ] || { ERROR "missing value for argument $1"; break; } - SEARCH_NAME=$2 - shift 1 - ;; - - -g | --group ) - [ $2 ] || { ERROR "missing value for argument $1"; break; } - SEARCH_GROUP=$2 - shift 1 - ;; - - -t | --type ) - [ $2 ] || { ERROR "missing value for argument $1"; break; } - SEARCH_TYPE=$2 - shift 1 - ;; - - ### runtime settings ##################### - - -y | --yes ) export __SCWRYPTS_YES=1 ;; - - -n | --no-log ) - SCWRYPTS_LOG_LEVEL=0 - [[ $1 =~ ^--no-log$ ]] && WARNING 'the --no-log flag is deprecated and will be removed in scwrypts v4.2' - ;; - - -v | --log-level ) - [[ $2 =~ ^[0-4]$ ]] || ERROR "invalid setting for log-level '$2'" - SCWRYPTS_LOG_LEVEL=$2 - shift 1 - ;; - - -e | --env ) - [ $2 ] || { ERROR "missing value for argument $1"; break; } - - [ $ENV_NAME ] && DEBUG '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) ;; - esac - shift 1 - done - - [ $SEARCH_NAME ] && { - [ $SEARCH_TYPE ] || ERROR '--name requires --type argument' - [ $SEARCH_GROUP ] || ERROR '--name requires --group argument' - } - - CHECK_ERRORS - - ##################################################################### - ### scwrypts selection / filtering ################################## - ##################################################################### - - local SCWRYPTS_AVAILABLE - SCWRYPTS_AVAILABLE=$(SCWRYPTS__GET_AVAILABLE_SCWRYPTS) - - ########################################## - - [ $SEARCH_NAME ] && 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_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 ] && { - 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 ]] && { - FAIL 1 "$(echo " - no such scwrypt exists - NAME : '$SEARCH_NAME' - TYPE : '$SEARCH_TYPE' - GROUP : '$SEARCH_GROUP' - PATTERNS : '$SEARCH_PATTERNS' - " | sed "1d; \$d; /''$/d")" - } - - ########################################## - - [[ $(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 - - ########################################## - - local NAME TYPE GROUP - SCWRYPTS__SEPARATE_SCWRYPT_SELECTION $SCWRYPT_SELECTION - - export SCWRYPT_NAME=$NAME - export SCWRYPT_TYPE=$TYPE - export SCWRYPT_GROUP=$GROUP - - ##################################################################### - ### environment variables and configuration validation ############## - ##################################################################### - - local ENV_REQUIRED=true \ - && [ ! $CI ] \ - && [[ ! $SCWRYPT_NAME =~ scwrypts/logs ]] \ - && [[ ! $SCWRYPT_NAME =~ scwrypts/environment ]] \ - || ENV_REQUIRED=false - - local REQUIRED_ENVIRONMENT_REGEX=$(eval echo '$SCWRYPTS_REQUIRED_ENVIRONMENT_REGEX__'$SCWRYPT_GROUP) - - [[ $ENV_REQUIRED =~ true ]] && { - [ ! $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 name to match '$REQUIRED_ENVIRONMENT_REGEX' (currently $ENV_NAME)" - } - - ########################################## - - [ ! $SUBSCWRYPT ] && [[ $ENV_NAME =~ prod ]] && { - STATUS "on '$ENV_NAME'; checking diff against origin/main" - - GIT_SCWRYPTS fetch --quiet origin main - local SYNC_STATUS=$? - - GIT_SCWRYPTS diff --exit-code origin/main -- . >&2 - local DIFF_STATUS=$? - - [[ $SYNC_STATUS -eq 0 ]] && [[ $DIFF_STATUS -eq 0 ]] && { - SUCCESS 'up-to-date with origin/main' - } || { - SCWRYPTS_LOG_LEVEL=3 WARNING "you are trying to run in ${__BRIGHT_RED}production${__YELLOW} but $([[ $SYNC_STATUS -ne 0 ]] && echo 'I am unable to verify your scwrypts version')$([[ $DIFF_STATUS -ne 0 ]] && echo 'your scwrypts is out-of-date (diff listed above)')" - - yN 'continue?' || { - REMINDER "you can use 'scwrypts --update' to quickly update scwrypts to latest" - ABORT - } - } - } - - ########################################## - - local RUN_STRING=$(SCWRYPTS__GET_RUNSTRING $SCWRYPT_NAME $SCWRYPT_TYPE $SCWRYPT_GROUP) - [ "$RUN_STRING" ] || return 42 - - ##################################################################### - ### logging and pretty header/footer setup ########################## - ##################################################################### - - local LOGFILE \ - && [[ $SCWRYPTS_LOG_LEVEL -gt 0 ]] \ - && [ ! $SUBSCWRYPT ] \ - && [[ ! $SCWRYPT_NAME =~ scwrypts/logs ]] \ - && [[ ! $SCWRYPT_NAME =~ interactive ]] \ - && LOGFILE="$SCWRYPTS_LOG_PATH/$(echo $GROUP/$TYPE/$NAME | sed 's/^\.\///; s/\//\%/g').log" \ - || LOGFILE='/dev/null' \ - ; - - local RUN_MODE=normal - [[ $LOGFILE =~ ^/dev/null$ ]] && RUN_MODE=no-logfile - [[ $SCWRYPT_NAME =~ interactive ]] && RUN_MODE=interactive - - local HEADER FOOTER - - [[ $SCWRYPTS_LOG_LEVEL -ge 2 ]] && { - HEADER=$( - echo " - ===================================================================== - script : $SCWRYPT_GROUP $SCWRYPT_TYPE $SCWRYPT_NAME - run at : $(date) - config : $ENV_NAME - log level : $SCWRYPTS_LOG_LEVEL - \\033[1;33m--- SCWRYPT BEGIN ---------------------------------------------------\\033[0m - " | sed 's/^\s\+//; 1d' - ) - - FOOTER="\\033[1;33m--- SCWRYPT END ---------------------------------------------------\\033[0m" - } - - [ $SUBSCWRYPT ] && { - HEADER="\\033[0;33m--- ($SUBSCWRYPT) BEGIN $SCWRYPT_GROUP $SCWRYPT_TYPE $SCWRYPT_NAME ---" - FOOTER="\\033[0;33m--- ($SUBSCWRYPT) END $SCWRYPT_GROUP $SCWRYPT_TYPE $SCWRYPT_NAME ---" - } - - ##################################################################### - ### run the scwrypt ################################################# - ##################################################################### - - [ ! $SUBSCWRYPT ] && export SUBSCWRYPT=0 - - set -o pipefail - { - [ $HEADER ] && echo $HEADER - case $RUN_MODE in - normal ) - (eval "$RUN_STRING $(printf "%q " "$@")") - EXIT_CODE=$? - ;; - no-logfile ) - eval "$RUN_STRING $(printf "%q " "$@")" - EXIT_CODE=$? - ;; - interactive ) - eval "$RUN_STRING $(printf "%q " "$@")" /dev/tty 2>&1 - EXIT_CODE=$? - ;; - esac - [ $FOOTER ] && echo $FOOTER - [[ $EXIT_CODE -eq 0 ]] && EXIT_COLOR='32m' || EXIT_COLOR='31m' - - [[ $SCWRYPTS_LOG_LEVEL -ge 2 ]] && [ ! $SUBSCWRYPT ] \ - && echo "terminated with\\033[1;$EXIT_COLOR code $EXIT_CODE\\033[0m" - - return $EXIT_CODE - } 2>&1 | tee --append "$LOGFILE" - -} $@ diff --git a/scwrypts b/scwrypts index 9f7f24d..3b051c4 100755 --- a/scwrypts +++ b/scwrypts @@ -1,2 +1,396 @@ #!/bin/zsh -source "${0:a:h}/run" $@ + +export EXECUTION_DIR=$(pwd) +source "$(dirname $(readlink -f "$0"))/zsh/lib/import.driver.zsh" || exit 42 + +##################################################################### +() { + cd "$SCWRYPTS_ROOT__scwrypts" + GIT_SCWRYPTS() { git -C "$SCWRYPTS_ROOT__scwrypts" $@; } + local ERRORS=0 + local USAGE=' + usage: scwrypts [...options...] [...patterns...] -- [...script options...] + + options: + selection + -m, --name only run the script if there is an exact match + (requires type and group) + -g, --group only use scripts from the indicated group + -t, --type only use scripts of the indicated type + + runtime + -y, --yes auto-accept all [yn] prompts through current scwrypt + -e, --env set environment; overwrites SCWRYPTS_ENV + -n shorthand for "--log-level 0" + -v, --log-level [0-4] set scwrypts log level to one of the following: + 0 : only command output and critical failures; skips logfile + 1 : add success / failure messages + 2 : include status update messages + 3 : (default) include warning messages + 4 : include debug messages + + 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 + ("-- --help" will provide more information) + ' + + ##################################################################### + ### cli argument parsing and global configuration ################### + ##################################################################### + + local ENV_NAME="$SCWRYPTS_ENV" + local SEARCH_PATTERNS=() + + local VARSPLIT SEARCH_GROUP SEARCH_TYPE SEARCH_NAME + + [ ! $SCWRYPTS_LOG_LEVEL ] && local SCWRYPTS_LOG_LEVEL=3 + + while [[ $# -gt 0 ]] + do + case $1 in + -[a-z][a-z]* ) + VARSPLIT=$(echo "$1 " | sed 's/^\(-.\)\(.*\) /\1 -\2/') + set -- $(echo " $VARSPLIT ") ${@:2} + ;; + + ### alternate commands ################### + + -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_SCWRYPTS describe --tags) + return 0 + ;; + + --update ) + GIT_SCWRYPTS fetch --quiet origin main + GIT_SCWRYPTS fetch --quiet origin main --tags + local SYNC_STATUS=$? + + GIT_SCWRYPTS diff --exit-code origin/main -- . >/dev/null 2>&1 + local DIFF_STATUS=$? + + [[ $SYNC_STATUS -eq 0 ]] && [[ $DIFF_STATUS -eq 0 ]] && { + SUCCESS 'already up-to-date with origin/main' + } || { + GIT_SCWRYPTS rebase --autostash origin/main \ + && SUCCESS 'up-to-date with origin/main' \ + && GIT_SCWRYPTS log -n1 \ + || { + GIT_SCWRYPTS rebase --abort + ERROR 'unable to update scwrypts; please try manual upgrade' + REMINDER "installation in '$(pwd)'" + } + } + return 0 + ;; + + ### scwrypts filters ##################### + + -m | --name ) + [ $2 ] || { ERROR "missing value for argument $1"; break; } + SEARCH_NAME=$2 + shift 1 + ;; + + -g | --group ) + [ $2 ] || { ERROR "missing value for argument $1"; break; } + SEARCH_GROUP=$2 + shift 1 + ;; + + -t | --type ) + [ $2 ] || { ERROR "missing value for argument $1"; break; } + SEARCH_TYPE=$2 + shift 1 + ;; + + ### runtime settings ##################### + + -y | --yes ) export __SCWRYPTS_YES=1 ;; + + -n | --no-log ) + SCWRYPTS_LOG_LEVEL=0 + [[ $1 =~ ^--no-log$ ]] && WARNING 'the --no-log flag is deprecated and will be removed in scwrypts v4.2' + ;; + + -v | --log-level ) + [[ $2 =~ ^[0-4]$ ]] || ERROR "invalid setting for log-level '$2'" + SCWRYPTS_LOG_LEVEL=$2 + shift 1 + ;; + + -e | --env ) + [ $2 ] || { ERROR "missing value for argument $1"; break; } + + [ $ENV_NAME ] && DEBUG '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) ;; + esac + shift 1 + done + + [ $SEARCH_NAME ] && { + [ $SEARCH_TYPE ] || ERROR '--name requires --type argument' + [ $SEARCH_GROUP ] || ERROR '--name requires --group argument' + } + + CHECK_ERRORS + + ##################################################################### + ### scwrypts selection / filtering ################################## + ##################################################################### + + local SCWRYPTS_AVAILABLE + SCWRYPTS_AVAILABLE=$(SCWRYPTS__GET_AVAILABLE_SCWRYPTS) + + ########################################## + + [ $SEARCH_NAME ] && 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_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 ] && { + 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 ]] && { + FAIL 1 "$(echo " + no such scwrypt exists + NAME : '$SEARCH_NAME' + TYPE : '$SEARCH_TYPE' + GROUP : '$SEARCH_GROUP' + PATTERNS : '$SEARCH_PATTERNS' + " | sed "1d; \$d; /''$/d")" + } + + ########################################## + + [[ $(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 + + ########################################## + + local NAME TYPE GROUP + SCWRYPTS__SEPARATE_SCWRYPT_SELECTION $SCWRYPT_SELECTION + + export SCWRYPT_NAME=$NAME + export SCWRYPT_TYPE=$TYPE + export SCWRYPT_GROUP=$GROUP + + ##################################################################### + ### environment variables and configuration validation ############## + ##################################################################### + + local ENV_REQUIRED=true \ + && [ ! $CI ] \ + && [[ ! $SCWRYPT_NAME =~ scwrypts/logs ]] \ + && [[ ! $SCWRYPT_NAME =~ scwrypts/environment ]] \ + || ENV_REQUIRED=false + + local REQUIRED_ENVIRONMENT_REGEX=$(eval echo '$SCWRYPTS_REQUIRED_ENVIRONMENT_REGEX__'$SCWRYPT_GROUP) + + [ $ENV_NAME ] && [ $REQUIRED_ENVIRONMENT_REGEX ] && { + [[ $ENV_NAME =~ $REQUIRED_ENVIRONMENT_REGEX ]] \ + || FAIL 5 "group '$SCWRYPT_GROUP' requires current environment name to match '$REQUIRED_ENVIRONMENT_REGEX' (currently $ENV_NAME)" + } + + [[ $ENV_REQUIRED =~ true ]] && { + [ ! $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 name to match '$REQUIRED_ENVIRONMENT_REGEX' (currently $ENV_NAME)" + } + + ########################################## + + [ ! $SUBSCWRYPT ] && export SUBSCWRYPT=0 + + [[ $SUBSCWRYPT -eq 0 ]] && [[ $ENV_NAME =~ prod ]] && [[ $SCWRYPTS_LOG_LEVEL -gt 0 ]] && { + STATUS "on '$ENV_NAME'; checking diff against origin/main" + + local WARNING_MESSAGE + + [ ! $WARNING_MESSAGE ] && { + GIT_SCWRYPTS fetch --quiet origin main \ + && WARNING_MESSAGE='I am unable to verify your scwrypts version' + } + + [ ! $WARNING_MESSAGE ] && { + GIT_SCWRYPTS diff --exit-code origin/main -- . >/dev/null 2>&1 \ + || WARNING_MESSAGE='your scwrypts is currently out-of-date' + } + + [ $WARNING_MESSAGE ] && { + [[ $SCWRYPTS_LOG_LEVEL -lt 3 ]] && { + REMINDER "you are running in ${__BRIGHT_RED}production${__BRIGHT_MAGENTA} and $WARNING_MESSAGE" + } || { + GIT_SCWRYPTS diff --exit-code origin/main -- . >&2 + WARNING "you are trying to run in ${__BRIGHT_RED}production${__YELLOW} but $WARNING_MESSAGE (relevant diffs and errors above)" + yN 'continue?' || { + REMINDER "you can use 'scwrypts --update' to quickly update scwrypts to latest" + ABORT + } + } + } + } + + ########################################## + + local RUN_STRING=$(SCWRYPTS__GET_RUNSTRING $SCWRYPT_NAME $SCWRYPT_TYPE $SCWRYPT_GROUP) + [ "$RUN_STRING" ] || return 42 + + ##################################################################### + ### logging and pretty header/footer setup ########################## + ##################################################################### + + local LOGFILE \ + && [[ $SCWRYPTS_LOG_LEVEL -gt 0 ]] \ + && [[ $SUBSCWRYPT -eq 0 ]] \ + && [[ ! $SCWRYPT_NAME =~ scwrypts/logs ]] \ + && [[ ! $SCWRYPT_NAME =~ interactive ]] \ + && LOGFILE="$SCWRYPTS_LOG_PATH/$(echo $GROUP/$TYPE/$NAME | sed 's/^\.\///; s/\//\%/g').log" \ + || LOGFILE='/dev/null' \ + ; + + local RUN_MODE=normal + [[ $LOGFILE =~ ^/dev/null$ ]] && RUN_MODE=no-logfile + [[ $SCWRYPT_NAME =~ interactive ]] && RUN_MODE=interactive + + local HEADER FOOTER + + [[ $SCWRYPTS_LOG_LEVEL -ge 2 ]] && { + HEADER=$( + echo " + ===================================================================== + script : $SCWRYPT_GROUP $SCWRYPT_TYPE $SCWRYPT_NAME + run at : $(date) + config : $ENV_NAME + log level : $SCWRYPTS_LOG_LEVEL + \\033[1;33m--- SCWRYPT BEGIN ---------------------------------------------------\\033[0m + " | sed 's/^\s\+//; 1d' + ) + + FOOTER="\\033[1;33m--- SCWRYPT END ---------------------------------------------------\\033[0m" + } + + [[ $SUBSCWRYPT -eq 0 ]] || { + HEADER="\\033[0;33m--- ($SUBSCWRYPT) BEGIN $SCWRYPT_GROUP $SCWRYPT_TYPE $SCWRYPT_NAME ---" + FOOTER="\\033[0;33m--- ($SUBSCWRYPT) END $SCWRYPT_GROUP $SCWRYPT_TYPE $SCWRYPT_NAME ---" + } + + ##################################################################### + ### run the scwrypt ################################################# + ##################################################################### + set -o pipefail + { + [ $HEADER ] && echo $HEADER + case $RUN_MODE in + normal ) + (eval "$RUN_STRING $(printf "%q " "$@")") + EXIT_CODE=$? + ;; + no-logfile ) + eval "$RUN_STRING $(printf "%q " "$@")" + EXIT_CODE=$? + ;; + interactive ) + eval "$RUN_STRING $(printf "%q " "$@")" /dev/tty 2>&1 + EXIT_CODE=$? + ;; + esac + [ $FOOTER ] && echo $FOOTER + [[ $EXIT_CODE -eq 0 ]] && EXIT_COLOR='32m' || EXIT_COLOR='31m' + + [[ $SCWRYPTS_LOG_LEVEL -ge 2 ]] && [ ! $SUBSCWRYPT ] \ + && echo "terminated with\\033[1;$EXIT_COLOR code $EXIT_CODE\\033[0m" + + return $EXIT_CODE + } 2>&1 | tee --append "$LOGFILE" +} $@ diff --git a/zsh/lib/cloud/aws/eks.module.zsh b/zsh/lib/cloud/aws/eks.module.zsh index e4bfc67..95b83f2 100644 --- a/zsh/lib/cloud/aws/eks.module.zsh +++ b/zsh/lib/cloud/aws/eks.module.zsh @@ -27,6 +27,9 @@ EKS() { local CONTEXT="arn:aws:eks:${AWS_REGION}:${AWS_ACCOUNT}:cluster/${CLUSTER_NAME}" + kubectl config get-contexts | grep -q $CONTEXT \ + || EKS__CLUSTER_LOGIN -c $CLUSTER_NAME + local CONTEXT_ARGS=() case $1 in helm ) CONTEXT_ARGS+=(--kube-context $CONTEXT) ;; @@ -52,6 +55,7 @@ EKS__CLUSTER_LOGIN() { " REQUIRED_ENV=(AWS_ACCOUNT AWS_REGION) CHECK_ENVIRONMENT || return 1 + local CLUSTER_NAME while [[ $# -gt 0 ]] diff --git a/zsh/lib/scwrypts/meta.module.zsh b/zsh/lib/scwrypts/meta.module.zsh index 1f8fb8a..15c6608 100644 --- a/zsh/lib/scwrypts/meta.module.zsh +++ b/zsh/lib/scwrypts/meta.module.zsh @@ -12,7 +12,7 @@ SCWRYPTS__RUN() { # context wrapper to run scwrypts within scwrypts local EXIT_CODE=0 ((SUBSCWRYPT+=1)) - SUBSCWRYPT=$SUBSCWRYPT $SCWRYPTS_ROOT/run $@ + SUBSCWRYPT=$SUBSCWRYPT $SCWRYPTS_ROOT/scwrypts $@ EXIT_CODE=$? ((SUBSCWRYPT-=1)) diff --git a/zsh/lib/utils/io.zsh b/zsh/lib/utils/io.zsh index df3950b..508d9ac 100644 --- a/zsh/lib/utils/io.zsh +++ b/zsh/lib/utils/io.zsh @@ -6,6 +6,7 @@ source "${0:a:h}/io.print.zsh" [ ! $ERRORS ] && ERRORS=0 ERROR() { # command encountered an error + [ ! $SCWRYPTS_LOG_LEVEL ] && local SCWRYPTS_LOG_LEVEL=4 [[ $SCWRYPTS_LOG_LEVEL -ge 1 ]] \ && PREFIX="ERROR ✖" COLOR=$__RED PRINT "$@" ((ERRORS+=1)) @@ -13,36 +14,42 @@ ERROR() { # command encountered an error } SUCCESS() { # command completed successfully + [ ! $SCWRYPTS_LOG_LEVEL ] && local SCWRYPTS_LOG_LEVEL=4 [[ $SCWRYPTS_LOG_LEVEL -ge 1 ]] \ && PREFIX="SUCCESS ✔" COLOR=$__GREEN PRINT "$@" return 0 } REMINDER() { # include sysadmin reminder or other important notice to users + [ ! $SCWRYPTS_LOG_LEVEL ] && local SCWRYPTS_LOG_LEVEL=4 [[ $SCWRYPTS_LOG_LEVEL -ge 1 ]] \ && PREFIX="REMINDER " COLOR=$__BRIGHT_MAGENTA PRINT "$@" return 0 } STATUS() { # general status updates (prefer this to generic 'echo') + [ ! $SCWRYPTS_LOG_LEVEL ] && local SCWRYPTS_LOG_LEVEL=4 [[ $SCWRYPTS_LOG_LEVEL -ge 2 ]] \ && PREFIX="STATUS " COLOR=$__BLUE PRINT "$@" return 0 } WARNING() { # warning-level messages; not errors + [ ! $SCWRYPTS_LOG_LEVEL ] && local SCWRYPTS_LOG_LEVEL=4 [[ $SCWRYPTS_LOG_LEVEL -ge 3 ]] \ && PREFIX="WARNING " COLOR=$__YELLOW PRINT "$@" return 0 } DEBUG() { # helpful during development or (sparingly) to help others' development + [ ! $SCWRYPTS_LOG_LEVEL ] && local SCWRYPTS_LOG_LEVEL=4 [[ $SCWRYPTS_LOG_LEVEL -ge 4 ]] \ && PREFIX="DEBUG ℹ" COLOR=$__WHITE PRINT "$@" return 0 } PROMPT() { # you probably want to use yN or INPUT from below + [ ! $SCWRYPTS_LOG_LEVEL ] && local SCWRYPTS_LOG_LEVEL=4 [[ $SCWRYPTS_LOG_LEVEL -ge 1 ]] \ && PREFIX="PROMPT " COLOR=$__CYAN PRINT "$@" \ && PREFIX="USER ⌨" COLOR=$__BRIGHT_CYAN PRINT '' --no-line-end \