From 110585875c872c6969343c41bb97815f8b0258b5 Mon Sep 17 00:00:00 2001 From: Martin Winkler Date: Sun, 29 May 2022 18:40:32 +0200 Subject: [PATCH] WIP clean old sequencer --- sequencer/sequencer.sh | 1393 ---------------------------------------- 1 file changed, 1393 deletions(-) delete mode 100755 sequencer/sequencer.sh diff --git a/sequencer/sequencer.sh b/sequencer/sequencer.sh deleted file mode 100755 index b124335..0000000 --- a/sequencer/sequencer.sh +++ /dev/null @@ -1,1393 +0,0 @@ -#!/bin/bash - -## Sequencer script is doing nothing on its own. It is included by a squence script -## which uses the sequencer.sh to provide sequencial operations with or without -## user interaction (see generated template which can be generated by calling this -## script directly) - -## Version information - -VERSION_REV=15 -VERSION_MAJOR=3 -VERSION_MINOR=1 - -## Start of generic script part - -QUIET=0 -DRY=0 -VERBOSE=0 -SINGLE=0 -ERNO=0 -SEQUENCER_ARGS= -STEP_ARGS= -STEP_RETURN=255 -readonly MAX_STEP=512 -ALIAS= -CONTEXT_HELP=0 -CONTEXT_EXE=0 -SEQ_NAME="$_SQN_ALIAS" -[ -z "$SEQ_NAME" ] && SEQ_NAME="${0##*/}" -SEQ_CONFIG_EDIT=0 -readonly SEQ_CONFIG_NAME=".seqs" -SEQ_CONFIG_FILE= -SEQ_CONFIG_HOME="$HOME/$SEQ_CONFIG_NAME" -SEQ_PROFILE_NAME= -SEQ_PROFILE_LIST= -readonly TEMPLATE_NAME=seqTemplateExample.sh -readonly MISSING_CONF=missingConf.log -readonly VERSION_STRING="${VERSION_REV}.${VERSION_MAJOR}.${VERSION_MINOR}" -DEFAULT_EDITOR_SYSTEM= - -BBLACK= ; [ -t 1 ] && BBLACK='\033[40m' -BLACK= ; [ -t 1 ] && BLACK='\033[0;30m' -DARKGRAY= ; [ -t 1 ] && DARKGRAY='\033[1;30m' -RED= ; [ -t 1 ] && RED='\033[0;31m' -LIGHTRED= ; [ -t 1 ] && LIGHTRED='\033[1;31m' -GREEN= ; [ -t 1 ] && GREEN='\033[0;32m' -LIGHTGREEN= ; [ -t 1 ] && LIGHTGREEN='\033[1;32m' -ORANGE= ; [ -t 1 ] && ORANGE='\033[0;33m' -YELLOW= ; [ -t 1 ] && YELLOW='\033[1;33m' -BLUE= ; [ -t 1 ] && BLUE='\033[0;34m' -LIGHTBLUE= ; [ -t 1 ] && LIGHTBLUE='\033[1;34m' -PURPLE= ; [ -t 1 ] && PURPLE='\033[0;35m' -LIGHTPURPLE= ; [ -t 1 ] && LIGHTPURPLE='\033[1;35m' -CYAN= ; [ -t 1 ] && CYAN='\033[0;36m' -LIGHTCYAN= ; [ -t 1 ] && LIGHTCYAN='\033[1;36m' -LIGHTGRAY= ; [ -t 1 ] && LIGHTGRAY='\033[0;37m' -WHITE= ; [ -t 1 ] && WHITE='\033[1;37m' -NC= ;[ -t 1 ] && NC='\033[0m' # No Color -SAVE_POS_ALIAS= ;[ -t 1 ] && SAVE_POS_ALIAS='\033[1A\033[1C\033[s\033[1B\033[1C' -SAVE_POS_EXE= ;[ -t 1 ] && SAVE_POS_EXE='\033[s' -SAVE_POS= ;[ -t 1 ] && SAVE_POS='\033[3D\033[s\033[3C' -RESTORE_POS= ;[ -t 1 ] && RESTORE_POS='\033[u' - - -helpSequencer() { - cat <,<,|). - Supporting: dry-run (-d): only print command without execution - verbose (-v): print command before execution - -USAGE_API - echo -e "${GREEN} exep \"[COMMAND STRING(s)]\"${NC}" - cat < \\'out put.log\\' - exep echo hello world \\> out\\\\ put.log - exep "echo hello world > 'out put.log'" - exep "echo hello world > out\\ put.log" - Important: - - Shell commands cd, read, ... won't work because [COMMAND STRING(s)] is started in a new shell. - - All apostrophes need to be esacped since the command line is given as string. - -USAGE_API - echo -e "${GREEN} escpath ${NC}" - cat < [TEMPLATE]${NC}" - cat < [SOURCE TYPE] ${NC}" - cat <) to a destination file. - If the CONFIGFILE exists, a backup (name_%Y%m%d-%H%M%S.bck) is saved at the same location. - If -s fails or -m, "$(realpath "$MISSING_CONF")" is created with the conflicts - to be resolved by the user. - - -c : create a new file - -a : append to existing file - -s : skip if CONFIGFILE exists (no backup and entry in missing conf) - -m : only add content to missing conf and warn user - [SOURCE TYPE] - -f : is a file - - Text or file (-f) to create or added to - - Target file to be created or modified. - -USAGE_API - echo -e "${GREEN} step ${NC}" - cat < [DESCRIPTION]${NC}" - cat < : Name used within eval - [DESCRIPTION] : Additional text for error output - -USAGE_API - echo -e "${GREEN} saveReturn [ERRORCODE]${NC}" - cat <>/dev/null; then - echoseq " [E] Sequence already running" - exit 1 - fi -} - -# Echo only if not -qq ($QUIET -ne 2) -echoseq() { [ $QUIET -ne 2 ] && echo "$@"; } - -# Echo to stderr -echoerr() { outColor red; >&2 echo "$@"; outColor none; } - -# outColor [BACKGROUND COLOR] -outColor() { - [ ! -t 1 ] && return 0 - [ -z "$1" ] && tput sgr0 && return 0 - case "$1" in - black) - tput setaf 0;; - red) - tput setaf 1;; - green) - tput setaf 2;; - yellow) - tput setaf 3;; - blue) - tput setaf 4;; - magenta) - tput setaf 5;; - cyan) - tput setaf 6;; - white) - tput setaf 7;; - none) - tput sgr0 - return 0;; - *) - tput setaf $1;; - esac - - case "$2" in - black) - tput setab 0;; - red) - tput setab 1;; - green) - tput setab 2;; - yellow) - tput setab 3;; - blue) - tput setab 4;; - magenta) - tput setab 5;; - cyan) - tput setab 6;; - white) - tput setab 7;; - esac -} - -# Echo additional line to info correctly indented -INDENT_HELP=' : ' -INDENT_EXE=' ' -INDENTAPPEND_HELP=' ' -echoinfo() { - if [ $CONTEXT_HELP -ne 0 ] ; then - printf '%s' "$INDENTAPPEND_HELP"; echo "$@" - else - printf '%s' "$INDENT_EXE"; echo "$@" - fi -} - -# Echo info about step arguments -# Needs to be called first in _info() function -echoinfoArgs() { - echo -e "${RESTORE_POS}$@" - if [ $CONTEXT_EXE -ne 0 ]; then - printf '%s' "$INDENT_EXE" - else - printf '%s' "$INDENT_HELP" - fi -} - -# Escaping non-printable characters with the proposed POSIX $'' syntax -escpath() { - printf "%q" "$*" -} - -# endCheckEmpty [DESCRIPTION] -# DESCRIPTION : Optional text for error -endCheckEmpty() { - eval 'local ref=$'$1 - - if [ -z $ref ] ; then - if [ -n "$2" ] ; then - echoerr -e " [E] $2\n Sequence stopped." - else - echoerr -e " [E] $1 must not be empty.\n Sequence stopped." - fi - exit 666 - fi -} - -existsFunction() { - local NOTFOUND=0 - declare -F $1 &>>/dev/null || NOTFOUND=1 - return $NOTFOUND -} - -# saveReturn -# Function returns with in case step wants additional evaluation -saveReturn() { - if [ $1 -ne 0 ] ; then - ERNO=$1 - fi - return $ERNO -} - -# getReturn -# Returns latest saved $ERNO -getReturn() { - return $ERNO -} - -# endReturn [-f] [-o ERRORCODE] [MESSAGE] -# -f : force exit with $ERNO without user input -# -o : override and check given error code -# MESSAGE : Custom error message -# -endReturn() { - local arg - local forceExit=0 - local errorCode=$ERNO - local endMessage="" - - for arg in "$@" ; do - case "$1" in - -f) - forceExit=1 - shift - ;; - -o) - shift - local rex='^[-]*[0-9]+$' - # Check if string is a number or alias - if [[ "$1" =~ $rex ]] ; then - errorCode=$1 - else - echoerr " [W] Ignoring invalid error code: $1" - fi - shift - ;; - "") - break - ;; - *) - endMessage="$@" - break - ;; - esac - done - - if [[ ( $errorCode -ne 0 && $QUIET -ne 0 ) || ( $errorCode -ne 0 && $forceExit -ne 0 ) ]] ; then - echo - if [ "$endMessage" != "" ]; then - echoerr -e " [E] $endMessage\n Sequence stopped" - else - echoerr -e " [E] Return value $errorCode detected.\n Sequence stopped" - fi - exit $errorCode - fi - if [ $errorCode -ne 0 ] ; then - echo - if [ "$endMessage" != "" ]; then - echoerr -e " [W] $endMessage" - else - echoerr " [W] Return value $errorCode detected." - fi - read -p "End sequence: [y]/n? " answer - case $answer in - [nN]) - # reset saved error code if user chooses to continue - ERNO=0 - echo - echo " [I] Continuing sequence..." - ;; - *) - echo - echoerr " [E] Sequence stopped" - exit $errorCode; - ;; - esac - fi -} - -# listProfiles [OPTION] [SEARCH] -# List all available profiles for current user -# [OPTION] -# -q : only check for profile support -listProfiles() { - local file= - local profiles=() - if [[ $SEQ_CONFIG_NAME == $(basename "$SEQ_CONFIG_HOME") ]] ; then - echoerr " [E] $SEQ_NAME does not have configuration profiles" - return 1 - fi - [[ "$1" == "-q" ]] && return 0 - for file in $(ls "$SEQ_CONFIG_HOME" 2>/dev/null); do - [[ ${file%.*} =~ ^${1:-".*"} ]] && profiles+=(${file%.*}) - done - printf '%s\n' "${profiles[*]}" -} - -# initSeqConfig [OPTION] [TEMPLATE] -# Create a configuration file in the users' home. -# Source it if already existent -# [OPTION] -# -p : is subfolder used for profiles -# -t : Source config also if created from template -# -e : Create empty configuration if no template is found -# Return -# 0 : Sourced configuration or -# (-t) : created and sourced configuration from template -# 1 : Created configuration from template but not sourced -# 2 : Created empty configuration -# 3 : No configuration created -initSeqConfig() { - local arg - local answer=n - local retVal=255 - local sourceAlways=0 - local createEmpty=0 - local seqProfiles=0 - for arg in "$@" ; do - case "$1" in - -e) - createEmpty=1 - shift - ;; - -p) - seqProfiles=1 - shift - ;; - -t) - sourceAlways=1 - shift - ;; - esac - done - - local configLoc="$SEQ_CONFIG_HOME/$1" - if [ $seqProfiles -ne 0 ] ; then - [ -z "$SEQ_PROFILE_NAME" ] && SEQ_PROFILE_NAME=default - configLoc="$SEQ_CONFIG_HOME/$1/${SEQ_PROFILE_NAME}.cfg" - fi - local configDir="$(dirname $configLoc)" - local configTemplate="$2" - - # Don't create anything if only profiles should be listed - if [ -n "${SEQ_PROFILE_LIST}" ] ; then - SEQ_CONFIG_HOME="$configDir" - return 0 - fi - - SEQ_CONFIG_HOME="$configDir" - - if [ -s "$configLoc" ] ; then - echoseq " [I] Using configuration file: $configLoc" - SEQ_CONFIG_FILE="$configLoc" - . "$configLoc" - return 0 - fi - - # Ask for config creation if not existent - if [ $QUIET -eq 0 ] && [ $DRY -eq 0 ]; then - echo " [I] Configuration $configLoc missing" - exe read -p "Create it now? y/[n]? " answer - case $answer in - [yY]) - ;; - *) - return 3 - ;; - esac - fi - - # Create config subdir in users home - if [ ! -e "$configDir/" ] ; then - echoseq -n " [I] Creating $(realpath $configDir)..." - exe install -m 700 -d "$configDir" && echoseq "Ok" || echoseq "Nok" - fi - - # Config does not exist, check for template - if [ -s "$configTemplate" ] ; then - - # Check first if there is an existing configuration at the templates position - local configExists="$(dirname $configTemplate)/$1" - if [ -s "$configExists" ] ; then - exe mv "$configExists" "$configLoc" - endReturn -o $? "Unable to use existing configuration: $configExists" - - echoerr " [I] Using existing configuration: $configExists" - echoerr " (Moved to $configDir)" - . "$configLoc" - retVal=0 - else - # Install new template to the final location - exe install -m 600 -T "$configTemplate" "$configLoc" - endReturn -o $? "Failed to create configuration" - - if [ $sourceAlways -eq 0 ] ; then - if [ $SEQ_CONFIG_EDIT -eq 0 ] ; then - echoerr " [W] Seq configuration created from template but not used" - echoerr " Please modify "$configLoc" first" - fi - retVal=1 - else - echo " [W] Using seq configuration from template $configTemplate" - echo " (Copied to $configDir)" - . "$configTemplate" - retVal=0 - fi - fi - SEQ_CONFIG_FILE="$configLoc" - else - echo " [W] Seq configuration template not found" - fi - - if [ $createEmpty -ne 0 ] ; then - # Create empty config file - echo " [W] Created empty configuration file $configLoc" - exe touch "$configLoc" - exe chmod 600 "$configLoc" - SEQ_CONFIG_FILE="$configLoc" - retVal=2 - fi - - # Give the user a chance to edit the create config file - if [ $retVal -eq 255 ]; then - echoerr " [E] No seq configuration created" - retVal=3 - elif [ $QUIET -eq 0 ] && [ $DRY -eq 0 ]; then - exe read -p "Edit configuration file now? y/[n]? " answer - case $answer in - [yY]) - exe "$DEFAULT_EDITOR_SYSTEM" "$configLoc" - . "$configLoc" - retVal=0 - ;; - esac - fi - - return $retVal -} - -# addConf [FILE_MODE] -# trying to write a file -# if exists, one attempt is made to create bck file of it -# if all fails, a log file is created with the conflicts to be resolved by the user -addConf() { - local arg - local confMode="" - local transferCmd="echo" - - for arg in $@ ; do - case "$1" in - -c) # create a new file - confMode="-c" - shift - ;; - -a) # append to existing file - confMode="-a" - shift - ;; - -s) # skip if CONFIGFILE exists - confMode="-s" - shift - ;; - -m) # only add content to missing conf and warn user - confMode="-m" - shift - ;; - -f) # choose if source is a file or text - transferCmd="cat" - shift - ;; - *) # default - if [ "$confMode" == "" ] ; then - echoerr " [E] Parameter 1 (-a|-c|-m|-s) missing for addConf()" - exit 0; - fi - ;; - esac - done - - local source="$1" - local dest="$2" - - if [ "$transferCmd" == "cat" ] && [ ! -f "$source" ] ; then - echoerr " [E] Source: \"$source\" does not exist" - return 1; - fi - if [ $DRY -ne 0 ] ; then - echo " [I] Writing $dest ...dry-run" - return 0; - fi - if [ -z "$dest" ] ; then - echoerr " [E] Destination empty" - return 1; - fi - - echo -n " [I] Writing $dest ..." - - if [ $confMode != "-m" ] ; then - # try writing config directly if it doesn't exist - if [ ! -f "$dest" ] ; then - $transferCmd "$source" > "$dest" - echo "ok" - return 0 - fi - - if [ $confMode == "-s" ] ; then - # if skip is selected, don't try to backup but add confilict entry - echo "skipping (exists)" - else - # try backup existing config - local addConfBackup="${dest}_`date +%Y%m%d-%H%M%S`.bck" - if [ ! -f "$addConfBackup" ] ; then - cp -ar "$dest" "$addConfBackup" - if [ $confMode == "-c" ] ; then - $transferCmd "$source" > "$dest" - else - $transferCmd "$source" >> "$dest" - fi - echo -e "ok \n [I] Existing config saved to ${addConfBackup}" - return 0 - else - echo "nok" - echoerr " [W] backup exists" - fi - fi - else - echo -e "ok \n [I] no change requested" - fi - - # add configuration to missingConf file - if [ "$missingDate" = "" ] ; then - missingDate=set - echo -n "### " >> "$MISSING_CONF" - date >> "$MISSING_CONF" - fi - - local helpText="needs to be added manually" - if [ "$confMode" == "-s" ] ; then - helpText="not overwritten" - fi - - echo "#--- \"$dest\" $helpText (Option: $confMode) ---" >> "$MISSING_CONF" - $transferCmd "$source" >> "$MISSING_CONF" - echo >> "$MISSING_CONF" - - echoerr " [W] Check $(realpath "$MISSING_CONF") for configuration conflicts ($dest)" - return 1 -} - -# execute [-q] -# -q: don't stop and don't report step functions which cannot be found -# execute given step_ function -execute() { - local NOTFOUND=0 - local NOREPORT=0 - - if [ $1 == "-q" ] ; then - NOREPORT=1 - shift - fi - - # check if step function exists - declare -F step_$1 &>>/dev/null || NOTFOUND=1 - if [ $NOTFOUND -eq 1 ] && [ $NOREPORT -ne 1 ] ; then - echoerr " [E] Step $1 not found" - exit 1; - fi - - # don't execute step functions which are not available - if [ $NOTFOUND -ne 0 ] ; then - return $NOTFOUND - fi - - if [ $QUIET -ne 2 ] ; then - existsFunction step_${1}_alias - [ $? -eq 0 ] && step_${1}_alias || ALIAS= - printf "\n [%3d] " $1 - if [ -n "$ALIAS" ]; then - echo -en "${ORANGE}$ALIAS${NC}${SAVE_POS_ALIAS}" - # Only add newline if step info() available - existsFunction step_${1}_info - [ $? -eq 0 ] && printf "\n%s" "$INDENT_EXE" - else - echo -en "${SAVE_POS_EXE}" - fi - existsFunction step_${1}_info - if [ $? -eq 0 ] ; then - CONTEXT_EXE=1 - step_${1}_info $1 "${STEP_ARGS[@]}" - CONTEXT_EXE=0 - outColor - else - # Add newline if no info is given - echo - fi - fi - - if [ $QUIET -eq 0 ] ; then - read -p "Start: (y)es/[n]o/(s)kip? " answer - case $answer in - [yY]) - step_$1 $1 "${STEP_ARGS[@]}" - STEP_RETURN=$? - ;; - [sS]) # skip step - STEP_RETURN=0 - return 0 - ;; - *) - local stepId="$1" - # Display alias if exists - existsFunction step_${1}_alias - if [ $? -eq 0 ] ; then - step_${1}_alias - stepId="$ALIAS" - fi - echoerr " [I] Stopping sequence at step: $stepId" - exit 1; - ;; - esac - else - step_$1 $1 "${STEP_ARGS[@]}" - STEP_RETURN=$? - fi - outColor -} - -# checkStep -# return 0 - for invalid step -# return Step Number -# Check sanitiy of step number or -# Check if alias exists -checkStep() { - local checkStep_rex='^[0-9]+$' - local checkStep_ref="" - - # Check if string is a number or alias - if ! [[ "$1" =~ $checkStep_rex ]] ; then - eval 'checkStep_ref=$alias_'"$1" - # Catch special character after eval - if ! [[ "$checkStep_ref" =~ $checkStep_rex ]] ; then - checkStep_ref=0 - fi - else - checkStep_ref=$1 - fi - - if (( $checkStep_ref < 1 || $checkStep_ref > $MAX_STEP )) ; then - echoerr " [E] Invalid step: $1" - return 0 - else - existsFunction step_$checkStep_ref - if [ $? -eq 0 ] ; then - return $checkStep_ref - else - # step doesn't exist - echoerr " [E] Invalid step: $1" - return 0 - fi - fi -} - -# step -# execute given step -step() { - local stepNo=0 - local stepArgs=("$@") - - checkStep "$1" - stepNo=$? - if [ "$stepNo" == "0" ] ; then - return 1 - else - step_$stepNo "${stepArgs[@]}" - fi - outColor -} - -# continous -# (max $MAX_STEP) -# execute sequence continously from given starting step -continous() { - local continous_all=0 - local continous_i - local continous_step=0 - - if [ "$1" == "-a" ]; then - continous_all=1 - shift - fi - - checkStep "$1" - continous_step=$? - [[ $continous_step == 0 ]] && return 1 - - echoseq " [I] Starting sequence $(realpath $0) ..." - - for ((continous_i=$continous_step; continous_i<=${MAX_STEP}; continous_i++)); do - execute -q $continous_i - [ $? -ne 0 ] && [ $continous_all -eq 0 ] && break - [ $STEP_RETURN -ne 0 ] && break - done - return $STEP_RETURN -} - -# selection -# execute given step list -# e.g.: selection -q (1, 4, 12) -selection() { - local selection_i - local selection_step=0 - local selection_array=("$@") - - [ ${#selection_array[@]} -eq 0 ] && return 1 - - echoseq " [I] Starting sequence $(realpath $0) ..." - - for selection_i in ${selection_array[@]} ; do - checkStep "$selection_i" - selection_step=$? - if [ $selection_step -eq 0 ] ; then - return 1 - else - execute $selection_step - fi - done - return $STEP_RETURN -} - -# Creating a minimal seq (step definition) template -createTemplate() { - if [ -f $TEMPLATE_NAME ] ; then - return 1 - fi - cat > $TEMPLATE_NAME << TEMPLATE_EOF -#!/bin/bash - -toolName=mytool - -# Get script working directory -# (when called from a different directory and even when called via symlink) -WDIR="\$(cd "\$(dirname -- "\$(realpath \${BASH_SOURCE[0]})")" >>/dev/null 2>&1 && pwd)" -APTOPT= -CONFIG=0 -SCRIPT_FILE=\$(basename -- \$0) -SCRIPT_NAME=\${SCRIPT_FILE%%.*} -CONFIG_FILE_NAME="\${SCRIPT_NAME}.cfg" -CONFIG_FILE_TEMPLATE="\$WDIR/\${CONFIG_FILE_NAME}.example" - -step_config() { - ## Called once before executing steps. - ## e.g. to source a config file manually: - #. "\$CONFIG_FILE" - - ## or to use sequencer api with profile config file support: - #initSeqConfig -p "\$SCRIPT_NAME" "\$CONFIG_FILE_TEMPLATE" - - ## or to use sequencer api with global config file: - #initSeqConfig "\$CONFIG_FILE_NAME" "\$CONFIG_FILE_TEMPLATE" - #if [ \$? -eq 0 ] ; then - # CONFIG=1 - #else - # # End if no configuration file exists - # [ \$DRY -eq 0 ] && return -1 - #fi - - ## Apt cmdline option to suppress user interaction - [ \$QUIET -ne 0 ] && APTOPT="-y" - - ## Return of non zero value will abort the sequence - return 0 -} - -step_1_info() { echoinfoArgs "[OPTIONS]"; echo "My custom step"; } -step_1_alias() { ALIAS="begin"; } -step_1() { - echo "Doing something for step \$1 ..." - echo "Command line arguments starting with argument 2: \$@" - # Use exe for regular command - # Use exep "command" for commands containing pipes or redirects - exe ls - exep "dmesg | head" -} - -VERSION_SEQREV=${VERSION_REV} -. $0 -TEMPLATE_EOF - - chmod +x $TEMPLATE_NAME - return 0 -} - -# Parse alias functions "step_[STEP NUBER]_alias" to create -# back reference variable of schema: -# alias_[ALIAS]=[STEP NUMBER] -parseAlias() { - local i - for ((i=1; i<=${MAX_STEP}; i++)); do - # Check for alias definition - existsFunction step_${i}_alias - if [ $? -ne 0 ] ; then - continue - fi - - # Function writes global ALIAS variable - step_${i}_alias - - eval 'alias_'$ALIAS'='$i - done -} - -# displayHelp [NO TEMPLATE] [STEP NUMBER OR ALIAS] -# [NO TEMPLATE] -# 0 (default) : Ask for template creation -# 1 : Do not ask for template creation -# [STEP NUMBER OR ALIAS] -# [NO TEMPLATE] must be set -# Display step info function only for given step -# -# - Display sequencer help and, if available, sequence help -# - Cluster continous (more than 1) steps visually together -displayHelp() { - local i - local answer - local clusterSize=0 - local lastClusterSize=0 - local createTemplate=1 - local stepFound=0 - local loopStart=0 - local loopEnd=${MAX_STEP} - CONTEXT_HELP=1 - - # check if help is requested for a single step - if [ -n "$2" ]; then - parseAlias - checkStep "$2" - loopStart=$? - fi - - if [ "$loopStart" == "0" ]; then - helpSequencer - loopStart=1 - else - # Output loop only for one step - loopEnd=$loopStart - fi - - if [ -n "$1" ] && [ $1 -eq 1 ] ; then - createTemplate=0 - fi - - # check if step definition exists by looking for a step_*() function - for ((i=1; i<=${MAX_STEP}; i++)); do - existsFunction step_${i} - if [ $? -ne 0 ] ; then - continue - fi - stepFound=$i - break - done - - if [ $stepFound -eq 0 ] ; then - echo -e "\n It seems ${0##*/} was called directly." - echo -e " Please create a sequence script first.\n" - if [ $createTemplate -ne 0 ] ; then - read -p " Create a template now? y/[n]? " answer - case $answer in - [yY]) - createTemplate - if [ $? -eq 0 ] ; then - echo -e "\n $TEMPLATE_NAME created." - else - echo -e "\n $TEMPLATE_NAME exists...Nothing to do!" - fi - ;; - *) - echo -e "\n Nothing to do!" - ;; - esac - fi - exit 1; - else - echo -e "\n Step (= alias) [STEP ARGS] : documentation" - for ((i=$loopStart; i<=$loopEnd; i++)); do - - # Display step reference in help if step function exists - existsFunction step_${i} - if [ $? -ne 0 ] ; then - if [ $clusterSize -ne 0 ] ; then - # Mark the end of a cluster - lastClusterSize=$clusterSize - clusterSize=0 - fi - continue - fi - ((clusterSize+=1)) - if [ $lastClusterSize -gt 1 ] ; then - # Add separation at the end of a cluster - lastClusterSize=0 - echo - elif [ $clusterSize -eq 1 ]; then - # Add separation before the start of a cluster if it is not the first - existsFunction step_$((i+1)) - [ $? -eq 0 ] && [ $i -ne $stepFound ] && echo - fi - printf ' %3s ' $i - - # Display alias if exists - existsFunction step_${i}_alias - if [ $? -eq 0 ] ; then - step_${i}_alias - echo -en " = ${ORANGE}$ALIAS${NC}${SAVE_POS_ALIAS}" - # Newline only if step info() exists - existsFunction step_${i}_info - [ $? -eq 0 ] && printf '\n%s' "$INDENT_HELP" - else - echo -en " : ${SAVE_POS}" - fi - - # Display step help only if info function exists - existsFunction step_${i}_info - if [ $? -eq 0 ] ; then - step_${i}_info $i - else - echo - fi - outColor - done - echo - fi - CONTEXT_HELP=0 -} - -# listSteps [FILTER STRING] -# [FILTER STRING] -# show only steps and aliases starting with [FILTER STRING] -listSteps() { - local aList=() - local aSearch="$1" - local locAlias= - - for ((i=1; i<=${MAX_STEP}; i++)); do - # Display step reference in help if step function exists - existsFunction step_${i} - [ $? -ne 0 ] && continue - - # Display alias if exists - existsFunction step_${i}_alias - if [ $? -eq 0 ] ; then - step_${i}_alias - locAlias=("$ALIAS") - else - locAlias=("$i") - fi - - if [ -z "$aSearch" ]; then - aList+=("$locAlias") - elif [[ "$locAlias" =~ ^$aSearch ]]; then - aList+=("$locAlias") - fi - done - - [ ${#aList[@]} -ne 0 ] && echo "${aList[@]}" -} - -# showVersion -showVersion() { - echo "Sequencer ${VERSION_STRING}" - echo -n "Seq Revision " - if [ -n "${VERSION_SEQREV}" ] ; then - echo "${VERSION_SEQREV}" - else - echo "-" - fi -} - -exe() { - if [ $DRY -ne 0 ] ; then - echo -n "--" - fi - if [ $DRY -ne 0 ] || [ $VERBOSE -eq 1 ] ; then - (set -x; : "$@") - fi - - if [ $DRY -eq 0 ] ; then - "$@" - fi -} - -# Handle dry run and verbose output for commands containing pipe and/or redirects -# exep -exep() { - if [ $DRY -ne 0 ] ; then - echo "--++ : $*" - elif [ $VERBOSE -eq 1 ] ; then - echo "++ : $*" - fi - - if [ $DRY -eq 0 ] ; then - bash -c "$*" - fi -} - -# Used as editor if no system editor could be found -no_editor_found() { - echoerr " [E] No editor found (\$EDITOR,\"/etc/alternatives\",nano,vi)" - echoerr " Cannot open: $*" -} - -main() { - local arg - local START=0 - local STARTALL - local EMPTYCALL=1 - local quietSave= - local quickStartOne=0 - - # options check - for arg in "$@" ; do - case "$1" in - ++) # end parameter and quickstart step 1 with -qq - quickStartOne=1 - QUIET=2 - shift && break;; - --) # end parameter - shift && break;; - --all|-a) # execute all steps; regardless continouity - STARTALL="-a" - shift;; - --config|-c) # open sequence configuration file - SEQ_CONFIG_EDIT=1 - shift;; - --dry-run|-d) # shows what would be done - DRY=1 - SEQUENCER_ARGS+=" $1" - shift;; - --help|-h) # show only help - displayHelp 1 "$2" - exit 0;; - --helpapi|-ha) #show build-in functions - helpApi - exit 0;; - --liststeps|-ls) - shift - listSteps "$1" - exit 0;; - --profile|-p) # seq profile name - SEQUENCER_ARGS+=" $1 $2" - shift - # Cover the case when only -p is given without profile name - [ -z "$1" ] && SEQ_PROFILE_NAME=default || SEQ_PROFILE_NAME="$1" - shift;; - -pl) # List available profiles with search - shift - QUIET=2 - SEQ_PROFILE_LIST="${1:-".*"}" - shift;; - --quiet|-q|-qq) # detect if option quiet is available - SEQUENCER_ARGS+=" $1" - if [ "$1" == "-qq" ] ; then - QUIET=2 - else - QUIET=1 - fi - shift;; - --single|-s) # execute only one step and stop - SEQUENCER_ARGS+=" $1" - SINGLE=1 - shift;; - --verbose|-v) # set verbose flag - SEQUENCER_ARGS+=" $1" - VERBOSE=1 - shift;; - --version) # version request - showVersion - exit 0;; - esac - done - - # Don't show help if only configuration should be edited - [ $SEQ_CONFIG_EDIT -ne 0 ] && [ -z "$1" ] && QUIET=2 - - if [ -z "$1" ] && [ $quickStartOne -eq 0 ] ; then - if [ $QUIET -eq 0 ] ; then - # Empty -> show help - displayHelp - fi - # Assume starting at one for interactive mode - START=1 - elif [ $quickStartOne -ne 0 ] ; then - EMPTYCALL=0 - START=1 - STEP_ARGS=( "$@" ) - else - EMPTYCALL=0 - read -r -a START <<< "$1" - shift - STEP_ARGS=( "$@" ) - fi - - # compatibility check of sequence - if [ -n "$VERSION_SEQREV" ] && [ $VERSION_SEQREV -gt $VERSION_REV ] ; then - echoerr " [E] Unsupported sequence revision" - showVersion - exit 1 - fi - # exclude older versions if needed - if [ -n "$VERSION_SEQREV" ] && [ $VERSION_SEQREV -lt 3 ] ; then - echoerr " [E] Unsupported sequence revision (addConf)" - showVersion - exit 1 - fi - if [ -z $VERSION_SEQREV ] ; then - echoerr -e " [W] No sequence revision found. Trying anyway...\n"; - fi - - if [ $DRY -ne 0 ] && [ $QUIET -eq 0 ] ; then - echo - echo " [W] Dry run active." - echo " - Printed commands may not be accurate (e.g. quotation incorrect)" - echo " - Sequence may ignore dry run" - read -p "Press enter to continue or Ctrl + C to abort" - fi - - # Determine system default editor - DEFAULT_EDITOR_SYSTEM="$(realpath -eq "/etc/alternatives/editor")" - ## Various fallbacks - [ -z "$DEFAULT_EDITOR_SYSTEM" ] && DEFAULT_EDITOR_SYSTEM="$EDITOR" - [ -z "$DEFAULT_EDITOR_SYSTEM" ] && DEFAULT_EDITOR_SYSTEM="$(command -v nano)" - [ -z "$DEFAULT_EDITOR_SYSTEM" ] && DEFAULT_EDITOR_SYSTEM="$(command -v vi)" - ## Fall back to error message - [ -z "$DEFAULT_EDITOR_SYSTEM" ] && DEFAULT_EDITOR_SYSTEM="no_editor_found" - - parseAlias - - # run configuration for sequence only if available and if first step is valid - existsFunction step_config - if [ $? -eq 0 ] ; then - - # Create/edit configuration file - if [ $SEQ_CONFIG_EDIT -ne 0 ] ; then - # Suppress step_config output for editing - quietSave=$QUIET - QUIET=2 - step_config "${STEP_ARGS[@]}" - QUIET=$quietSave - if [ -w "$SEQ_CONFIG_FILE" ]; then - exe "$DEFAULT_EDITOR_SYSTEM" "$SEQ_CONFIG_FILE" - else - echoerr " [E] No configuration file available" - fi - [ $EMPTYCALL -ne 0 ] && exit 0 - fi - - checkStep "${START[0]}" - if [ $? -ne 0 ] ; then - step_config "${STEP_ARGS[@]}" - if [ $? -ne 0 ]; then - echoerr " [E] Configuring sequence failed" - exit 1 - fi - else - return 1 - fi - elif [ $SEQ_CONFIG_EDIT -ne 0 ] ; then - echoerr " [E] Sequence does not have a configuration file" - return 1 - fi - - # Check for profile support - if [ -n "$SEQ_PROFILE_LIST" ]; then - listProfiles "${SEQ_PROFILE_LIST}"; exit $? - elif [ -n "$SEQ_PROFILE_NAME" ]; then - listProfiles -q || exit 1 - fi - - # check if more than one step is given and select execution mode - if [ $SINGLE -ne 0 ] ; then - selection "${START[0]}" - elif [ "${#START[@]}" -gt "1" ]; then - selection "${START[@]}" - else - continous $STARTALL $START - fi -} - -main "$@" -MAINRETURN=$? - -if [ $QUIET -ne 2 ] ; then - echo - echo "$SEQ_NAME finished" -fi - -exit $MAINRETURN