Initial commit: add .gitignore and README

This commit is contained in:
defiQUG
2026-02-09 21:51:52 -08:00
commit 5d47b3a5d9
49 changed files with 5633 additions and 0 deletions

37
lib/common/colors.sh Executable file
View File

@@ -0,0 +1,37 @@
#!/usr/bin/env bash
# Color definitions for script output
# Usage: source "$(dirname "$0")/colors.sh"
# Reset
NC='\033[0m' # No Color
# Regular Colors
BLACK='\033[0;30m'
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
BLUE='\033[0;34m'
PURPLE='\033[0;35m'
CYAN='\033[0;36m'
WHITE='\033[0;37m'
# Bold Colors
BOLD_BLACK='\033[1;30m'
BOLD_RED='\033[1;31m'
BOLD_GREEN='\033[1;32m'
BOLD_YELLOW='\033[1;33m'
BOLD_BLUE='\033[1;34m'
BOLD_PURPLE='\033[1;35m'
BOLD_CYAN='\033[1;36m'
BOLD_WHITE='\033[1;37m'
# Background Colors
BG_BLACK='\033[40m'
BG_RED='\033[41m'
BG_GREEN='\033[42m'
BG_YELLOW='\033[43m'
BG_BLUE='\033[44m'
BG_PURPLE='\033[45m'
BG_CYAN='\033[46m'
BG_WHITE='\033[47m'

46
lib/common/error-handling.sh Executable file
View File

@@ -0,0 +1,46 @@
#!/usr/bin/env bash
# Error handling functions
# Usage: source "$(dirname "$0")/error-handling.sh"
# Requires: logging.sh
# Set error trap
set_error_trap() {
trap 'error_handler $? $LINENO' ERR
}
# Error handler
error_handler() {
local exit_code=$1
local line_number=$2
log_error "Error occurred at line $line_number with exit code $exit_code"
# Call cleanup function if defined
if [ "$(type -t cleanup)" = "function" ]; then
cleanup
fi
exit "$exit_code"
}
# Cleanup function template (can be overridden)
cleanup() {
log_debug "Running cleanup..."
# Override this function in scripts that need cleanup
}
# Exit with error message
exit_with_error() {
local message="$1"
local exit_code="${2:-1}"
log_error "$message"
exit "$exit_code"
}
# Exit with success message
exit_with_success() {
local message="$1"
log_success "$message"
exit 0
}

57
lib/common/logging.sh Executable file
View File

@@ -0,0 +1,57 @@
#!/usr/bin/env bash
# Logging functions for scripts
# Usage: source "$(dirname "$0")/logging.sh"
# Requires: colors.sh
# Log levels (higher number = more verbose)
LOG_LEVEL_ERROR=0
LOG_LEVEL_WARN=1
LOG_LEVEL_INFO=2
LOG_LEVEL_DEBUG=3
# Default log level
LOG_LEVEL="${LOG_LEVEL:-$LOG_LEVEL_INFO}"
# Log functions
log_info() {
if [ "$LOG_LEVEL" -ge "$LOG_LEVEL_INFO" ]; then
echo -e "${GREEN}[INFO]${NC} $1" >&2
fi
}
log_error() {
if [ "$LOG_LEVEL" -ge "$LOG_LEVEL_ERROR" ]; then
echo -e "${RED}[ERROR]${NC} $1" >&2
fi
}
log_warn() {
if [ "$LOG_LEVEL" -ge "$LOG_LEVEL_WARN" ]; then
echo -e "${YELLOW}[WARN]${NC} $1" >&2
fi
}
log_debug() {
if [ "$LOG_LEVEL" -ge "$LOG_LEVEL_DEBUG" ]; then
echo -e "${CYAN}[DEBUG]${NC} $1" >&2
fi
}
log_success() {
echo -e "${GREEN}${NC} $1" >&2
}
log_failure() {
echo -e "${RED}${NC} $1" >&2
}
log_step() {
echo -e "${BLUE}📋${NC} $1" >&2
}
log_heading() {
echo -e "\n${BOLD_CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}" >&2
echo -e "${BOLD_CYAN}$1${NC}" >&2
echo -e "${BOLD_CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}\n" >&2
}

110
lib/common/utils.sh Executable file
View File

