Compare commits
4 commits
f1e74c18f2
...
6368928cc2
Author | SHA1 | Date | |
---|---|---|---|
6368928cc2 | |||
5be44a87bf | |||
b706526e99 | |||
7dcaaf5950 |
5 changed files with 265 additions and 29 deletions
96
bashutils.sh
96
bashutils.sh
|
@ -26,6 +26,9 @@
|
|||
|
||||
|
||||
# Environment control
|
||||
## => Restores the environment
|
||||
## => Arguments: none
|
||||
## => Returns: 0
|
||||
function _bashutils_restore_environment() {
|
||||
if [ -n "${_BASHUTILS_ENVIRONMENT_PREVIOUS_OPTIONS}" ]; then
|
||||
[[ "${_BASHUTILS_ENVIRONMENT_PREVIOUS_OPTIONS}" == *"e"* ]] && set -e
|
||||
|
@ -38,7 +41,14 @@ function _bashutils_restore_environment() {
|
|||
[ -z "${_BASHUTILS_ENVIRONMENT_PREVIOUS_PIPEFAIL}" ] && set +o pipefail
|
||||
unset _BASHUTILS_ENVIRONMENT_PREVIOUS_OPTIONS
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
## => Resets the environment to optimal conditions for bashutils
|
||||
## => Arguments:
|
||||
## -> 1. none
|
||||
## -> 2. [?...:command to execute]
|
||||
## => Returns: 0 or the command's exit code if one is supplied
|
||||
function _bashutils_reset_environment() {
|
||||
export "_BASHUTILS_ENVIRONMENT_PREVIOUS_OPTIONS=${-}"
|
||||
[ -o "pipefail" ] && export "_BASHUTILS_ENVIRONMENT_PREVIOUS_PIPEFAIL=true"
|
||||
|
@ -53,20 +63,48 @@ function _bashutils_reset_environment() {
|
|||
_bashutils_restore_environment
|
||||
return "${EXITCODE}"
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
function _bashutils_restore_return() {
|
||||
## => Resets the environment and returns the first argument.
|
||||
## This is useful in situations where the environment shall
|
||||
## be reset and the exit code preserved.
|
||||
## => Arguments: <byte:exit code>
|
||||
## => Returns: the provided exit code
|
||||
function _bashutils_return_environment() {
|
||||
_bashutils_restore_environment
|
||||
return "${1}"
|
||||
return "${1:-0}"
|
||||
}
|
||||
|
||||
|
||||
# Logging
|
||||
## => Prints a diagnostic message.
|
||||
## => Arguments: <str...:message>
|
||||
## => Returns: 0
|
||||
function diag() { [ "${BASHUTILS_LOGLEVEL}" -lt 1 ] && echo -e "DIAG ${*//\\n/\\n }"; }
|
||||
## => Prints a verbose message.
|
||||
## => Arguments: <str...:message>
|
||||
## => Returns: 0
|
||||
function verb() { [ "${BASHUTILS_LOGLEVEL}" -lt 2 ] && echo -e "VERB ${*//\\n/\\n }"; }
|
||||
## => Prints a silent warning message.
|
||||
## => Arguments: <str...:message>
|
||||
## => Returns: 0
|
||||
function sarn() { [ "${BASHUTILS_LOGLEVEL}" -lt 3 ] && echo -e "SARN ${*//\\n/\\n }"; }
|
||||
## => Prints an informational message.
|
||||
## => Arguments: <str...:message>
|
||||
## => Returns: 0
|
||||
function info() { [ "${BASHUTILS_LOGLEVEL}" -lt 4 ] && echo -e "INFO ${*//\\n/\\n }"; }
|
||||
## => Prints a warning message.
|
||||
## => Arguments: <str...:message>
|
||||
## => Returns: 0
|
||||
function warn() { [ "${BASHUTILS_LOGLEVEL}" -lt 5 ] && echo -e "WARN ${*//\\n/\\n }"; }
|
||||
## => Prints an error message.
|
||||
## => Arguments: <str...:message>
|
||||
## => Returns: 0
|
||||
function error() { [ "${BASHUTILS_LOGLEVEL}" -lt 6 ] && echo -e "ERR! ${*//\\n/\\n }" &> /dev/stderr; }
|
||||
## => Handles crashes.
|
||||
## => Arguments: <bool:terminate?> <str...:message>
|
||||
## => Returns: 0
|
||||
function crash() {
|
||||
_bashutils_reset_environment
|
||||
[ "${1}" == "true" ] && CRASH_TERMINATE=true || CRASH_TERMINATE=false
|
||||
|
@ -101,15 +139,57 @@ EOF
|
|||
}
|
||||
|
||||
# Checks
|
||||
function is_command_alias() { _bashutils_reset_environment; [[ "$(type -t "${1}")" == alias ]]; _bashutils_restore_return ${?}; }
|
||||
function is_command_keyword() { _bashutils_reset_environment; [[ "$(type -t "${1}")" == keyword ]]; _bashutils_restore_return ${?}; }
|
||||
function is_command_function() { _bashutils_reset_environment; [[ "$(type -t "${1}")" == function ]]; _bashutils_restore_return ${?}; }
|
||||
function is_command_builtin() { _bashutils_reset_environment; [[ "$(type -t "${1}")" == builtin ]]; _bashutils_restore_return ${?}; }
|
||||
function is_command_file() { _bashutils_reset_environment; [[ "$(type -t "${1}")" == file ]]; _bashutils_restore_return ${?}; }
|
||||
function is_command_defined() { _bashutils_reset_environment; [[ "$(type -t "${1}")" == "" ]]; _bashutils_restore_return ${?}; }
|
||||
## Command type
|
||||
## => Checks whether the provided command name is an alias.
|
||||
## => Arguments: <str:command name>
|
||||
## => Returns: 0 if it is, 1 otherwise
|
||||
function is_command_alias() { _bashutils_reset_environment; [[ "$(type -t "${1}")" == alias ]]; _bashutils_return_environment ${?}; }
|
||||
## => Checks whether the provided command name is a keyword.
|
||||
## => Arguments: <str:command name>
|
||||
## => Returns: 0 if it is, 1 otherwise
|
||||
function is_command_keyword() { _bashutils_reset_environment; [[ "$(type -t "${1}")" == keyword ]]; _bashutils_return_environment ${?}; }
|
||||
## => Checks whether the provided command name is a function.
|
||||
## => Arguments: <str:command name>
|
||||
## => Returns: 0 if it is, 1 otherwise
|
||||
function is_command_function() { _bashutils_reset_environment; [[ "$(type -t "${1}")" == function ]]; _bashutils_return_environment ${?}; }
|
||||
## => Checks whether the provided command name is a builtin.
|
||||
## => Arguments: <str:command name>
|
||||
## => Returns: 0 if it is, 1 otherwise
|
||||
function is_command_builtin() { _bashutils_reset_environment; [[ "$(type -t "${1}")" == builtin ]]; _bashutils_return_environment ${?}; }
|
||||
## => Checks whether the provided command name is a file.
|
||||
## => Arguments: <str:command name>
|
||||
## => Returns: 0 if it is, 1 otherwise
|
||||
function is_command_file() { _bashutils_reset_environment; [[ "$(type -t "${1}")" == file ]]; _bashutils_return_environment ${?}; }
|
||||
## => Checks whether the provided command name is defined.
|
||||
## => Arguments: <str:command name>
|
||||
## => Returns: 0 if it is, 1 otherwise
|
||||
function is_command_defined() { _bashutils_reset_environment; [[ "$(type -t "${1}")" == "" ]]; _bashutils_return_environment ${?}; }
|
||||
## Input type
|
||||
## => Checks whether the provided input is a bool.
|
||||
## => Arguments: <str:input>
|
||||
## => Returns: 0 if it is, 1 otherwise
|
||||
function is_input_bool() { _bashutils_reset_environment; [ "${1}" == "true" ] || [ "${1}" == "false" ]; _bashutils_return_environment "${?}"; }
|
||||
## => Checks whether the provided input is a byte.
|
||||
## => Arguments: <str:input>
|
||||
## => Returns: 0 if it is, 1 otherwise
|
||||
function is_input_byte() { _bashutils_reset_environment; [[ "${1}" =~ ^[0-9]+$ ]] && [[ "${1}" -gt -1 ]] && [["${1}" -lt 256 ]]; _bashutils_return_environment "${?}"; }
|
||||
## => Checks whether the provided input is a integer/number.
|
||||
## => Arguments: <str:input>
|
||||
## => Returns: 0 if it is, 1 otherwise
|
||||
function is_input_int() { _bashutils_reset_environment; [[ "${1}" =~ ^[0-9]+$ ]]; _bashutils_return_environment "${?}"; }
|
||||
## => Checks whether the provided input is a char.
|
||||
## => Arguments: <str:input>
|
||||
## => Returns: 0 if it is, 1 otherwise
|
||||
function is_input_char() { _bashutils_reset_environment; [[ "${1}" =~ ^.$ ]]; _bashutils_return_environment "${?}"; }
|
||||
|
||||
# Variable definition
|
||||
## => Sets the specified variable to the specified value if it is undefined.
|
||||
## => Arguments: <str:variable> <?:value>
|
||||
## => Returns: 0 if it is, 1 otherwise
|
||||
function set_undefined() { _bashutils_reset_environment; [ -z "${!1}" ] && export "${1}=${2}"; _bashutils_restore_environment; }
|
||||
## => Sets the specified variable to the specified value if it is defined.
|
||||
## => Arguments: <str:variable> <?:value>
|
||||
## => Returns: 0 if it is, 1 otherwise
|
||||
function set_defined() { _bashutils_reset_environment; [ -n "${!1}" ] && export "${1}=${2}"; _bashutils_restore_environment; }
|
||||
|
||||
|
||||
|
|
|
@ -24,8 +24,8 @@ is_command_builtin "echo" && echo "'echo'" is built into bash"
|
|||
! is_command_defined "setup" && echo "ERROR: 'setup' is undefined"
|
||||
```
|
||||
|
||||
## Command type checks
|
||||
These check the type of the passed command and return `0` if it matches or `1` if it doesn't.
|
||||
## Command type
|
||||
These checks check the type of the passed command and return `0` if it matches or `1` if it doesn't.
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
|
@ -57,3 +57,33 @@ These check the type of the passed command and return `0` if it matches or `1` i
|
|||
<td><code>is_command_defined <str:command name></code></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
## Input type
|
||||
These checks check the type of the specified input and return `0` if the type matches or `1` if it isn't.
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td>Checks for</td>
|
||||
<td>Usage</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>bool</code></td>
|
||||
<td><code>is_input_bool <?:input></code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>byte</code></td>
|
||||
<td><code>is_input_byte <?:input></code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>int</code></td>
|
||||
<td><code>is_input_int <?:input></code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>char</code></td>
|
||||
<td><code>is_input_char <?:input></code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>str</code></td>
|
||||
<td>Are you serious?</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
|
|
@ -22,32 +22,32 @@ required arguments along.
|
|||
<tr>
|
||||
<td>Diagnostic</td>
|
||||
<td>0</td>
|
||||
<td><code>diag <str:message></code></td>
|
||||
<td><code>diag <str...:message></code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Verbose</td>
|
||||
<td>1</td>
|
||||
<td><code>verb <str:message></code></td>
|
||||
<td><code>verb <str..:message></code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Silent warning</td>
|
||||
<td>2</td>
|
||||
<td><code>sarn <str:message></code></td>
|
||||
<td><code>sarn <str...:message></code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Informational</td>
|
||||
<td>3</td>
|
||||
<td><code>info <str:message></code></td>
|
||||
<td><code>info <str...:message></code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Warning</td>
|
||||
<td>4</td>
|
||||
<td><code>warn <str:message></code></td>
|
||||
<td><code>warn <str...:message></code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Error</td>
|
||||
<td>5</td>
|
||||
<td><code>error <str:message></code></td>
|
||||
<td><code>error <str...:message></code></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
|
@ -56,7 +56,7 @@ bashutils includes a fully functional crash handler.
|
|||
It prints information about the operating system, environment, stack trace and of course the crash itself.
|
||||
And, if you wish, it will terminate the script with code `69`.
|
||||
|
||||
To trigger a crash, simply invoke `crash <bool:terminate> <str:message>`.
|
||||
To trigger a crash, simply invoke `crash <bool:terminate> <str...:message>`.
|
||||
|
||||
## Customization
|
||||
bashutils allows you to customize the logging system via environment variables.
|
||||
|
|
|
@ -7,6 +7,9 @@ description: Describes which data types bashutils uses and understands.
|
|||
# Data types
|
||||
This document describes which data types bashutils can understand.
|
||||
|
||||
## `?`
|
||||
Denotes a lack of data types. This means any data type is accepted.
|
||||
|
||||
## `bool`
|
||||
Booleans. May only be `true` or `false`. `1` or `0` is not supported and will be treated as a number instead.
|
||||
|
||||
|
|
147
test.sh
147
test.sh
|
@ -1,8 +1,9 @@
|
|||
#!/usr/bin/env bash
|
||||
export "LC_ALL=C.UTF-8"
|
||||
set -uo pipefail
|
||||
IFS=$'\n'
|
||||
|
||||
unset TEST TESTS
|
||||
unset TESTS TEST STAGE
|
||||
|
||||
TESTS="
|
||||
# Logging
|
||||
|
@ -15,34 +16,38 @@ logger_error
|
|||
logger_crash
|
||||
|
||||
# Checks
|
||||
## Command type
|
||||
check_command_alias
|
||||
check_command_keyword
|
||||
check_command_function
|
||||
check_command_builtin
|
||||
check_command_file
|
||||
check_command_defined
|
||||
## Input type
|
||||
check_input_bool
|
||||
check_input_byte
|
||||
check_input_int
|
||||
check_input_char
|
||||
"
|
||||
|
||||
# Utility methods
|
||||
function invalid() { echo ":: Error: Invalid test ${TEST}, skipping"; }
|
||||
function fail() {
|
||||
echo -e ":: Test ${TEST} failed\n ${*//\\n/\\n }"
|
||||
[ "${TEST_FAILFAST}" == "true" ] && exit 1
|
||||
echo -e ":: Test ${TEST} failed during stage ${STAGE}\n ${*//\\n/\\n }"
|
||||
[ "${TEST_FAILFAST:-true}" == "true" ] && exit 1
|
||||
}
|
||||
## Assertions
|
||||
function assert_equals() {
|
||||
EXPECTED="${1}"
|
||||
shift
|
||||
ACTUAL="${*}"
|
||||
ACTUAL="${2}"
|
||||
|
||||
[[ "${ACTUAL}" != "${EXPECTED}" ]] && fail "${1}" "String does not match expected string\nExpected: ${EXPECTED}\nActual: ${ACTUAL}"
|
||||
[[ "${ACTUAL}" != "${EXPECTED}" ]] && fail "String does not match expected string\nExpected: '${EXPECTED}'\nActual: '${ACTUAL}'"
|
||||
}
|
||||
function assert_contains() {
|
||||
EXPECTED="${1}"
|
||||
shift
|
||||
ACTUAL="${*}"
|
||||
EXPECTED="${1}"
|
||||
ACTUAL="${2}"
|
||||
|
||||
[[ "${ACTUAL}" != *"${EXPECTED}"* ]] && fail "${1}" "String does not contain expected string\nExpected: ${EXPECTED}\nActual: ${ACTUAL}"
|
||||
[[ "${ACTUAL}" != *"${EXPECTED}"* ]] && fail "String does not contain expected string\nExpected: '${EXPECTED}'\nActual: '${ACTUAL}'"
|
||||
}
|
||||
|
||||
# Test loop
|
||||
|
@ -50,7 +55,8 @@ for TEST in ${TESTS}; do
|
|||
[ -z "${TEST}" ] || [[ "${TEST}" == "#"* ]] && continue
|
||||
|
||||
echo ":: Running test ${TEST}"
|
||||
export TEST
|
||||
export "TEST"
|
||||
export "STAGE=0"
|
||||
|
||||
# Logging
|
||||
if [[ "${TEST}" == "logger_"* ]]; then
|
||||
|
@ -73,7 +79,7 @@ for TEST in ${TESTS}; do
|
|||
elif [[ "${TEST}" == "check_"* ]]; then
|
||||
# Command checks
|
||||
if [[ "${TEST}" == "check_command_"* ]]; then
|
||||
case "${TEST//check_command/}" in
|
||||
case "${TEST//check_command_/}" in
|
||||
"alias")
|
||||
assert_equals "0" "$(
|
||||
source "bashutils.sh"
|
||||
|
@ -117,6 +123,123 @@ for TEST in ${TESTS}; do
|
|||
echo "${?}"
|
||||
)"
|
||||
;;
|
||||
*)
|
||||
invalid
|
||||
;;
|
||||
esac
|
||||
|
||||
# Input checks
|
||||
elif [[ "${TEST}" == "check_input_"* ]]; then
|
||||
case "${TEST//check_input_/}" in
|
||||
"bool")
|
||||
assert_equals "0" "$(
|
||||
source "bashutils.sh"
|
||||
is_input_bool "true"
|
||||
echo "${?}"
|
||||
)"
|
||||
export "STAGE=1"
|
||||
assert_equals "0" "$(
|
||||
source "bashutils.sh"
|
||||
is_input_bool "false"
|
||||
echo "${?}"
|
||||
)"
|
||||
export "STAGE=2"
|
||||
assert_equals "1" "$(
|
||||
source "bashutils.sh"
|
||||
is_input_bool "0"
|
||||
echo "${?}"
|
||||
)"
|
||||
export "STAGE=3"
|
||||
assert_equals "1" "$(
|
||||
source "bashutils.sh"
|
||||
is_input_bool "1"
|
||||
echo "${?}"
|
||||
)"
|
||||
;;
|
||||
"byte")
|
||||
assert_equals "0" "$(
|
||||
source "bashutils.sh"
|
||||
is_input_byte "0"
|
||||
echo "${?}"
|
||||
)"
|
||||
export "STAGE=1"
|
||||
assert_equals "0" "$(
|
||||
source "bashutils.sh"
|
||||
is_input_byte "255"
|
||||
echo "${?}"
|
||||
)"
|
||||
export "STAGE=2"
|
||||
assert_equals "0" "$(
|
||||
source "bashutils.sh"
|
||||
is_input_byte "69"
|
||||
echo "${?}"
|
||||
)"
|
||||
export "STAGE=3"
|
||||
assert_equals "1" "$(
|
||||
source "bashutils.sh"
|
||||
is_input_byte "256"
|
||||
echo "${?}"
|
||||
)"
|
||||
export "STAGE=4"
|
||||
assert_equals "1" "$(
|
||||
source "bashutils.sh"
|
||||
is_input_byte "-1"
|
||||
echo "${?}"
|
||||
)"
|
||||
export "STAGE=5"
|
||||
assert_equals "1" "$(
|
||||
source "bashutils.sh"
|
||||
is_input_int "asd"
|
||||
echo "${?}"
|
||||
)"
|
||||
;;
|
||||
"int")
|
||||
assert_equals "0" "$(
|
||||
source "bashutils.sh"
|
||||
is_input_int "9223372036854775807"
|
||||
echo "${?}"
|
||||
)"
|
||||
export "STAGE=1"
|
||||
assert_equals "1" "$(
|
||||
source "bashutils.sh"
|
||||
is_input_int "asd"
|
||||
echo "${?}"
|
||||
)"
|
||||
;;
|
||||
"char")
|
||||
assert_equals "0" "$(
|
||||
source "bashutils.sh"
|
||||
is_input_int "!"
|
||||
echo "${?}"
|
||||
)"
|
||||
export "STAGE=1"
|
||||
assert_equals "0" "$(
|
||||
source "bashutils.sh"
|
||||
is_input_int "™"
|
||||
echo "${?}"
|
||||
)"
|
||||
export "STAGE=2"
|
||||
assert_equals "0" "$(
|
||||
source "bashutils.sh"
|
||||
is_input_int "5"
|
||||
echo "${?}"
|
||||
)"
|
||||
export "STAGE=3"
|
||||
assert_equals "1" "$(
|
||||
source "bashutils.sh"
|
||||
is_input_int "asd"
|
||||
echo "${?}"
|
||||
)"
|
||||
export "STAGE=4"
|
||||
assert_equals "1" "$(
|
||||
source "bashutils.sh"
|
||||
is_input_int "666"
|
||||
echo "${?}"
|
||||
)"
|
||||
;;
|
||||
*)
|
||||
invalid
|
||||
;;
|
||||
esac
|
||||
|
||||
# Invalid command
|
||||
|
|
Loading…
Reference in a new issue