#!/usr/bin/env bash
# STAROPENSOURCE BASHUTILS SOURCE FILE
# Copyright (c) 2024 The StarOpenSource bashutils Authors
# Licensed under the GNU Affero General Public License v3
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see .
#
#
# The copyright only protects the code from this line on until
# the "BASHUTILS CODE ENDS HERE" line. This notice is provided
# in case the bashutils script is embedded into a script file.
# The copyright notice above this notice does not apply the code
# above this notice or below the "BASHUTILS CODE ENDS HERE" line
# unless it licensed under the same license without modifications.
# Logging
## => Handles log calls and prints the specified message correctly.
## => Arguments:
## => Returns: 0
function _bashutils_log() {
# Cancel if disallowed
[ ! "${BASHUTILS_LOGLEVEL}" -lt "${1}" ] && return
# Set variables
# -> Level
#LEVEL_ID=${1}
LEVEL_NAME=${2}
# -> Message
shift 2
MESSAGE=${*}
# -> Indentation
unset INDENTATION
for ((i=1; i <= BASHUTILS_SUBSHELL; i++))
do
INDENTATION="${INDENTATION}${BASHUTILS_LOGINDENTATION}"
done
# Add shadow
MESSAGE=${MESSAGE//\\n/\\n }
# Print
echo -e "${LEVEL_NAME} ${INDENTATION} ${MESSAGE}";
}
## => Prints a diagnostic message.
## => Arguments:
## => Returns: 0
function diag() { _bashutils_log "1" "DIAG" "${*}"; }
## => Prints a verbose message.
## => Arguments:
## => Returns: 0
function verb() { _bashutils_log "2" "VERB" "${*}"; }
## => Prints a silent warning message.
## => Arguments:
## => Returns: 0
function sarn() { _bashutils_log "3" "SARN" "${*}"; }
## => Prints an informational message.
## => Arguments:
## => Returns: 0
function info() { _bashutils_log "4" "INFO" "${*}"; }
## => Prints a warning message.
## => Arguments:
## => Returns: 0
function warn() { _bashutils_log "5" "WARN" "${*}"; }
## => Prints an error message.
## => Arguments:
## => Returns: 0
function error() { _bashutils_log "6" "ERR!" "${*}" &> /dev/stderr; }
## => Handles crashes.
## => Arguments:
## => Returns: 0
function crash() {
[ "${1}" == "true" ] && CRASH_TERMINATE=true || CRASH_TERMINATE=false
shift
# shellcheck disable=SC2002
cat << EOF &> /dev/stderr
$([ "${CRASH_TERMINATE}" == "false" ] && echo "!!! This crash will not terminate the shell !!!")
-------------------------
sos!bashutils crash
-------------------------
Issuer
-> Line: $(caller)
-> Message: ${*}
Operating system
$(
if [ -f "/etc/os-release" ]; then
# /etc/os-release file is likely
# already sorted so don't sort here
cat "/etc/os-release" | while read -r line; do
echo " -> ${line}"
done
else
echo "/etc/os-release does not exist"
fi
)
Environment
$(
env | sort - | while read -r line; do
echo " -> ${line}"
done
)
Stacktrace
$(for index in $(seq 0 1000); do if [ -z "$(caller "${index}")" ]; then break; else echo " -> $(caller "${index}")"; fi; done)
-------------------------
sos!bashutils crash
-------------------------
$([ "${CRASH_TERMINATE}" == "false" ] && echo "!!! This crash will not terminate the shell !!!")
EOF
[ "${CRASH_TERMINATE}" == "true" ] && exit 69
}
# Checks
## Command type
## => Checks whether the provided command name is an alias.
## => Arguments:
## => Returns: 0 if it is, 1 otherwise
function is_command_alias() { [[ "$(type -t "${1}")" == alias ]]; }
## => Checks whether the provided command name is a keyword.
## => Arguments:
## => Returns: 0 if it is, 1 otherwise
function is_command_keyword() { [[ "$(type -t "${1}")" == keyword ]]; }
## => Checks whether the provided command name is a function.
## => Arguments:
## => Returns: 0 if it is, 1 otherwise
function is_command_function() { [[ "$(type -t "${1}")" == function ]]; }
## => Checks whether the provided command name is a builtin.
## => Arguments:
## => Returns: 0 if it is, 1 otherwise
function is_command_builtin() { [[ "$(type -t "${1}")" == builtin ]]; }
## => Checks whether the provided command name is a file.
## => Arguments:
## => Returns: 0 if it is, 1 otherwise
function is_command_file() { [[ "$(type -t "${1}")" == file ]]; }
## => Checks whether the provided command name is defined.
## => Arguments:
## => Returns: 0 if it is, 1 otherwise
function is_command_defined() { [[ "$(type -t "${1}")" == "" ]]; }
## Input type
## => Checks whether the provided input is a bool.
## => Arguments:
## => Returns: 0 if it is, 1 otherwise
function is_input_bool() { [ "${1}" == "true" ] || [ "${1}" == "false" ]; }
## => Checks whether the provided input is a byte.
## => Arguments:
## => Returns: 0 if it is, 1 otherwise
function is_input_byte() { [[ "${1}" =~ ^[0-9]+$ ]] && [[ "${1}" -gt -1 ]] && [[ "${1}" -lt 256 ]]; }
## => Checks whether the provided input is a integer/number.
## => Arguments:
## => Returns: 0 if it is, 1 otherwise
function is_input_int() { [[ "${1}" =~ ^[0-9]+$ ]]; }
## => Checks whether the provided input is a char.
## => Arguments:
## => Returns: 0 if it is, 1 otherwise
function is_input_char() { [[ "${1}" =~ ^.$ ]]; }
# Variable definition
## => Sets the specified variable to the specified value if it is undefined.
## => Arguments:
## => Returns: 0 if it is, 1 otherwise
function set_undefined() { [ -z "${!1}" ] && export "${1}=${2}"; }
## => Sets the specified variable to the specified value if it is defined.
## => Arguments:
## => Returns: 0 if it is, 1 otherwise
function set_defined() { [ -n "${!1}" ] && export "${1}=${2}"; }
# Initialize variables
set_undefined "BASHUTILS_LOGLEVEL" "3"
set_undefined "BASHUTILS_LOGINDENTATION" ">"
set_undefined "BASHUTILS_SUBSHELL" "1"
################################
### BASHUTILS CODE ENDS HERE ###
################################