@@ -0,0 +1,110 @@
#!/usr/bin/env bash
# Common utility functions
# Usage: source "$(dirname "$0")/utils.sh"
# Requires: logging.sh, colors.sh
# Check if a command exists
check_command() {
command -v "$1" &> /dev/null
}
# Require a command to exist, exit if not found
require_command() {
if ! check_command "$1"; then
log_error "$1 is not installed. Please install it first."
exit 1
fi
log_debug "$1 is available"
}
# Check if a file exists
check_file() {
[ -f "$1" ]
}
# Require a file to exist, exit if not found
require_file() {
if ! check_file "$1"; then
log_error "Required file not found: $1"
exit 1
fi
}
# Check if a directory exists
check_dir() {
[ -d "$1" ]
}
# Require a directory to exist, exit if not found
require_dir() {
if ! check_dir "$1"; then
log_error "Required directory not found: $1"
exit 1
fi
}
# Get script directory
get_script_dir() {
local script_path="${BASH_SOURCE[1]}"
if [ -z "$script_path" ]; then
script_path="${BASH_SOURCE[0]}"
fi
dirname "$(readlink -f "$script_path")"
}
# Get project root (assumes scripts/ is in project root)
get_project_root() {
local script_dir="$(get_script_dir)"
# Go up from scripts/ or scripts/subdir/ to project root
if [[ "$script_dir" == */scripts ]]; then
dirname "$script_dir"
elif [[ "$script_dir" == */scripts/* ]]; then
dirname "$(dirname "$script_dir")"
else
echo "."
fi
}
# Create directory if it doesn't exist
ensure_dir() {
if [ ! -d "$1" ]; then
mkdir -p "$1"
log_debug "Created directory: $1"
fi
}
# Prompt for confirmation
confirm() {
local prompt="${1:-Continue?}"
local response
read -p "$(echo -e ${YELLOW}$prompt [y/N]: ${NC})" response
case "$response" in
[yY][eE][sS]|[yY])
return 0
;;
*)
return 1
;;
esac
}
# Run command with retry
retry() {
local max_attempts="${1:-3}"
local delay="${2:-1}"
shift 2
local attempt=1
while [ $attempt -le $max_attempts ]; do
if "$@"; then
return 0
fi
log_warn "Attempt $attempt/$max_attempts failed. Retrying in ${delay}s..."
sleep "$delay"
attempt=$((attempt + 1))
done
log_error "Command failed after $max_attempts attempts"
return 1
}

86
lib/common/validation.sh Executable file
View File

@@ -0,0 +1,86 @@
#!/usr/bin/env bash
# Input validation functions
# Usage: source "$(dirname "$0")/validation.sh"
# Requires: logging.sh
# Validate project name (alphanumeric, hyphens, underscores)
validate_project_name() {
local name="$1"
if [ -z "$name" ]; then
log_error "Project name is required"
return 1
fi
if [[ ! "$name" =~ ^[a-zA-Z0-9_-]+$ ]]; then
log_error "Invalid project name: $name (must be alphanumeric with hyphens/underscores only)"
return 1
fi
return 0
}
# Validate environment name
validate_environment() {
local env="$1"
local valid_envs=("development" "dev" "staging" "stg" "production" "prod" "test")
if [ -z "$env" ]; then
log_error "Environment is required"
return 1
fi
for valid_env in "${valid_envs[@]}"; do
if [ "$env" = "$valid_env" ]; then
return 0
fi
done
log_error "Invalid environment: $env (must be one of: ${valid_envs[*]})"
return 1
}
# Validate URL format
validate_url() {
local url="$1"
if [ -z "$url" ]; then
log_error "URL is required"
return 1
fi
if [[ ! "$url" =~ ^https?:// ]]; then
log_error "Invalid URL format: $url (must start with http:// or https://)"
return 1
fi
return 0
}
# Validate port number
validate_port() {
local port="$1"
if [ -z "$port" ]; then
log_error "Port is required"
return 1
fi
if ! [[ "$port" =~ ^[0-9]+$ ]] || [ "$port" -lt 1 ] || [ "$port" -gt 65535 ]; then
log_error "Invalid port: $port (must be 1-65535)"
return 1
fi
return 0
}
# Validate non-empty string
validate_non_empty() {
local value="$1"
local name="${2:-Value}"
if [ -z "$value" ]; then
log_error "$name is required and cannot be empty"
return 1
fi
return 0
}

65
lib/config/env.sh Executable file
View File

@@ -0,0 +1,65 @@
#!/usr/bin/env bash
# Environment loading functions
# Usage: source "$(dirname "$0")/env.sh"
# Requires: logging.sh, utils.sh
# Load environment file
load_env() {
local env_file="${1:-.env}"
local project_root="${PROJECT_ROOT:-$(get_project_root)}"
local full_path="$project_root/$env_file"
if [ -f "$full_path" ]; then
log_debug "Loading environment from: $full_path"
set -a
source "$full_path"
set +a
return 0
else
log_debug "Environment file not found: $full_path"
return 1
fi
}
# Require environment variable
require_env() {
local var_name="$1"
local var_value="${!var_name}"
if [ -z "$var_value" ]; then
log_error "Required environment variable not set: $var_name"
exit 1
fi
log_debug "Environment variable $var_name is set"
}
# Require multiple environment variables
require_envs() {
local missing_vars=()
for var_name in "$@"; do
if [ -z "${!var_name}" ]; then
missing_vars+=("$var_name")
fi
done
if [ ${#missing_vars[@]} -gt 0 ]; then
log_error "Missing required environment variables: ${missing_vars[*]}"
exit 1
fi
}
# Get environment variable with default
get_env() {
local var_name="$1"
local default_value="${2:-}"
local var_value="${!var_name:-$default_value}"
if [ -z "$var_value" ] && [ -z "$default_value" ]; then
log_warn "Environment variable $var_name is not set and no default provided"
fi
echo "$var_value"
}

31
lib/init.sh Executable file
View File

@@ -0,0 +1,31 @@
#!/usr/bin/env bash
# Initialize all common libraries
# Usage: source "$(dirname "$0")/init.sh"
#
# This script loads all common libraries in the correct order.
# Individual scripts can source this instead of sourcing each library separately.
# Get lib directory (this file's directory)
LIB_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# Get script directory if not set (try to get from calling script)
if [ -z "${SCRIPT_DIR:-}" ]; then
# Try to get from calling script (BASH_SOURCE[2] because init.sh adds one level)
if [ -n "${BASH_SOURCE[2]:-}" ]; then
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[2]}")" && pwd)"
elif [ -n "${BASH_SOURCE[1]:-}" ]; then
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[1]}")" && pwd)"
fi
fi
# Source libraries in order (dependencies first)
source "${LIB_DIR}/common/colors.sh"
source "${LIB_DIR}/common/logging.sh"
source "${LIB_DIR}/common/utils.sh"
source "${LIB_DIR}/common/validation.sh" 2>/dev/null || true
source "${LIB_DIR}/common/error-handling.sh" 2>/dev/null || true
source "${LIB_DIR}/config/env.sh" 2>/dev/null || true
# Log that libraries are loaded (only in debug mode)
[ "${LOG_LEVEL:-2}" -ge 3 ] && log_debug "Common libraries loaded from ${LIB_DIR}"