Last active
June 25, 2025 00:04
-
-
Save thiago-rezende/af0c6d139a33cdb7add1e677046352d4 to your computer and use it in GitHub Desktop.
generic command-line utility script
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #! /usr/bin/env bash | |
| # | |
| # βββ ββββββββββββββββββ βββββββββββββββ βββ | |
| # βββ ββββββββββββββββββ ββββββββββββββββ ββββ | |
| # βββ βββ βββ ββββββ βββ βββ βββββββ | |
| # βββ βββ βββ ββββββ βββ βββ βββββ | |
| # βββββββββ βββ ββββββββββββββ βββ βββ | |
| # βββββββ βββ ββββββββββββββ βββ βββ | |
| # | |
| # Filename: utility.sh | |
| # GitHub: https://github.com/thiago-rezende | |
| # Maintainer: Thiago Rezende <thiago.manoel.rezende@gmail.com> | |
| # script variables | |
| script_name=`basename "$0"` | |
| script_version='v0.0.0' | |
| script_description='general purpose utility script' | |
| # script directories | |
| script_directory=`dirname "$0"` | |
| script_logs_directory=${SCRIPT_LOGS_DIRECTORY:-"${script_directory}/logs"} | |
| # script verbosity variables | |
| script_verbose_output=${SCRIPT_VERBOSE_OUTPUT:-1} | |
| # positional arguments | |
| positional_arguments=() | |
| # ansi colors | |
| declare -r \ | |
| ansi_red='\033[31m' \ | |
| ansi_blue='\033[34m' \ | |
| ansi_cyan='\033[36m' \ | |
| ansi_gray='\033[30m' \ | |
| ansi_white='\033[37m' \ | |
| ansi_green='\033[32m' \ | |
| ansi_yellow='\033[33m' \ | |
| ansi_magenta='\033[35m' \ | |
| ansi_red_bold='\033[0;31;1m' \ | |
| ansi_blue_bold='\033[0;34;1m' \ | |
| ansi_cyan_bold='\033[0;36;1m' \ | |
| ansi_black_bold='\033[0;30;1m' \ | |
| ansi_green_bold='\033[0;32;1m' \ | |
| ansi_white_bold='\033[0;37;1m' \ | |
| ansi_yellow_bold='\033[0;33;1m' \ | |
| ansi_magenta_bold='\033[0;35;1m' \ | |
| ansi_reset='\033[0m' | |
| # script usage message | |
| script__usage() { | |
| echo -e "[$ansi_green_bold $script_name $ansi_reset]$ansi_white <$ansi_yellow_bold ${script_version}$ansi_reset$ansi_white > $ansi_reset" | |
| echo -e " $ansi_blue_bold $script_description $ansi_reset" | |
| echo -e "" | |
| echo -e "[$ansi_white_bold usage $ansi_reset]" | |
| echo -e " $ansi_green $script_name $ansi_white utility $ansi_yellow command $ansi_magenta < argument > $ansi_cyan [ options ] $ansi_reset" | |
| echo -e "" | |
| echo -e "[$ansi_white_bold utilities $ansi_reset]" | |
| echo -e " $ansi_white help $ansi_reset - show this help message" | |
| echo -e " $ansi_white changelog $ansi_reset - execute the$ansi_white changelog$ansi_reset utility" | |
| echo -e "" | |
| echo -e "[$ansi_white_bold changelog $ansi_reset]" | |
| echo -e " $ansi_yellow fail $ansi_reset - simulate the '$ansi_blue failure$ansi_reset ' procedure" | |
| echo -e " $ansi_yellow plain $ansi_reset - generate a plain changelog" | |
| echo -e " $ansi_yellow markdown $ansi_reset - generate a plain changelog" | |
| echo -e "" | |
| echo -e "[$ansi_white_bold options $ansi_reset]" | |
| echo -e " $ansi_cyan --quiet $ansi_reset - reduce verbosity" | |
| echo -e "" | |
| exit 0 | |
| } | |
| # generic validation error | |
| invalid() { | |
| local kind=$1 | |
| local object=$2 | |
| local ansi_color=${3:-"${ansi_yellow}"} | |
| if [ -z "$object" ]; then | |
| script__usage | |
| else | |
| echo >&2 -e "[$ansi_red error $ansi_reset] invalid $kind '$ansi_color $object $ansi_reset'" | |
| echo >&2 -e "|- run '$ansi_green ${script_name}$ansi_white help $ansi_reset' to check the script usage" | |
| fi | |
| exit 1 | |
| } | |
| # generic missing error | |
| missing() { | |
| local kind=$1 | |
| local ansi_color=${3:-"${ansi_yellow}"} | |
| echo >&2 -e "[$ansi_red error $ansi_reset] missing '$ansi_color $kind $ansi_reset'" | |
| echo >&2 -e "|- run '$ansi_green ${script_name}$ansi_white help $ansi_reset' to check the script usage" | |
| exit 1 | |
| } | |
| # generic failure procedure | |
| failure() { | |
| local utility=$1 | |
| local command=$2 | |
| local output=$3 | |
| echo >&2 -e "[$ansi_red error $ansi_reset] utility '$ansi_white $utility $ansi_reset' failed on '$ansi_yellow $command $ansi_reset'" | |
| echo >&2 -e "|- [$ansi_white log $ansi_reset] check '$ansi_yellow $output $ansi_reset' for more information" | |
| exit 1 | |
| } | |
| # setup verbosity | |
| setup__verbosity() { | |
| if [ "${script_verbose_output}" -ne 0 ]; then | |
| exec 3>&1 | |
| else | |
| exec 3>/dev/null | |
| fi | |
| } | |
| # setup logging | |
| setup__logging() { | |
| if [ -d $script_logs_directory ]; then | |
| return | |
| fi | |
| echo >&3 -e "[$ansi_white logging $ansi_reset] settnig up the '$ansi_cyan logging $ansi_reset' environment" | |
| echo >&3 -e "|- [$ansi_white mkdir $ansi_reset] creating the '$ansi_yellow ${script_logs_directory}$ansi_reset ' directory" | |
| mkdir >&/tmp/${script_name%.*}__setup__logging__mkdir.log -p $script_logs_directory | |
| if [ $? -ne 0 ]; then | |
| failure "setup" "logging" "/tmp/${script_name%.*}__setup__logging__mkdir.log" | |
| fi | |
| } | |
| # changelog handler | |
| changelog__handler() { | |
| setup__logging | |
| local command=$1 | |
| case $command in | |
| fail) changelog__fail "${@:2}";; | |
| plain) changelog__plain "${@:2}";; | |
| markdown) changelog__markdown "${@:2}";; | |
| *) if [ -z $command ]; then missing "command" $ansi_yellow; else invalid "command" $command $ansi_yellow; fi;; | |
| esac | |
| } | |
| # changelog fail | |
| changelog__fail() { | |
| echo >&3 -e "[$ansi_white changelog $ansi_reset] simulating the '$ansi_blue failure $ansi_reset' procedure" | |
| echo >&3 -e "|- calling the '$ansi_blue failure $ansi_reset' procedure" | |
| echo >&${script_logs_directory}/changelog__fail.log "changelog failure simulation" | |
| failure "changelog" "fail" "${script_logs_directory}/changelog__fail.log" | |
| } | |
| changelog__plain() { | |
| echo >&3 -e "[$ansi_white changelog $ansi_reset] generating a '$ansi_yellow plain $ansi_reset' changelog" | |
| echo >&${script_logs_directory}/changelog__plain.log "simulating the generation of a plain changelog" | |
| } | |
| changelog__markdown() { | |
| echo >&3 -e "[$ansi_white changelog $ansi_reset] generating a '$ansi_yellow markdown $ansi_reset' changelog" | |
| echo >&${script_logs_directory}/changelog__markdown.log "simulating the generation of a markdown changelog" | |
| } | |
| # options handler | |
| while [ $# -gt 0 ]; do | |
| case $1 in | |
| # quiet option | |
| --quiet) script_verbose_output=0; shift;; | |
| # usage option | |
| -h|--help) script__usage;; | |
| # invalid option | |
| -*|--*) invalid "option" $1 $ansi_cyan;; | |
| # positional argument | |
| *) positional_arguments+=("$1"); shift;; | |
| esac | |
| done | |
| set -- "${positional_arguments[@]}" | |
| # setup script verbosity | |
| setup__verbosity | |
| # argument handler | |
| case $1 in | |
| help) script__usage;; | |
| changelog) changelog__handler "${@:2}";; | |
| *) invalid "utility" ${1:-""} $ansi_white;; | |
| esac |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment