374 lines
12 KiB
Bash
Executable file
374 lines
12 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
|
|
# @file .config/log
|
|
# @brief Logger / prompt library that logs pretty console messages and provides several prompt methods
|
|
# @description
|
|
# This file contains several functions that log content in different formats. It also provides an
|
|
# interface for [Gum](https://github.com/charmbracelet/gum) based prompts. The available methods include:
|
|
#
|
|
# * `choose` - Prompt user with choices
|
|
# * `confirm` - Fancy Yes/No confirmation prompt
|
|
# * `error` - Logs an error message
|
|
# * `filter` - Filterable list of choices (with choices passed in as a line-return seperated file)
|
|
# * `info` - Logs a regular message
|
|
# * `input` - Prompt for a text input
|
|
# * `md` - Render a markdown file with [Glow](https://github.com/charmbracelet/glow)
|
|
# * `password` - Prompt for text that is masked by the prompt
|
|
# * `prompt` - Log a description for a prompt that follows
|
|
# * `spin` - Show a spinner while background job completes
|
|
# * `star` - Logs a message with a star icon at the beginning
|
|
# * `start` - Log a job start message
|
|
# * `success` - Logs a success message
|
|
# * `warn` - Logs a warning message
|
|
# * `write` - Multi-line input prompt
|
|
#
|
|
# If the `docker` environment variable is not set, the script / library will ensure both Gum and Glow are installed.
|
|
|
|
# @description Installs glow (a markdown renderer) from GitHub releases
|
|
installGlow() {
|
|
# TODO: Add support for other architecture types
|
|
if [ -d '/Applications' ] && [ -d '/Library' ] && [ -d '/Users' ]; then
|
|
GLOW_DOWNLOAD_URL="https://github.com/charmbracelet/glow/releases/download/v1.4.1/glow_1.4.1_Darwin_x86_64.tar.gz"
|
|
elif [ -f '/etc/ubuntu-release' ] || [ -f '/etc/debian_version' ] || [ -f '/etc/redhat-release' ] || [ -f '/etc/SuSE-release' ] || [ -f '/etc/arch-release' ] || [ -f '/etc/alpine-release' ]; then
|
|
GLOW_DOWNLOAD_URL="https://github.com/charmbracelet/glow/releases/download/v1.4.1/glow_1.4.1_linux_x86_64.tar.gz"
|
|
fi
|
|
if type curl &> /dev/null; then
|
|
if { [ -d '/Applications' ] && [ -d '/Library' ] && [ -d '/Users' ]; } || [ -f '/etc/ubuntu-release' ] || [ -f '/etc/debian_version' ] || [ -f '/etc/redhat-release' ] || [ -f '/etc/SuSE-release' ] || [ -f '/etc/arch-release' ] || [ -f '/etc/alpine-release' ]; then
|
|
TMP="$(mktemp)"
|
|
TMP_DIR="$(dirname "$TMP")"
|
|
curl -sSL "$GLOW_DOWNLOAD_URL" > "$TMP"
|
|
tar -xzf "$TMP" -C "$TMP_DIR"
|
|
if [ -n "$HOME" ]; then
|
|
if mkdir -p "$HOME/.local/bin" && mv "$TMP_DIR/glow" "$HOME/.local/bin/glow"; then
|
|
GLOW_PATH="$HOME/.local/bin/glow"
|
|
else
|
|
GLOW_PATH="$(dirname "${BASH_SOURCE[0]}")/glow"
|
|
mv "$TMP_DIR/gum" "$GLOW_PATH"
|
|
fi
|
|
chmod +x "$GLOW_PATH"
|
|
else
|
|
echo "WARNING: The HOME environment variable is not set! (Glow)"
|
|
fi
|
|
else
|
|
echo "WARNING: Unable to detect system type. (Glow)"
|
|
fi
|
|
fi
|
|
}
|
|
|
|
# @description Installs gum (a logging CLI) from GitHub releases
|
|
installGum() {
|
|
# TODO: Add support for other architecture types
|
|
if [ -d '/Applications' ] && [ -d '/Library' ] && [ -d '/Users' ]; then
|
|
GUM_DOWNLOAD_URL="https://github.com/charmbracelet/gum/releases/download/v0.4.0/gum_0.4.0_Darwin_x86_64.tar.gz"
|
|
elif [ -f '/etc/ubuntu-release' ] || [ -f '/etc/debian_version' ] || [ -f '/etc/redhat-release' ] || [ -f '/etc/SuSE-release' ] || [ -f '/etc/arch-release' ] || [ -f '/etc/alpine-release' ]; then
|
|
GUM_DOWNLOAD_URL="https://github.com/charmbracelet/gum/releases/download/v0.4.0/gum_0.4.0_linux_x86_64.tar.gz"
|
|
fi
|
|
if type curl &> /dev/null; then
|
|
if { [ -d '/Applications' ] && [ -d '/Library' ] && [ -d '/Users' ]; } || [ -f '/etc/ubuntu-release' ] || [ -f '/etc/debian_version' ] || [ -f '/etc/redhat-release' ] || [ -f '/etc/SuSE-release' ] || [ -f '/etc/arch-release' ] || [ -f '/etc/alpine-release' ]; then
|
|
TMP="$(mktemp)"
|
|
TMP_DIR="$(dirname "$TMP")"
|
|
curl -sSL "$GUM_DOWNLOAD_URL" > "$TMP"
|
|
tar -xzf "$TMP" -C "$TMP_DIR"
|
|
if [ -n "$HOME" ]; then
|
|
if mkdir -p "$HOME/.local/bin" && mv "$TMP_DIR/gum" "$HOME/.local/bin/gum"; then
|
|
GUM_PATH="$HOME/.local/bin/gum"
|
|
else
|
|
GUM_PATH="$(dirname "${BASH_SOURCE[0]}")/gum"
|
|
mv "$TMP_DIR/gum" "$GLOW_PATH"
|
|
fi
|
|
chmod +x "$GUM_PATH"
|
|
else
|
|
echo "WARNING: The HOME environment variable is not set! (Gum)"
|
|
fi
|
|
else
|
|
echo "WARNING: Unable to detect system type. (Gum)"
|
|
fi
|
|
fi
|
|
}
|
|
|
|
# @description Configure the logger to use echo or gum
|
|
if [ "${container:=}" != 'docker' ]; then
|
|
# Acquire gum's path or attempt to install it
|
|
if type gum &> /dev/null; then
|
|
GUM_PATH="$(which gum)"
|
|
elif [ -f "$HOME/.local/bin/gum" ]; then
|
|
GUM_PATH="$HOME/.local/bin/gum"
|
|
elif [ -f "$(dirname "${BASH_SOURCE[0]}")/gum" ]; then
|
|
GUM_PATH="$(dirname "${BASH_SOURCE[0]}")/gum"
|
|
elif type brew &> /dev/null; then
|
|
brew install gum
|
|
GUM_PATH="$(which gum)"
|
|
else
|
|
installGum
|
|
fi
|
|
|
|
# If gum's path was set, then turn on enhanced logging
|
|
if [ -n "$GUM_PATH" ]; then
|
|
chmod +x "$GUM_PATH"
|
|
ENHANCED_LOGGING=true
|
|
fi
|
|
fi
|
|
|
|
# @description Disable logging for Semantic Release because it tries to parse it as JSON
|
|
if [ -n "$SEMANTIC_RELEASE" ]; then
|
|
NO_LOGGING=true
|
|
fi
|
|
|
|
# @description Logs using Node.js
|
|
logger() {
|
|
if [ "$1" == 'error' ]; then
|
|
"$GUM_PATH" style --border="thick" "$("$GUM_PATH" style --foreground="#ff0000" "✖") $("$GUM_PATH" style --bold --background="#ff0000" --foreground="#ffffff" " ERROR ") $("$GUM_PATH" style --bold "$(format "$2")")"
|
|
elif [ "$1" == 'info' ]; then
|
|
"$GUM_PATH" style " $("$GUM_PATH" style --foreground="#00ffff" "○") $2"
|
|
elif [ "$1" == 'md' ]; then
|
|
# @description Ensure glow is installed
|
|
if [ "${container:=}" != 'docker' ]; then
|
|
if type glow &> /dev/null; then
|
|
GLOW_PATH="$(which glow)"
|
|
elif [ -f "$HOME/.local/bin/glow" ]; then
|
|
GLOW_PATH="$HOME/.local/bin/glow"
|
|
elif [ -f "$(dirname "${BASH_SOURCE[0]}")/glow" ]; then
|
|
GLOW_PATH="$(dirname "${BASH_SOURCE[0]}")/glow"
|
|
elif type brew &> /dev/null; then
|
|
brew install glow
|
|
GLOW_PATH="$(which glow)"
|
|
else
|
|
installGlow
|
|
fi
|
|
|
|
if [ -n "$GLOW_PATH" ]; then
|
|
chmod +x "$GLOW_PATH"
|
|
ENHANCED_LOGGING=true
|
|
fi
|
|
fi
|
|
"$GLOW_PATH" "$2"
|
|
elif [ "$1" == 'prompt' ]; then
|
|
"$GUM_PATH" style " $("$GUM_PATH" style --foreground="#00008b" "▶") $("$GUM_PATH" style --bold "$(format "$2")")"
|
|
elif [ "$1" == 'star' ]; then
|
|
"$GUM_PATH" style " $("$GUM_PATH" style --foreground="#d1d100" "◆") $("$GUM_PATH" style --bold --underline "$(format "$2")")"
|
|
elif [ "$1" == 'start' ]; then
|
|
"$GUM_PATH" style " $("$GUM_PATH" style --foreground="#00ff00" "▶") $("$GUM_PATH" style --bold "$(format "$2")")"
|
|
elif [ "$1" == 'success' ]; then
|
|
"$GUM_PATH" style "$("$GUM_PATH" style --foreground="#00ff00" "✔") $("$GUM_PATH" style --bold "$(format "$2")")"
|
|
elif [ "$1" == 'warn' ]; then
|
|
"$GUM_PATH" style " $("$GUM_PATH" style --foreground="#d1d100" "◆") $("$GUM_PATH" style --bold --background="#ffff00" --foreground="#000000" " WARNING ") $("$GUM_PATH" style --bold --italic "$(format "$2")")"
|
|
else
|
|
echo "WARNING: Unknown log type"
|
|
echo "$2"
|
|
fi
|
|
}
|
|
|
|
format() {
|
|
# shellcheck disable=SC2001,SC2016
|
|
ANSI_STR="$(echo "$1" | sed 's/^\([^`]*\)`\([^`]*\)`/\1\\u001b[47;1;30m \2 \\e[0;39m/')"
|
|
if [[ $ANSI_STR == *'`'*'`'* ]]; then
|
|
ANSI_STR="$(format "$ANSI_STR")"
|
|
fi
|
|
echo -e "$ANSI_STR"
|
|
}
|
|
|
|
# @description Display prompt that allows you to choose between options
|
|
choose() {
|
|
if type gum &> /dev/null; then
|
|
CHOOSE_ARGS="gum choose"
|
|
for CURRENT_VAR in "$@"; do
|
|
CHOOSE_ARGS="$CHOOSE_ARGS \"$CURRENT_VAR\""
|
|
done
|
|
eval $CHOOSE_ARGS
|
|
else
|
|
echo "ERROR: gum is not installed!"
|
|
fi
|
|
}
|
|
|
|
# @description Display a confirmation prompt that returns an exit code if "No" is selected
|
|
confirm() {
|
|
if type gum &> /dev/null; then
|
|
GUM_OPTS=""
|
|
if [ -n "$2" ]; then
|
|
# shellcheck disable=SC089
|
|
GUM_OPTS="$GUM_OPTS --affirmative=""'$2'"
|
|
fi
|
|
if [ -n "$3" ]; then
|
|
GUM_OPTS="$GUM_OPTS --negative=""'$3'"
|
|
fi
|
|
if [ -n "$1" ]; then
|
|
if [ -n "$GUM_OPTS" ]; then
|
|
gum confirm "$1" "$GUM_OPTS"
|
|
else
|
|
gum confirm "$1"
|
|
fi
|
|
else
|
|
gum confirm
|
|
fi
|
|
else
|
|
echo "ERROR: gum is not installed!"
|
|
fi
|
|
}
|
|
|
|
# @description Logs an error message
|
|
error() {
|
|
if [ -z "$NO_LOGGING" ]; then
|
|
if [ -n "$ENHANCED_LOGGING" ]; then
|
|
logger error "$1"
|
|
else
|
|
echo -e "\e[1;41m ERROR \e[0m $(format "$1")\e[0;39m"
|
|
fi
|
|
fi
|
|
}
|
|
|
|
# @description Display a filterable prompt that is populated with options from a text file
|
|
filter() {
|
|
if type gum &> /dev/null; then
|
|
TMP="$(mktemp)"
|
|
gum filter < "$1"
|
|
else
|
|
echo "ERROR: gum is not installed!"
|
|
fi
|
|
}
|
|
|
|
# @description Logs an info message
|
|
info() {
|
|
if [ -z "$NO_LOGGING" ]; then
|
|
if [ -n "$ENHANCED_LOGGING" ]; then
|
|
logger info "$1"
|
|
else
|
|
echo -e "\e[1;46m INFO \e[0m $(format "$1")\e[0;39m"
|
|
fi
|
|
fi
|
|
}
|
|
|
|
# @description Displays an input with masked characters
|
|
input() {
|
|
if type gum &> /dev/null; then
|
|
if [ -n "$1" ]; then
|
|
gum input --placeholder="$1"
|
|
else
|
|
gum input
|
|
fi
|
|
else
|
|
echo "ERROR: gum is not installed!"
|
|
fi
|
|
}
|
|
|
|
# @description Logs a message written in markdown
|
|
md() {
|
|
if [ ! -f "$1" ]; then
|
|
echo "ERROR: A markdown file must be passed in as the parameter" && exit 1
|
|
fi
|
|
if [ -n "$ENHANCED_LOGGING" ]; then
|
|
logger md "$1"
|
|
fi
|
|
}
|
|
|
|
# @description Displays an input with masked characters
|
|
password() {
|
|
if type gum &> /dev/null; then
|
|
if [ -n "$1" ]; then
|
|
gum input --password --placeholder="$1"
|
|
else
|
|
gum input --password
|
|
fi
|
|
else
|
|
echo "ERROR: gum is not installed!"
|
|
fi
|
|
}
|
|
|
|
# @description Logs a message that describes a prompt
|
|
prompt() {
|
|
if [ -z "$NO_LOGGING" ]; then
|
|
if [ -n "$ENHANCED_LOGGING" ]; then
|
|
logger prompt "$1"
|
|
else
|
|
echo -e "\e[1;104m PROMPT \e[0m $(format "$1")\e[0;39m"
|
|
fi
|
|
fi
|
|
}
|
|
|
|
# @description Display a spinner that stays until a command is completed
|
|
spin() {
|
|
if type gum &> /dev/null; then
|
|
if [ -n "$1" ] && [ -n "$2" ]; then
|
|
gum spin --title="$2" "$1"
|
|
elif [ -n "$1" ]; then
|
|
gum spin "$1"
|
|
else
|
|
gum input
|
|
fi
|
|
else
|
|
echo "ERROR: gum is not installed!"
|
|
fi
|
|
}
|
|
|
|
# @description Logs a message that starts with a star emoji
|
|
star() {
|
|
if [ -z "$NO_LOGGING" ]; then
|
|
if [ -n "$ENHANCED_LOGGING" ]; then
|
|
logger star "$1"
|
|
else
|
|
echo -e "\e[1;104m LINK \e[0m $(format "$1")\e[0;39m"
|
|
fi
|
|
fi
|
|
}
|
|
|
|
# @description Logs a message at the beginning of a task
|
|
start() {
|
|
if [ -z "$NO_LOGGING" ]; then
|
|
if [ -n "$ENHANCED_LOGGING" ]; then
|
|
logger start "$1"
|
|
else
|
|
echo -e "\e[1;46m START \e[0m $(format "$1")\e[0;39m"
|
|
fi
|
|
fi
|
|
}
|
|
|
|
# @description Logs a success message
|
|
success() {
|
|
if [ -z "$NO_LOGGING" ]; then
|
|
if [ -n "$ENHANCED_LOGGING" ]; then
|
|
logger success "$1"
|
|
else
|
|
echo -e "\e[1;42m SUCCESS \e[0m $(format "$1")\e[0;39m"
|
|
fi
|
|
fi
|
|
}
|
|
|
|
# @description Logs a warning message
|
|
warn() {
|
|
if [ -z "$NO_LOGGING" ]; then
|
|
if [ -n "$ENHANCED_LOGGING" ]; then
|
|
logger warn "$1"
|
|
else
|
|
echo -e "\e[1;43m WARNING \e[0m $(format "$1")\e[0;39m"
|
|
fi
|
|
fi
|
|
}
|
|
|
|
# @description Displays a multi-line prompt for text input
|
|
write() {
|
|
if type gum &> /dev/null; then
|
|
if [ -n "$1" ]; then
|
|
gum write --placeholder="$1"
|
|
else
|
|
gum write
|
|
fi
|
|
else
|
|
echo "ERROR: gum is not installed!"
|
|
fi
|
|
}
|
|
|
|
if [ -n "$1" ] && [ -n "$2" ]; then
|
|
# Public functions that require at least two parameters to be used
|
|
if [ "$1" == 'warn' ] || [ "$1" == 'success' ] || [ "$1" == 'star' ] || [ "$1" == 'info' ] \
|
|
|| [ "$1" == 'error' ] || [ "$1" == 'md' ] || [ "$1" == 'write' ] || [ "$1" == 'start' ] \
|
|
|| [ "$1" == 'spin' ] || [ "$1" == 'prompt' ] || [ "$1" == 'filter' ] || [ "$1" == 'input' ] \
|
|
|| [ "$1" == 'confirm' ] || [ "$1" == 'password' ]; then
|
|
"$1" "$2"
|
|
elif [[ "$1" == 'choose' ]]; then
|
|
"$@"
|
|
fi
|
|
elif [ -n "$1" ]; then
|
|
# Public functions that can run with only one argument passed to .config/log (i.e. `.config/log password`)
|
|
if [ "$1" == 'write' ] || [ "$1" == 'password' ] || [ "$1" == 'confirm' ] || [ "$1" == 'input' ]; then
|
|
"$1"
|
|
fi
|
|
fi
|