Skip to content

Adds custom error codes #236

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 16 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 35 additions & 25 deletions go-core.bash
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,14 @@
# https://mike-bland.com/
# https://github.com/mbland

_GO_EC_GENERR="${_GO_EC_GENERR:-70}"
_GO_EC_DEPMISS="${_GO_EC_DEPMISS:-72}"

if [[ "${BASH_VERSINFO[0]}" -lt '3' ||
( "${BASH_VERSINFO[0]}" -eq '3' && "${BASH_VERSINFO[1]}" -lt '2' ) ]]; then
printf "This module requires bash version 3.2 or greater:\n %s %s\n" \
"$BASH" "$BASH_VERSION"
exit 1
exit "$_GO_EXIT_DEPMISS"
fi

# The version of the framework
Expand All @@ -46,7 +49,7 @@ declare -r -x _GO_CORE_VERSION='v1.7.0'
declare -r -x _GO_CORE_URL='https://github.com/mbland/go-script-bash'

declare __go_orig_dir="$PWD"
cd "${0%/*}" || exit 1
cd "${0%/*}" || exit "$_GO_EC_GENERR"

# Path to the project's root directory
#
Expand All @@ -56,21 +59,23 @@ cd "${0%/*}" || exit 1
declare -x _GO_ROOTDIR="$PWD"

if [[ "${BASH_SOURCE[0]:0:1}" != '/' ]]; then
cd "$__go_orig_dir/${BASH_SOURCE[0]%/*}" || exit 1
cd "$__go_orig_dir/${BASH_SOURCE[0]%/*}" || exit "$_GO_EC_GENERR"
else
cd "${BASH_SOURCE[0]%/*}" || exit 1
cd "${BASH_SOURCE[0]%/*}" || exit "$_GO_EC_GENERR"
fi

# Path to the ./go script framework's directory
declare -r -x _GO_CORE_DIR="$PWD"

. "$_GO_CORE_DIR/lib/internal/sysexits"

# Set _GO_STANDALONE if your script is a standalone program.
#
# See the "Standalone mode" section of README.md for more information.
if [[ -z "$_GO_STANDALONE" ]]; then
cd "$_GO_ROOTDIR" || exit 1
cd "$_GO_ROOTDIR" || exit "$_GO_EC_GENERR"
else
cd "$__go_orig_dir" || exit 1
cd "$__go_orig_dir" || exit "$_GO_EC_GENERR"
fi
unset __go_orig_dir

Expand Down Expand Up @@ -193,6 +198,8 @@ declare _GO_INJECT_MODULE_PATH="$_GO_INJECT_MODULE_PATH"
done
printf '%s' "$line"
done <<<"${result//$'\n'/$'\n\x1f'}"$'\x1f'

return "$_GO_EC_OK"
}

