Files
shell_sequencer/sequencer/sequencer.sh
2021-01-31 17:33:03 +01:00

992 lines
26 KiB
Bash
Executable File

#!/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=12
VERSION_MAJOR=0
VERSION_MINOR=0
## Start of generic script part
QUIET=0
DRY=0
VERBOSE=0
SINGLE=0
ERNO=0
STEP_ARGS=
STEP_RETURN=255
MAX_STEP=512
ALIAS=
SEQ_CONFIG_NAME=".seqs"
SEQ_CONFIG_HOME="$HOME/$SEQ_CONFIG_NAME"
SEQ_CONFIG_FILE=
SEQ_PROFILE_NAME=default
TEMPLATE_NAME=seqTemplateExample.sh
MISSING_CONF=missingConf.log
VERSION_STRING="${VERSION_REV}.${VERSION_MAJOR}.${VERSION_MINOR}"
helpSequencer() {
cat <<USAGE_EOF
Usage: ${0##*/} [OPTIONS] [STEP NUMBER(s) or ALIAS] [STEP ARGUMENTS]
[OPTIONS]
--dry-run, -d : Only print to console what would be done
! Attention - Sequence must support this
--help, -h : Display help
--helpapi, -ha : Display help about build-in supporting functions
(e.g. exe,addconf,echerr,...)
--profile, -p : Sequence configuration profile name (default: \"default\")
If supported by seq
--quiet, -q : Don't ask for permission to execute steps
If called without starting step number, only this help is shown
-qq : Same as --quiet but suppresses regular sequencer.sh output
--single, -s : Execute only one step
If more than one step is requested, only the first will be executed
--verbose, -v : Verbose output (use exe() function to call shell commands in seqs)
( e.g.: exe apt update )
--version : Display version of sequencer and revision of sequence
[STEP NUMBER\"(s)\" 1-${MAX_STEP} or ALIAS]
No STEP or ALIAS : assume 1 as starting point
Single STEP or ALIAS : starting point of sequential process
Multiple STEPS or ALIAS : execute only given steps
(e.g. $0 \"2 4 12\")
multiple steps need to be given as string
[STEP ARGUMENTS]
* : Arguments will be passed to selected steps and step infos as:
\$2 ...
\$1 is always the step number
USAGE_EOF
}
helpApi(){
cat <<USAGE_API
sequencer.sh API
The sequencer.sh build-in functions are available in all sequence functions:
- step_config
If optional step_config is defined in the sequence, it will be called once before any step.
- step_[1-${MAX_STEP}]_info
- step_[1-${MAX_STEP}]_alias
- step_[1-${MAX_STEP}]
sequencer.sh global variables:
\$QUIET
0 : default
1 (-q) : No user interaction (e.g. question to start a step)
2 (-qq) : 1 and no regular output of sequencer.sh
\$DRY
0 : default
1 (-d) : Commands shall only be printed but not executed
\$VERBOSE
0 : default
1 : Print full command from exe() or exep() before executing
\$SEQ_CONFIG_HOME
Path to user specific seq configuration directory
\$SEQ_CONFIG_FILE
Path to user specific seq configuration file
Will be empty if unused
sequencer.sh build-in functions:
exe [COMMANDLINE]
Execute command line without pipes or redirects (>,<,|).
Supporting: dry-run (-d): only print command without execution
verbose (-v): print command before execution
exep \"[COMMANDLINE]\"
See exe, but support for pipes or redirects.
Important:
- Shell commands cd, read, ... won't work because COMMANDLINE is started in a new shell.
- All apostrophes need to be esacped since the command line is given as string.
initSeqConfig [OPTION] <NAME> [TEMPLATE]
Create a configuration file in $SEQ_CONFIG_HOME/ and source it if already existent.
[OPTION]
-p : Use profiles
-t : Source config also if created from template
-e : Create empty configuration if no template is found
Returns
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
addConf <OPTIONS> [SOURCE TYPE] <SOURCE> <DESTINATION FILE>
Trying to write or append text or a file (<SOURCE>) 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.
<OPTIONS>
-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 : <SOURCE> is a file
<SOURCE>
Text or file (-f) to create or added to <DESTINATION FILE>
<DESTINATION FILE>
Target file to be created or modified.
step <STEP NUMBER OR ALIAS>
Executes a single step also by alias. Useful if step numbers get reorganized.
dry-run is not applied in this function! The executed step is responsible.
echoerr [...]
echo to stderr
[...] : all parameter are forwarded to echo
echoinfo [...]
echo additional correctly indented line to step info
[...] : all parrameter are forwared to echo
endCheckEmpty <VARIABLENAME> [DESCRIPTION]
exit 666 if variable is empty
<VARIABLENAME> : Name used within eval
[DESCRIPTION] : Additional text for error output
saveReturn [ERRORCODE]
Save ERRORCODE if it is != 0 for later use with endReturn
getReturn
Return last saved error code
endReturn [OPTIONS] [MESSAGE]
Notifys user that there was an error (previously saved by saveReturn,
or -o [ERRORCODE]) and asks to continue or end the sequence.
Always exits with evaluated error code.
[OPTIONS]
-f : force exit without user input, if error code is not 0
-o ERRORCODE : override stored error code and check ERRORCODE
[MESSAGE]
String which is displayed in the error output
USAGE_API
}
# Echo to stderr
echoerr() { >&2 echo "$@"; }
# Echo additional line to info correctly indented
CONTEXT_HELP=0
INDENT_HELP=' : '
INDENTAPPEND_HELP=' '
INDENTAPPEND_INFO=' '
echoinfo() {
if [ $CONTEXT_HELP -ne 0 ] ; then
printf '%s' "$INDENTAPPEND_HELP"; echo "$@"
else
printf '%s' "$INDENTAPPEND_INFO"; echo "$@"
fi
}
# endCheckEmpty <VariableName> [DESCRIPTION]
# DESCRIPTION : Optional text for error
endCheckEmpty() {
eval 'local ref=$'$1
if [ -z $ref ] ; then
if [ ! -z "$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 <ERRNO>
# Function returns with <ERRNO> 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
}
# initSeqConfig [OPTION] <NAME> [TEMPLATE]
# Create a configuration file in the users' home.
# Source it if already existent
# [OPTION]
# -p : <NAME> 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 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
configLoc="$SEQ_CONFIG_HOME/$1/${SEQ_PROFILE_NAME}.cfg"
fi
local configDir="$(dirname $configLoc)"
local configTemplate="$2"
# Create config subdir in users home
if [ ! -e "$configDir/" ] ; then
echo -n " [I] Creating $(realpath $configDir)..."
exe mkdir -p "$configDir" && echo "Ok" || echo "Nok"
exe chmod 700 "$configDir"
fi
if [ -s "$configLoc" ] ; then
if [ $QUIET -ne 2 ] ; then echo " [I] Using configuration file: $configLoc" ; fi
SEQ_CONFIG_FILE="$configLoc"
. "$configLoc"
return 0
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"
return 0
fi
exe cp -ar "$configTemplate" "$configLoc"
endReturn -o $? "Failed to create configuration"
exe chmod 600 "$configLoc"
if [ $sourceAlways -eq 0 ] ; then
echoerr " [W] Seq configuration created from template but not used"
echoerr " Please modify "$configLoc" first and restart sequence"
return 1
else
echo " [W] Using seq configuration from template $configTemplate"
echo " (Copied to $configDir)"
SEQ_CONFIG_FILE="$configLoc"
. "$configLoc"
return 0
fi
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"
return 2
fi
echoerr " [E] No seq configuration created"
return 3
}
# addConf <CONF_MODE> [FILE_MODE] <SOURCE> <DESTINATION_FILE>
# 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 [ "$dest" == "" ] ; then
echoerr " [E] Destination empty"
return 1;
fi
if [ "$DRY" -ne 0 ] ; then
echo " [I] Writing $dest ...dry-run"
return 0;
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] <Step Number>
# -q: don't stop and don't report step functions which cannot be found
# execute given step_<Step Number> 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
echo -en "\n [STEP $1] "
existsFunction step_${1}_info
if [ $? -eq 0 ] ; then
step_${1}_info $1 "${STEP_ARGS[@]}"
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
}
# checkStep <Step Number or Alias>
# return 0 - for invalid step
# return Step Number
# Check sanitiy of step number or
# Check if alias exists
checkStep() {
local rex='^[0-9]+$'
local ref=""
# Check if string is a number or alias
if ! [[ "$1" =~ $rex ]] ; then
eval 'ref=$alias_'"$1"
# Catch special character after eval
if ! [[ "$ref" =~ $rex ]] ; then
ref=0
fi
else
ref=$1
fi
if (( $ref < 1 || $ref > $MAX_STEP )) ; then
echoerr " [E] Invalid step: $ref"
return 0
else
existsFunction step_$ref
if [ $? -eq 0 ] ; then
return $ref
else
# step doesn't exist
echoerr " [E] Invalid step: $ref"
return 0
fi
fi
}
# step <Step Number of Alias>
# execute given step
step() {
local stepNo=0
local stepArgs=("$@")
checkStep "$1"
stepNo=$?
if [ "$stepNo" == "0" ] ; then
return 1
else
step_$stepNo "${stepArgs[@]}"
fi
}
# continous <Starting Step Number>
# (max $MAX_STEP)
# execute sequence continously from given starting step
continous() {
local i
local step=0
checkStep "$1"
step=$?
if [[ $step == 0 ]] ; then
return 1
fi
if [ $QUIET -ne 2 ]; then echo " [I] Starting sequence $(realpath $0) ..."; fi
for ((i=$step; i<=${MAX_STEP}; i++)); do
execute -q $i
local res=$?
if [ $res -ne 0 ] ; then
break
fi
if [ $STEP_RETURN -ne 0 ] ; then
break
fi
done
return $STEP_RETURN
}
# selection <STEP ARRAY>
# execute given step list
# e.g.: selection -q (1, 4, 12)
selection() {
local i
local step=0
local array=("$@")
if [ ${#array[@]} -eq 0 ] ; then
return 1
fi
if [ $QUIET -ne 2 ]; then echo " [I] Starting sequence $(realpath $0) ..."; fi
for i in ${array[@]} ; do
checkStep "$i"
step=$?
if [ $step -eq 0 ] ; then
return 1
else
execute $step
fi
done
return $STEP_RETURN
}
# Creating a minimal seq (step definition) template
createTemplate() {
if [ -f $TEMPLATE_NAME ] ; then
return 1
fi
echo "#!/bin/bash" > $TEMPLATE_NAME
echo >> $TEMPLATE_NAME
echo "toolName=mytool" >> $TEMPLATE_NAME
echo >> $TEMPLATE_NAME
echo "# Get script working directory" >> $TEMPLATE_NAME
echo "# (when called from a different directory)" >> $TEMPLATE_NAME
echo "WDIR=\"\$( cd \"\$( dirname \"\${BASH_SOURCE[0]}\" )\" >>/dev/null 2>&1 && pwd )\"" >> $TEMPLATE_NAME
echo "CONFIG=0" >> $TEMPLATE_NAME
echo "CONFIG_FILE_NAME=\"\${toolName}.cfg\"" >> $TEMPLATE_NAME
echo "CONFIG_FILE_TEMPLATE=\"\$WDIR/\${CONFIG_FILE_NAME}.example\"" >> $TEMPLATE_NAME
echo >> $TEMPLATE_NAME
echo "step_config() {" >> $TEMPLATE_NAME
echo " echo \"Called once before executing steps.\"" >> $TEMPLATE_NAME
echo " ## e.g. to source a config file manually:" >> $TEMPLATE_NAME
echo " #. \"\$CONFIG_FILE\"" >> $TEMPLATE_NAME
echo " ## or to use sequencer api:" >> $TEMPLATE_NAME
echo " #initSeqConfig \"\$CONFIG_FILE_NAME\" \"\$CONFIG_FILE_TEMPLATE\"" >> $TEMPLATE_NAME
echo " #if [ \$? -eq 0 ] ; then" >> $TEMPLATE_NAME
echo " # CONFIG=1" >> $TEMPLATE_NAME
echo " #fi" >> $TEMPLATE_NAME
echo "}" >> $TEMPLATE_NAME
echo >> $TEMPLATE_NAME
echo "step_1_info() { echo \"My custom step\"; }" >> $TEMPLATE_NAME
echo "step_1_alias() { ALIAS=\"begin\"; }" >> $TEMPLATE_NAME
echo "step_1() {" >> $TEMPLATE_NAME
echo " echo \"Doing something for step \$1 ...\"" >> $TEMPLATE_NAME
echo " echo \"Command line arguments starting with argument 2: \$@\"" >> $TEMPLATE_NAME
echo " # Use exe for regular command" >> $TEMPLATE_NAME
echo " # Use exep \"command\" for commands containing pipes or redirects" >> $TEMPLATE_NAME
echo " exe ls" >> $TEMPLATE_NAME
echo " exep \"dmesg | grep usb\"" >> $TEMPLATE_NAME
echo "}" >> $TEMPLATE_NAME
echo >> $TEMPLATE_NAME
echo "VERSION_SEQREV=${VERSION_REV}" >> $TEMPLATE_NAME
echo ". $0" >> $TEMPLATE_NAME
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]
# [NO TEMPLATE]
# 0 (default) : Ask for template creation
# 1 : Do not ask for template creation
# - Always 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 stepsFound=0
CONTEXT_HELP=1
helpSequencer
if [ ! -z $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
stepsFound=1
done
if [ $stepsFound -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) documentation:"
for ((i=1; i<=${MAX_STEP}; i++)); do
# Display step reference in help if step function exists
existsFunction step_${i}
if [ $? -ne 0 ] ; then
if [ $clusterSize -ne 0 ] ; then
lastClusterSize=$clusterSize
clusterSize=0
fi
continue
fi
((clusterSize+=1))
if [ $lastClusterSize -gt 1 ] ; then
lastClusterSize=0
echo
fi
printf ' Step %3s ' $i
# Display alias if exists
existsFunction step_${i}_alias
if [ $? -eq 0 ] ; then
step_${i}_alias
echo " = $ALIAS"
printf '%s' "$INDENT_HELP"
else
echo -n " : "
fi
# Display step help only if info function exists
existsFunction step_${i}_info
if [ $? -eq 0 ] ; then
step_${i}_info $i
else
echo " - step_${i}_info() missing"
fi
done
echo
fi
CONTEXT_HELP=0
}
# showVersion
showVersion() {
echo "Sequencer ${VERSION_STRING}"
echo -n "Seq Revision "
if [ ! -z "${VERSION_SEQREV}" ] ; then
echo "${VERSION_SEQREV}"
else
echo "-"
fi
}
exe() {
local arr=("$@")
if [ $DRY -ne 0 ] ; then
echo -n "--"
fi
if [ $DRY -ne 0 ] || [ $VERBOSE -eq 1 ] ; then
(set -x; : "${arr[@]}")
fi
if [ $DRY -eq 0 ] ; then
"${arr[@]}"
fi
}
# Handle dry run and verbose output for commands containing pipe and/or redirects
# exep <COMMAND TO RUN AS STRING>
exep() {
if [ $DRY -ne 0 ] ; then
echo "--++ : $1"
elif [ $VERBOSE -eq 1 ] ; then
echo "++ : $1"
fi
if [ $DRY -eq 0 ] ; then
bash -c "$1"
fi
}
main() {
local arg
local START=0
local EMPTYCALL=1
# options check
for arg in "$@" ; do
case "$1" in
--dry-run|-d) # shows what would be done
DRY=1
shift
;;
--help|-h) # show only help
displayHelp 1
exit 0;
;;
--helpapi|-ha) #show build-in functions
helpApi
exit 0;
;;
--profile|-p) # seq profile name
shift
SEQ_PROFILE_NAME="$1"
shift
;;
--quiet|-q|-qq) # detect if option quiet is available
if [ "$1" == "-qq" ] ; then
QUIET=2
else
QUIET=1
fi
shift
;;
--single|-s) # execute only one step and stop
SINGLE=1
shift
;;
--verbose|-v) # set verbose flag
VERBOSE=1
shift
;;
--version) # version request
showVersion
exit 0;
;;
esac
done
if [ -z "$1" ] || [ "$1" == "" ] ; then
if [ $QUIET -eq 0 ] ; then
# Empty -> show help
displayHelp
fi
# Assume starting at one for interactive mode
START=1
else
EMPTYCALL=0
read -r -a START <<< "$1"
shift
STEP_ARGS=( "$@" )
fi
# compatibility check of sequence
if [ ! -z $VERSION_SEQREV ] && [ $VERSION_SEQREV -gt $VERSION_REV ] ; then
echoerr " [E] Unsupported sequence revision"
showVersion
exit 1
fi
# exclude older versions if needed
if [ ! -z $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
parseAlias
# run configuration for seq only if available and if first step is valid
existsFunction step_config
if [ $? -eq 0 ] ; then
checkStep "${START[0]}"
if [ $? -ne 0 ] ; then
if [ $QUIET -ne 2 ] ; then echo " [I] Configuring sequence (step_config) ..." ; fi
step_config "${STEP_ARGS[@]}"
else
return 1
fi
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 $START
fi
}
main "$@"
MAINRETURN=$?
if [ $QUIET -ne 2 ] ; then
echo
echo "${0##*/} finished"
fi
exit $MAINRETURN;