testsAndMisc/linux_configuration/scripts/lib/common.sh
Krzysztof kuhy Rudnicki 51e3945507
Some checks are pending
billsplit CI / quality (push) Waiting to run
Pre-commit checks / pre-commit (push) Waiting to run
Shell tests / shell-tests (push) Waiting to run
Shell tests / arch-tests (push) Waiting to run
Split scripts/lib/common.sh, the library 49 scripts source
620 -> 163, with common.sh staying the single entry point that sources
its own three parts - the shape the handoff prescribes for config.sh, so
all 49 consumers are untouched.

Verified by diffing `declare -F` after sourcing it against the same from
a detached worktree at HEAD: an identical 48-function set. For a library
this widely sourced that is the check that matters, not a passing lint.

The FOCUS_APPS_* arrays moved with is_focus_app_running, the only
function that reads them.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011w2Pj4Ek3ZNMQVYcFHgXDY
2026-08-16 21:14:48 +02:00

164 lines
4.4 KiB
Bash
Executable File

#!/bin/bash
# Common library functions for linux-configuration scripts
# Source this file at the beginning of scripts that need shared functionality
#
# Usage: source "$(dirname "$(readlink -f "$0")")/../lib/common.sh"
# Or: source "/path/to/scripts/lib/common.sh"
# Prevent multiple sourcing
[[ -n ${_LIB_COMMON_LOADED:-} ]] && return 0
_LIB_COMMON_LOADED=1
# =============================================================================
# LOGGING FUNCTIONS
# =============================================================================
# Log message with timestamp to stderr and optionally to a file
# Usage: log_message "message" [log_file]
log_message() {
local msg="$1"
local log_file="${2:-}"
local formatted
printf -v formatted '%(%Y-%m-%d %H:%M:%S)T - %s' -1 "$msg"
echo "$formatted" >&2
if [[ -n $log_file ]]; then
echo "$formatted" >>"$log_file" 2>/dev/null || true
fi
}
# Simple log with timestamp (no file output)
# Usage: log "message"
log() {
local _ts
printf -v _ts '%(%Y-%m-%d %H:%M:%S)T' -1
printf '[%s] %s\n' "$_ts" "$*"
}
# =============================================================================
# SUDO / ROOT HANDLING
# =============================================================================
# Check if running as root, if not re-exec with sudo
# Usage: require_root "$@"
require_root() {
if [[ $EUID -ne 0 ]]; then
echo "This script requires root privileges."
echo "Requesting sudo access..."
exec sudo "$0" "$@"
fi
}
# Get the actual user even when running with sudo
# Usage: ACTUAL_USER=$(get_actual_user)
get_actual_user() {
echo "${SUDO_USER:-$USER}"
}
# Get the actual user's home directory
# Usage: USER_HOME=$(get_actual_user_home)
get_actual_user_home() {
local user
user=$(get_actual_user)
if [[ $user == "root" ]]; then
echo "/root"
else
echo "/home/$user"
fi
}
# Set both ACTUAL_USER and USER_HOME variables (common pattern)
# Usage: set_actual_user_vars
# echo "$ACTUAL_USER" # => the actual user
# echo "$USER_HOME" # => /home/username
set_actual_user_vars() {
ACTUAL_USER=$(get_actual_user)
USER_HOME=$(get_actual_user_home)
export ACTUAL_USER USER_HOME
}
# =============================================================================
# ARGUMENT PARSING HELPERS
# =============================================================================
# Parse common --interactive/-i and --help/-h flags
# Sets INTERACTIVE_MODE variable (exported for use by calling scripts)
# Usage: parse_common_args "$@"
# shift "$COMMON_ARGS_SHIFT"
export INTERACTIVE_MODE=false
export COMMON_ARGS_SHIFT=0
parse_interactive_args() {
INTERACTIVE_MODE=false
COMMON_ARGS_SHIFT=0
local script_name="${0##*/}"
while [[ $# -gt 0 ]]; do
case $1 in
-i | --interactive)
INTERACTIVE_MODE=true
((COMMON_ARGS_SHIFT++))
shift
;;
-h | --help)
echo "Usage: $script_name [OPTIONS]"
echo "Options:"
echo " -i, --interactive Enable interactive prompts (default: auto-yes)"
echo " -h, --help Show this help message"
exit 0
;;
*)
# Stop parsing at first unknown argument
break
;;
esac
done
}
# Handle common argument patterns for scripts with custom usage functions
# Usage: handle_arg_help_or_unknown "$1" usage_function err_function
# Returns: 1 if the argument is not ours, so the caller handles it.
# Exits: on -h/--help (exit 0) or unknown arg starting with - (exit 2).
# There is deliberately no success return: every other branch exits. The old
# trailing `return 0` was unreachable, and the doc promised a 0 that no code
# path could ever produce.
handle_arg_help_or_unknown() {
local arg="$1"
local usage_fn="${2:-usage}"
local err_fn="${3:-err}"
case "$arg" in
-h | --help)
"$usage_fn"
exit 0
;;
-*)
"$err_fn" "Unknown argument: $arg"
"$usage_fn"
exit 2
;;
*)
return 1 # Not a flag, let caller handle it
;;
esac
}
# Initialize a setup script with common boilerplate
# Usage: init_setup_script "Script Title" "$@"
# This combines: parse_interactive_args, shift, require_root, print_setup_header
init_setup_script() {
local title="$1"
shift
parse_interactive_args "$@"
shift "$COMMON_ARGS_SHIFT"
require_root "$@"
print_setup_header "$title"
}
_COMMON_DIR="$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")"
# shellcheck source=common_services.sh
source "$_COMMON_DIR/common_packages.sh"
# shellcheck source=common_services.sh
source "$_COMMON_DIR/common_services.sh"
# shellcheck source=common_datetime.sh
source "$_COMMON_DIR/common_datetime.sh"