Files
michaelschiemer/.deployment-archive-20251030-111806/scripts/lib/common.sh

216 lines
4.4 KiB
Bash
Executable File
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/bin/bash
#
# Common Library Functions for Deployment Scripts
# Provides unified logging, error handling, and utilities
#
set -euo pipefail
# Colors for output
readonly RED='\033[0;31m'
readonly GREEN='\033[0;32m'
readonly YELLOW='\033[1;33m'
readonly BLUE='\033[0;34m'
readonly CYAN='\033[0;36m'
readonly MAGENTA='\033[0;35m'
readonly NC='\033[0m' # No Color
# Logging functions
log_info() {
echo -e "${BLUE} ${1}${NC}"
}
log_success() {
echo -e "${GREEN}${1}${NC}"
}
log_warning() {
echo -e "${YELLOW}⚠️ ${1}${NC}"
}
log_error() {
echo -e "${RED}${1}${NC}"
}
log_debug() {
if [[ "${DEBUG:-0}" == "1" ]]; then
echo -e "${CYAN}🔍 ${1}${NC}"
fi
}
log_step() {
echo -e "${MAGENTA}▶️ ${1}${NC}"
}
# Error handling
die() {
log_error "$1"
exit "${2:-1}"
}
# Check if command exists
command_exists() {
command -v "$1" &> /dev/null
}
# Validate prerequisites
require_command() {
local cmd="$1"
local install_hint="${2:-}"
if ! command_exists "$cmd"; then
log_error "Required command not found: $cmd"
[[ -n "$install_hint" ]] && log_info "Install with: $install_hint"
return 1
fi
return 0
}
# Run command with retry logic
run_with_retry() {
local max_attempts="${1}"
local delay="${2}"
shift 2
local cmd=("$@")
local attempt=1
while [[ $attempt -le $max_attempts ]]; do
if "${cmd[@]}"; then
return 0
fi
if [[ $attempt -lt $max_attempts ]]; then
log_warning "Command failed (attempt $attempt/$max_attempts). Retrying in ${delay}s..."
sleep "$delay"
fi
((attempt++))
done
log_error "Command failed after $max_attempts attempts"
return 1
}
# Execute command and capture output
execute() {
local cmd="$1"
log_debug "Executing: $cmd"
eval "$cmd"
}
# Spinner for long-running operations
spinner() {
local pid=$1
local delay=0.1
local spinstr='⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏'
while ps -p "$pid" > /dev/null 2>&1; do
local temp=${spinstr#?}
printf " [%c] " "$spinstr"
local spinstr=$temp${spinstr%"$temp"}
sleep $delay
printf "\b\b\b\b\b\b"
done
printf " \b\b\b\b"
}
# Progress bar
progress_bar() {
local current=$1
local total=$2
local width=50
local percentage=$((current * 100 / total))
local completed=$((width * current / total))
local remaining=$((width - completed))
printf "\r["
printf "%${completed}s" | tr ' ' '█'
printf "%${remaining}s" | tr ' ' '░'
printf "] %3d%%" "$percentage"
if [[ $current -eq $total ]]; then
echo ""
fi
}
# Confirm action
confirm() {
local prompt="${1:-Are you sure?}"
local default="${2:-n}"
if [[ "$default" == "y" ]]; then
prompt="$prompt [Y/n] "
else
prompt="$prompt [y/N] "
fi
read -rp "$prompt" response
response=${response:-$default}
[[ "$response" =~ ^[Yy]$ ]]
}
# Parse YAML-like config
parse_config() {
local config_file="$1"
local key="$2"
if [[ ! -f "$config_file" ]]; then
log_error "Config file not found: $config_file"
return 1
fi
grep "^${key}:" "$config_file" | sed "s/^${key}:[[:space:]]*//" | tr -d '"'
}
# Timestamp functions
timestamp() {
date '+%Y-%m-%d %H:%M:%S'
}
timestamp_file() {
date '+%Y%m%d_%H%M%S'
}
# Duration calculation
duration() {
local start=$1
local end=${2:-$(date +%s)}
local elapsed=$((end - start))
local hours=$((elapsed / 3600))
local minutes=$(((elapsed % 3600) / 60))
local seconds=$((elapsed % 60))
if [[ $hours -gt 0 ]]; then
printf "%dh %dm %ds" "$hours" "$minutes" "$seconds"
elif [[ $minutes -gt 0 ]]; then
printf "%dm %ds" "$minutes" "$seconds"
else
printf "%ds" "$seconds"
fi
}
# Cleanup handler
cleanup_handlers=()
register_cleanup() {
cleanup_handlers+=("$1")
}
cleanup() {
log_info "Running cleanup handlers..."
for handler in "${cleanup_handlers[@]}"; do
eval "$handler" || log_warning "Cleanup handler failed: $handler"
done
}
trap cleanup EXIT
# Export functions for use in other scripts
export -f log_info log_success log_warning log_error log_debug log_step
export -f die command_exists require_command run_with_retry execute
export -f spinner progress_bar confirm parse_config
export -f timestamp timestamp_file duration
export -f register_cleanup cleanup