Skip to content

Commit

Permalink
Merge pull request #186 from tegonal/feature/askWithTimeout
Browse files Browse the repository at this point in the history
introduce askWithTimeout and reuse in askYesOrNo
  • Loading branch information
robstoll authored Apr 11, 2024
2 parents 69c2a9f + 9627601 commit 6b8fbca
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 11 deletions.
65 changes: 55 additions & 10 deletions src/utility/ask.sh
Original file line number Diff line number Diff line change
Expand Up @@ -48,18 +48,17 @@ function askYesOrNo() {
local -r question=$1
shift || die "could not shift by 1"

# shellcheck disable=SC2059 # the question itself can have %s thus we use it in the format string
printf "\n\033[0;36m$question\033[0m y/[N]:" "$@"
local -r askYesOrNo_timeout=20
local answer='n'
local -r timeout=20
set +e
read -t "$timeout" -r answer
local lastResult=$?
set -e
if ((lastResult > 128)); then

# shellcheck disable=SC2317 # called by name
function askYesOrNo_noAnswerCallback() {
printf "\n"
logInfo "no user interaction after %s seconds, going to interpret that as a 'no'." "$timeout"
fi
logInfo "no user interaction after %s seconds, going to interpret that as a 'no'." "$askYesOrNo_timeout"
}

# shellcheck disable=SC2059 # the question itself can have %s thus we use it in the format string
askWithTimeout "\033[0;36m$question\033[0m y/[n]:" "$askYesOrNo_timeout" askYesOrNo_noAnswerCallback answer "" "$@"
if [[ $answer == y ]] || [[ $answer == Y ]]; then
return 0
elif [[ $answer == n ]] || [[ $answer == N ]]; then
Expand All @@ -69,3 +68,49 @@ function askYesOrNo() {
return 1
fi
}

function askWithTimeout() {
if (($# < 5)); then
logError "At least five arguments need to be passed to askWithTimeout, given \033[0;36m%s\033[0m\n" "$#"
echo >&2 '1: question the question which the user should answer'
echo >&2 '2: timeout timeout in seconds after which we will call noAnswerFn'
echo >&2 '3: noAnswerFn callback used in case we did not get an answer from the user'
echo >&2 '4: outVarName name of output variable used to pass back the result'
echo >&2 '5: readArgs additional args passed to read'
echo >&2 '6... args... arguments for the question (question is printed with printf)'
printStackTrace
exit 9
fi
# prefixing all variables here as plan to write the answer to an variable which is not in scope of this function
# i.e. if we don't prefix and one using the same name for outVarName as a variable local to this function, then we
# would just assign a value to the local function instead of the variable defined outside this function. The prefix
# prevents such a clash in most likely all cases -- otherwise the user is to blame ;)
local -r askWithTimeout_question=$1
local -r askWithTimeout_timeout=$2
local -r askWithTimeout_noAnswerFn=$3
local -r askWithTimeout_outVarName=$4
local -r askWithTimeout_readArgs=$5
shift 5 || die "could not shift by 5"

exitIfArgIsNotFunction "$askWithTimeout_noAnswerFn" 3
# shellcheck disable=SC2059 # the question itself can have %s thus we use it in the format string
printf "\n$askWithTimeout_question " "$@"
local askWithTimeout_answer=''
set +e
if [[ -n $askWithTimeout_readArgs ]]; then
read -t "$askWithTimeout_timeout" "${askWithTimeout_readArgs?}" -r askWithTimeout_answer
else
read -t "$askWithTimeout_timeout" -r askWithTimeout_answer
fi

local askWithTimeout_lastResult=$?
set -e
if ((askWithTimeout_lastResult > 128)); then
"$askWithTimeout_noAnswerFn"
elif [[ $askWithTimeout_lastResult -eq 0 ]]; then
# that's where the black magic happens, we are assigning to a global (not local to this function) variable here
printf -v "$askWithTimeout_outVarName" "%s" "$askWithTimeout_answer" || die "could not assign value to $askWithTimeout_outVarName"
else
return "$askWithTimeout_lastResult"
fi
}
2 changes: 1 addition & 1 deletion src/utility/parse-args.sh
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ function parseArgumentsInternal {
printStackTrace
exit 9
fi
# that's where the black magic happens, we are assigning to global variables here
# that's where the black magic happens, we are assigning to global (not local to this function) variables here
printf -v "$parseArguments_paramName" "%s" "$2" || die "could not assign value to $parseArguments_paramName"
parseArguments_expectedName=1
((++parseArguments_numOfArgumentsParsed))
Expand Down

0 comments on commit 6b8fbca

Please sign in to comment.