# Prints the stack trace at the point of the call.
Expand All @@ -205,17 +212,17 @@ declare _GO_INJECT_MODULE_PATH="$_GO_INJECT_MODULE_PATH"
# skip_callers: The number of callers to skip over when printing the stack
@go.print_stack_trace() {
local skip_callers="$1"
local result=0
local result="$_GO_EC_OK"
local i

if [[ -n "$skip_callers" && ! "$skip_callers" =~ ^[1-9][0-9]*$ ]]; then
printf '%s argument %s not a positive integer; printing full stack\n' \
"$FUNCNAME" "'$skip_callers'" >&2
result=1
result="$_GO_EC_GENERR"
elif [[ "$skip_callers" -ge "${#FUNCNAME[@]}" ]]; then
printf '%s argument %d exceeds stack size %d; printing full stack\n' \
"$FUNCNAME" "$skip_callers" "$((${#FUNCNAME[@]} - 1))" >&2
result=1
result="$_GO_EC_GENERR"
fi

if [[ "$result" -ne '0' ]]; then
Expand Down Expand Up @@ -263,15 +270,15 @@ declare _GO_INJECT_MODULE_PATH="$_GO_INJECT_MODULE_PATH"
# search_func: Helper function implementing the search operation
#
# Returns:
# Zero if `search_func` ever returns zero, nonzero otherwise
# _GO_EC_OK if `search_func` ever returns zero, _GO_EC_GENERR otherwise
@go.search_plugins() {
local __gsp_plugins_dir="$_GO_SCRIPTS_DIR/plugins"

while true; do
if "$1" "$__gsp_plugins_dir"; then
return
return "$_GO_EC_OK"
elif [[ "$__gsp_plugins_dir" == "$_GO_PLUGINS_DIR" ]]; then
return 1
return "$_GO_EC_GENERR"
fi
__gsp_plugins_dir="${__gsp_plugins_dir%/plugins/*}/plugins"
done
Expand All @@ -289,20 +296,20 @@ declare _GO_INJECT_MODULE_PATH="$_GO_INJECT_MODULE_PATH"
case "$cmd" in
'')
[email protected]_builtin 'help' 1>&2
return 1
return "$_GO_EC_USAGE"
;;
-h|-help|--help)
cmd='help'
;;
-*)
@go.printf "Unknown flag: $cmd\n\n"
[email protected]_builtin 'help' 1>&2
return 1
return "$_GO_EC_USAGE"
;;
edit)
if [[ -z "$EDITOR" ]]; then
echo "Cannot edit $@: \$EDITOR not defined."
return 1
return "$_GO_EC_CONFIG"
fi
"$EDITOR" "$@"
return
Expand All @@ -314,7 +321,7 @@ declare _GO_INJECT_MODULE_PATH="$_GO_INJECT_MODULE_PATH"
cd|pushd|unenv)
@go.printf "$cmd is only available after using \"$_GO_CMD env\" %s\n" \
"to set up your shell environment." >&2
return 1
return "$_GO_EC_USAGE"
;;
esac

Expand All @@ -329,7 +336,7 @@ declare _GO_INJECT_MODULE_PATH="$_GO_INJECT_MODULE_PATH"
local __go_argv

if ! [email protected]_command_path_and_argv "$cmd" "$@"; then
return 1
return "$_GO_EC_GENERR"
fi

