Files
Arch-Linux-Installer/lib/core/common.sh

274 lines
6.4 KiB
Bash
Raw Permalink Blame History

This file contains ambiguous Unicode characters
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
# Copyright 2026 Logan Fick
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# common.sh - Core utility functions for messaging and user interaction
#
# Provides colored output, user prompts, and progress tracking used throughout
# the installer.
# Color codes for terminal output
readonly COLOR_RED='\033[0;31m'
readonly COLOR_GREEN='\033[0;32m'
readonly COLOR_YELLOW='\033[0;33m'
readonly COLOR_BLUE='\033[0;34m'
readonly COLOR_CYAN='\033[0;36m'
readonly COLOR_BG_GRAY='\033[48;5;236m'
readonly COLOR_RESET='\033[0m'
# Current installation phase (set by set_phase)
CURRENT_PHASE=""
# Step counter for progress indicator
CURRENT_STEP=0
TOTAL_STEPS=10
# Print the installer banner (call once at start)
print_banner() {
echo ""
echo -e "${COLOR_BLUE}:: ${INSTALLER_NAME} ::${COLOR_RESET}"
echo ""
}
# Print a standard message with arrow prefix
print() {
echo -e "${COLOR_BLUE}${COLOR_RESET} $1"
}
# Print an informational message
print_info() {
echo -e "${COLOR_CYAN}${COLOR_RESET} $1"
}
# Run a command with gray background for its output
# Use this for commands that produce visible output (fdisk, pacstrap, pacman, etc.)
# Logs the command before execution for auditing
run_visible_cmd() {
log_cmd "$@"
echo -ne "${COLOR_BG_GRAY}"
"$@"
local exit_code=$?
echo -e "${COLOR_RESET}"
return $exit_code
}
# Run a command with piped input and gray background for its output
# Logs the command (without the piped input) before execution
# Arguments:
# $1 - input to pipe to the command
# $@ - command and arguments
run_piped_cmd() {
local input="$1"
shift
log_cmd "$@"
echo -ne "${COLOR_BG_GRAY}"
echo -n "$input" | "$@"
local exit_code=$?
echo -e "${COLOR_RESET}"
return $exit_code
}
# Run a command with logging only (no visual wrapper)
# Use for commands that need stdout preserved (pipes, redirections)
run_cmd() {
log_cmd "$@"
"$@"
}
# Run a command that is allowed to fail
# Logs the command, suppresses stderr, and always returns success
# Use for cleanup commands where failure is acceptable
run_cmd_allow_fail() {
log_cmd "$@"
"$@" 2>/dev/null || true
}
# Run a command in the chroot environment with logging
# Use for commands that don't produce visible output
run_cmd_in_chroot() {
log_cmd arch-chroot "${MOUNT_POINT}" "$@"
arch-chroot "${MOUNT_POINT}" "$@"
}
# Run a command in the chroot environment with gray background
# Use for commands that produce visible output (pacman, mkinitcpio, etc.)
run_visible_cmd_in_chroot() {
log_cmd arch-chroot "${MOUNT_POINT}" "$@"
echo -ne "${COLOR_BG_GRAY}"
arch-chroot "${MOUNT_POINT}" "$@"
local exit_code=$?
echo -e "${COLOR_RESET}"
return $exit_code
}
# Print an installation step/phase header with progress indicator
print_step() {
local step="$1"
CURRENT_STEP=$((CURRENT_STEP + 1))
CURRENT_PHASE="$step"
echo ""
echo -e "${COLOR_BLUE}=== [${CURRENT_STEP}/${TOTAL_STEPS}] ${step} ===${COLOR_RESET}"
}
# Print a success message
print_success() {
echo -e "${COLOR_GREEN}[OK]${COLOR_RESET} $1"
}
# Print a warning message
print_warning() {
echo -e "${COLOR_YELLOW}[WARNING]${COLOR_RESET} $1"
}
# Print an error message
print_error() {
echo -e "${COLOR_RED}[ERROR]${COLOR_RESET} $1" >&2
}
# Ask for yes/no confirmation
# Arguments:
# $1 - prompt message
# Returns:
# 0 if user confirms, 1 otherwise
confirm() {
local prompt="$1"
local response
print "${prompt} [y/N]: "
read -r response
case "$response" in
[yY][eE][sS]|[yY])
return 0
;;
*)
return 1
;;
esac
}
# Require "I am sure" confirmation for destructive operations
# Arguments:
# $1 - warning message
# Returns:
# 0 if user confirms, 1 otherwise
require_confirmation() {
local warning="$1"
local response
print "${warning}"
print "Enter 'I am sure' exactly to confirm, or anything else to cancel."
read -r response
if [ "$response" = "I am sure" ]; then
return 0
else
print "Confirmation failed. Exiting..."
return 1
fi
}
# Prompt for user input
# Arguments:
# $1 - prompt message
# $2 - variable name to store result
prompt() {
local prompt_msg="$1"
local var_name="$2"
local response
print "$prompt_msg"
read -r response
eval "$var_name='$response'"
}
# Prompt for secret input (no echo)
# Arguments:
# $1 - prompt message
# $2 - variable name to store result
prompt_secret() {
local prompt_msg="$1"
local var_name="$2"
local response
print "$prompt_msg"
read -rs response
echo
eval "$var_name='$response'"
}
# Prompt for password with confirmation
# Arguments:
# $1 - prompt message
# $2 - variable name to store result
# Returns:
# 0 on success, 1 if passwords don't match
prompt_password() {
local prompt_msg="$1"
local var_name="$2"
local password
local password_confirm
print "$prompt_msg"
read -rs password
echo
print "Please confirm your password."
read -rs password_confirm
echo
if [ "$password" != "$password_confirm" ]; then
print_error "Passwords do not match."
return 1
fi
eval "$var_name='$password'"
unset password password_confirm
return 0
}
# Display a menu and get user selection
# Arguments:
# $1 - menu title
# $@ - menu options (remaining arguments)
# Returns:
# Selected option number in MENU_SELECTION variable
prompt_menu() {
local title="$1"
shift
local options=("$@")
local i=1
print "$title"
for option in "${options[@]}"; do
print " $i - $option"
((i++))
done
read -r MENU_SELECTION
}
# Wait for user to press enter
wait_for_enter() {
local message="${1:-Press enter to continue.}"
print "$message"
read -r
}
# Get the directory containing the main script
get_script_dir() {
echo "$SCRIPT_DIR"
}