Skip to content

Instantly share code, notes, and snippets.

@thiago-rezende
Last active June 25, 2025 00:04
Show Gist options
  • Select an option

  • Save thiago-rezende/af0c6d139a33cdb7add1e677046352d4 to your computer and use it in GitHub Desktop.

Select an option

Save thiago-rezende/af0c6d139a33cdb7add1e677046352d4 to your computer and use it in GitHub Desktop.
generic command-line utility script
#! /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