if [[ "${__go_cmd_path#$_GO_SCRIPTS_DIR}" =~ /plugins/[^/]+/bin/ ]]; then
Expand Down Expand Up @@ -366,7 +373,7 @@ [email protected]_command_script() {
@go.printf \
"The first line of %s does not contain #!/path/to/interpreter.\n" \
"$cmd_path" >&2
return 1
return "$_GO_EC_BADFRMT"
fi

interpreter="${interpreter%$'\r'}"
Expand All @@ -383,7 +390,7 @@ [email protected]_command_script() {
. "$cmd_path" "$@"
elif [[ -z "$interpreter" ]]; then
@go.printf "Could not parse interpreter from first line of $cmd_path.\n" >&2
return 1
return "$_GO_EC_BADFRMT"
else
if [[ -z "$_GO_CMD_NAME" ]]; then
local origIFS="$IFS"
Expand All @@ -401,23 +408,26 @@ [email protected]_scripts_dir() {

if [[ "$#" -ne '1' ]]; then
echo "ERROR: there should be exactly one command script dir specified" >&2
return 1
return "$_GO_EC_CONFIG"
elif [[ ! -e "$scripts_dir" ]]; then
echo "ERROR: command script directory $scripts_dir does not exist" >&2
return 1
return "$_GO_EC_CONFIG"
elif [[ ! -d "$scripts_dir" ]]; then
echo "ERROR: $scripts_dir is not a directory" >&2
return 1
return "$_GO_EC_CONFIG"
elif [[ ! -r "$scripts_dir" || ! -x "$scripts_dir" ]]; then
echo "ERROR: you do not have permission to access the $scripts_dir" \
"directory" >&2
return 1
return "$_GO_EC_NOPERM"
fi
_GO_SCRIPTS_DIR="$scripts_dir"
return "$_GO_EC_OK"
}

if ! [email protected]_scripts_dir "$@"; then
exit 1
[email protected]_scripts_dir "$@" && ec=0 || ec="$?"

if [[ "$ec" -ne "$_GO_EC_OK" ]]; then
exit "$ec"
elif [[ -z "$COLUMNS" ]]; then
# On Travis, $TERM is set to 'dumb', but `tput cols` still fails.
if command -v tput >/dev/null && tput cols >/dev/null 2>&1; then
Expand Down
16 changes: 8 additions & 8 deletions go-template
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ download_go_script_bash_tarball() {

if [[ "$protocol" == "$url" ]]; then
printf 'GO_SCRIPT_BASH_DOWNLOAD_URL has no protocol: %s\n' "$url" >&2
return 1
return "$_GO_EC_CONFIG"
elif [[ "$(git --version)" =~ windows && "$protocol" == 'file' ]]; then
url="file://$(cygpath -m "${url#file://}")"
fi
Expand All @@ -74,28 +74,28 @@ download_go_script_bash_tarball() {
download_cmd=(wget -O - "$url")
else
printf "Failed to find cURL, wget, or fetch\n" >&2
return 1
return "$_GO_EC_DEPMISS"
fi

if ! command -v tar >/dev/null; then
printf "Failed to find tar\n" >&2
return 1
return "$_GO_EC_DEPMISS"
fi
printf "Downloading framework from '%s'...\n" "$url"

if ! "${download_cmd[@]}" | tar -xzf - ||
[[ "${PIPESTATUS[0]}" -ne '0' ]]; then
printf "Failed to download from '%s'.\n" "$url" >&2
return 1
return "$_GO_EC_NOTFND"
elif [[ ! -d "$core_dir_parent" ]] && ! mkdir -p "$core_dir_parent" ; then
printf "Failed to create scripts dir '%s'\n" "$core_dir_parent" >&2
rm -rf "$unpacked_dir"
return 1
return "$_GO_EC_CANTCREAT"
elif ! mv "$unpacked_dir" "$GO_SCRIPT_BASH_CORE_DIR"; then
printf "Failed to install downloaded directory in '%s'\n" \
"$GO_SCRIPT_BASH_CORE_DIR" >&2
rm -rf "$unpacked_dir"
return 1
return "$_GO_EC_CANTCREAT"
fi
printf "Download of '%s' successful.\n\n" "$url"
}
Expand All @@ -106,7 +106,7 @@ git_clone_go_script_bash() {
-b "$GO_SCRIPT_BASH_VERSION" "$GO_SCRIPT_BASH_REPO_URL" \
"$GO_SCRIPT_BASH_CORE_DIR"; then
printf "Failed to clone '%s'; aborting.\n" "$GO_SCRIPT_BASH_REPO_URL" >&2
return 1
return "$_GO_EC_GENERR"
fi
printf "Clone of '%s' successful.\n\n" "$GO_SCRIPT_BASH_REPO_URL"
}
Expand All @@ -115,7 +115,7 @@ if [[ ! -e "$GO_SCRIPT_BASH_CORE_DIR/go-core.bash" ]]; then
if ! download_go_script_bash_tarball; then
printf "Using git clone as fallback\n"
if ! git_clone_go_script_bash; then
exit 1
exit "$_GO_EC_GENERR"
fi
fi
fi
Expand Down
2 changes: 1 addition & 1 deletion lib/bats-main
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ fi
if [[ "$word_index" -eq '0' ]]; then
echo '--coverage' '--edit' '--list'
if [[ "${1:0:1}" == '-' ]]; then
return
return "$_GO_EC_OK"
fi
fi
@go 'glob' '--complete' "$test_word_index" "${_GO_BATS_GLOB_ARGS[@]}" "$@"
Expand Down
4 changes: 2 additions & 2 deletions lib/bats/helpers
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,7 @@ test_break_after_num_iterations() {
for __tbani_caller_var in "${@:2}"; do
printf -- '%s: %s\n' "$__tbani_caller_var" "${!__tbani_caller_var}" >&2
done
exit 1
exit "$_GO_EC_GENERR"
fi
}
export -f test_break_after_num_iterations
Expand Down Expand Up @@ -551,7 +551,7 @@ __create_bats_test_script() {

if [[ -z "$script_path" ]]; then
echo "No test script name or path specified" >&2
exit 1
exit "$_GO_EC_USAGE"
elif [[ "$script_dir" == "$script_path" ]]; then
script_dir=''
fi
Expand Down
9 changes: 8 additions & 1 deletion lib/complete
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,12 @@

compgen_exit_index="$((${#compreply[@]} - 1))"

if [[ "${compreply[$compgen_exit_index]}" -ne '0' ]]; then
if [[ "${compreply[$compgen_exit_index]}" -eq '1' ]]; then
return "$_GO_EC_NOTFND"
elif [[ "${compreply[$compgen_exit_index]}" -eq '2' ]]; then
return "$_GO_EC_USAGE"
elif [[ "${compreply[$compgen_exit_index]}" -ne '0' ]]; then
# probably never occurs
return "${compreply[$compgen_exit_index]}"
fi
unset "compreply[$compgen_exit_index]"
Expand Down Expand Up @@ -77,4 +82,6 @@
fi
done
done

return "$_GO_EC_OK"
}
4 changes: 2 additions & 2 deletions lib/diff
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,9 @@ export _GO_DIFF_EDITOR="${_GO_DIFF_EDITOR:-vimdiff}"
"$_GO_DIFF_EDITOR" "$lhs" "$rhs"
fi
else
return '0'
return "$_GO_EC_OK"
fi
return '1'
return "$_GO_EC_SIGN1"
}

# Log differences between two directory structures
Expand Down
33 changes: 24 additions & 9 deletions lib/existence
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,15 @@
# Arguments:
# label: Label describing the type of file
# file_path: Path to the file to check
#
# Returns:
# _GO_EC_OK if file exists, _GO_EC_NOTFND otherwise
@go.check_file_exists() {
if [[ ! -e "$2" ]]; then
@go.printf "%s doesn't exist: %s\n" "$1" "$2" >&2
return 1
return "$_GO_EC_NOTFND"
else
return "$_GO_EC_OK"
fi
}

Expand All @@ -37,11 +42,15 @@
# Arguments:
# label: Label describing the type of file
# file_path: Path to the file to check
#
# Returns:
# _GO_EC_OK if file exists and is readable, _GO_EC_GENERR otherwise
@go.check_file_readable() {
if [[ ! -r "$2" ]]; then
@go.printf "%s doesn't exist or isn't readable: %s\n" "$1" "$2" >&2
return 1
return "$_GO_EC_GENERR"
fi
return "$_GO_EC_OK"
}

# Selects the first installed command from a list of possible commands/names.
Expand All @@ -54,18 +63,22 @@
# ...: List of commands from which to select the first available
#
# Returns:
# Zero if any of the commands are installed, nonzero otherwise
# _GO_EC_OK if any of the commands are installed, _GO_EC_NOTFND otherwise
@go.pick_command() {
local __go_pick_cmd
for __go_pick_cmd in "${@:2}"; do
if command -v "$__go_pick_cmd" >/dev/null; then
printf -v "$1" -- '%s' "$__go_pick_cmd"
return
printf -v "$1" -- '%s' "$__go_pick_cmd" && ec=0 || ec="$?"
if [[ "$ec" -ne 0 ]]; then
return $((_GO_EC_GENERR+ec))
else
return "$_GO_EC_OK"
fi
fi
done
@go.printf 'None of the following commands were found on the system:\n' >&2
printf ' %s\n' "${@:2}" >&2
return 1
return "$_GO_EC_NOTFND"
}

# Checks whether a required command is installed on the system.
Expand All @@ -78,11 +91,13 @@
# err_msg: Name of the command or other info to use in the error message
#
# Returns:
# Zero if the command is installed, nonzero otherwise
# _GO_EC_OK if the command is installed, _GO_EC_DEPMISS otherwise
@go.check_command_installed() {
if ! command -v "$1" >/dev/null; then
if command -v "$1" >/dev/null; then
return "$_GO_EC_OK"
else
@go.printf 'Please install %s on your system and try again.\n' \
"${2:-$1}" >&2
return 1
return "$_GO_EC_DEPMISS"
fi
}
Loading