WIP additional functions, system text editor detection, fix listSteps output

Adding sequence template
This commit is contained in:
2022-05-17 14:34:27 +02:00
parent ea6e85a020
commit a67c92555d
2 changed files with 186 additions and 25 deletions

51
seqTemplate.sh Executable file
View File

@@ -0,0 +1,51 @@
#!/usr/bin/env bash
readonly toolName=mytool
# Get script working directory
# (when called from a different directory and even when called via symlink)
readonly sq_dir="$(cd "$(dirname -- "$(realpath ${BASH_SOURCE[0]})")" >>/dev/null 2>&1 && pwd)"
readonly sq_scriptFile=$(basename -- $0)
readonly sq_scriptName=${sq_scriptFile%%.*}
readonly sq_configFileName="${sq_scriptName}.cfg"
readonly sq_configFileTemplate="$sq_dir/${sq_configFileName}.example"
sq_aptOpt=
sq_config=0
step_config() {
## Called once before executing steps.
## e.g. to source a config file manually:
#. "$sq_config_FILE"
## or to use sequencer api with profile config file support:
#initSeqConfig -p "$sq_scriptName" "$sq_configFileTemplate"
## or to use sequencer api with global config file:
#initSeqConfig "$sq_configFileName" "$sq_configFileTemplate"
#if [ $? -eq 0 ] ; then
# sq_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 ] && sq_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() { echo "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=16
. /usr/local/bin/sequencer.sh

View File

@@ -12,7 +12,7 @@ set -o pipefail
# Turn on traces, useful while debugging but commented out by default
# set -o xtrace
## Globals
## Globals
{
readonly _sqr_version=16
readonly _sqr_versionMajor=0
@@ -44,9 +44,12 @@ set -o pipefail
_sqr_debug=0
_sqr_dry=0
_sqr_verbose=0
_sqr_errno=0
sqr_editor=
# Colors
col_black= ; [ -t 1 ] && col_black='\033[0;30m'
col_black= ; [ -t 1 ] && col_black='\033[0;30m'
col_darkgrey= ; [ -t 1 ] && col_darkgrey='\033[1;30m'
col_red= ; [ -t 1 ] && col_red='\033[0;31m'
col_lightred= ; [ -t 1 ] && col_lightred='\033[1;31m'
@@ -95,7 +98,7 @@ set -o pipefail
--)
shift && break ;;
-a)
appendText=1
appendText=1
shift ;;
-e)
outp='/dev/stderr'
@@ -119,7 +122,7 @@ set -o pipefail
fi
if (( ! appendText )) ; then
printf " %3s " "[${log_level}]" >${outp}
printf " %3s " "[${log_level}]" >${outp}
printf "%s" "${log_line}" >${outp}
else
# +3 : "[] "
@@ -137,9 +140,10 @@ set -o pipefail
info () { [[ "${LOG_LEVEL:-0}" -ge 3 ]] && sqr::log "i" "" "${@}"; true; }
debug () { [[ "${LOG_LEVEL:-0}" -ge 4 ]] && sqr::log "dbug" "${col_lightpurple}" "${@}"; true; }
# internal printf same loglevel as info
# internal print(s) same loglevel as error
# shellcheck disable=SC2059 # don't use variables in format
sqr::print () { [[ "${LOG_LEVEL:-0}" -ge 1 ]] && printf "$@"; true; }
sqr::printf () { [[ "${LOG_LEVEL:-0}" -ge 1 ]] && printf "$@"; true; }
sqr::echo () { [[ "${LOG_LEVEL:-0}" -ge 1 ]] && echo "$@"; true; }
sqr::debugPause() {
if (( _sqr_debug )) ; then set +o xtrace; else true; fi
@@ -173,7 +177,7 @@ set -o pipefail
tput sgr0
return 0 ;;
*)
tput setaf ${1:-} ;;
tput setaf "${1:-}" ;;
esac
case "${2:-}" in
@@ -216,15 +220,18 @@ set -o pipefail
# trap 'sqr::error_report "${FUNCNAME:-.}" ${LINENO}' ERR
}
# check if run as root
root() {
[[ $(id -u) -eq 0 ]]
}
# check if there is another PID other than this one
running() {
pidof -o %PPID -x "${0##*/}">>/dev/null
}
# exists [-f] [--] [ELEMENT]
# [ELEMENT]
# : either a variable name or
# -f : function
# -f : a function
exists() {
sqr::debugPause
local func=
@@ -245,7 +252,6 @@ exists() {
[[ -n "${!1:-}" ]]
fi
}
# interactive
# Started with -q to use defaults for confirmations
interactive() {
@@ -275,7 +281,7 @@ verbose() {
### interactive
# confirm [OPTIONS] [--] [QUESTION]
# Default (empty character) = no
#
#
# [OPTIONS]
# -f : interactive even if quiet
# -n : no input help
@@ -308,7 +314,9 @@ confirm() {
(( noHelp )) && inputHelp=
if interactive || (( force )) ; then
read -r -p "${1:-} ${inputHelp}" -n 1
echo ""
# Needed when read stops after one character (-n 1)
# Add a newline only if input is not empty (just enter is pressed)
[[ -z "$REPLY" ]] || sqr::echo ""
else
REPLY=''
fi
@@ -345,7 +353,7 @@ ask() {
done
local answer=
if [[ -n "${2:-}" ]] ; then
! interactive && printf '%s\n' "${2}" && sqr::debugContinue && return 0
! interactive && printf '%s\n' "${2}" && sqr::debugContinue && return 0
read ${hidden?} -r -p "${1:-"User input"} ($2) " answer
else
read ${hidden?} -r -p "${1:-"User input"} " answer
@@ -361,25 +369,111 @@ ask() {
[[ -n "${answer}" ]]
fi
}
# Escaping non-printable characters with the proposed POSIX $'' syntax
escpath() {
printf "%q" "$*"
}
# saveReturn <ERRNO>
# Function returns with <ERRNO> in case step wants additional evaluation
saveReturn() {
if [[ "${1:-"0"}" -ne 0 ]] ; then
_sqr_errno=${1}
fi
return "${_sqr_errno}"
}
# getReturn
# Returns latest saved $_sqr_errno
getReturn() {
return "${_sqr_errno}"
}
# endReturn [-f] [-o ERRORCODE] [MESSAGE]
# -f : force exit with $_sqr_errno without user input
# -o : override and check given error code
# MESSAGE : Custom error message
#
endReturn() {
local arg
local forceExit=0
local errorCode=${_sqr_errno}
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
warning " [W] Ignoring invalid error code: $1"
fi
shift
;;
"")
break
;;
*)
endMessage="$*"
break
;;
esac
done
if ( [[ ${errorCode} -ne 0 ]] && ! interactive ) \
|| [[ ${errorCode} -ne 0 && $forceExit -ne 0 ]] ; then
sqr::echo
if [[ -n "${endMessage}" ]] ; then
error -e "${endMessage}"
error -e -a "Sequence stopped"
else
error -e "Return value ${errorCode} detected."
error -e -a "Sequence stopped"
fi
exit "${errorCode}"
fi
if [[ "${errorCode}" -ne 0 ]] ; then
sqr::echo
if [ "${endMessage}" != "" ]; then
error -e "${endMessage}"
else
error -e "Return value ${errorCode} detected."
fi
if confirm -y "End sequence"; then
error -e "Sequence stopped"
exit "${errorCode}";
else
# reset saved error code if user chooses to continue
_sqr_errno=0
sqr::echo
warning "Continuing sequence..."
fi
fi
}
# listSteps [FILTER STRING]
# [FILTER STRING]
# show only steps and aliases starting with [FILTER STRING]
listSteps() {
local locAlias=
local aList=()
local aSearch="${1:-}"
local locAlias=
for ((i=1; i<=${_sqr_stepMax}; i++)); do
for ((i=1; i<=_sqr_stepMax; i++)); do
# Display step reference in help if step function exists
exists -f step_${i} || continue
exists -f "step_${i}" || continue
# Display alias if exists
if exists -f step_${i}_alias ; then
step_${i}_alias
locAlias=("$ALIAS")
if exists -f "step_${i}_alias" ; then
locAlias="$("step_${i}_alias")"
else
locAlias=("$i")
locAlias="$i"
fi
if [ -z "$aSearch" ]; then
@@ -389,7 +483,7 @@ listSteps() {
fi
done
[ ${#aList[@]} -ne 0 ] && printf '%s\n' "${aList[@]}"
[ ${#aList[@]} -ne 0 ] && printf '%s\n' "${aList[*]}"
}
# showVersion
@@ -404,9 +498,9 @@ exe() {
dry && printf -- '--'
if dry || verbose ; then
(set -x; : "$@")
fi
fi
if ! dry ; then
if ! dry ; then
"$@"
fi
}
@@ -420,11 +514,17 @@ exep() {
printf '++ : %s\n' "$*"
fi
if ! dry ; then
if ! dry ; then
bash -c "$*"
fi
}
# Used as editor if no system editor could be found
sqr::noEditor() {
error "No editor found (\$EDITOR,\"/etc/alternatives\",nano,vi)"
error -a "Cannot open: $*"
}
sqr::main() {
# options check
for arg in "$@" ; do
@@ -463,7 +563,17 @@ sqr::main() {
trap 'sqr::error_report "${FUNCNAME:-.}" ${LINENO}' ERR
fi
sqr::print 'Running...\n'
# Determine system default editor
# Change with update-alternatives --config editor
sqr_editor="$(realpath -eq "/etc/alternatives/editor")"
## Various fallbacks
[ -z "${sqr_editor}" ] && sqr_editor="$EDITOR"
[ -z "${sqr_editor}" ] && sqr_editor="$(command -v nano)"
[ -z "${sqr_editor}" ] && sqr_editor="$(command -v vi)"
## Fall back to error message
[ -z "${sqr_editor}" ] && sqr_editor="sqr::noEditor"
sqr::printf 'Running...\n'
seq_config 2>/dev/null || true
step_1 "$@"
}