feat: implement modular numbered script system
- Add scripts/ directory with numbered execution pattern - Create 00-check-dependencies.sh for requirement validation - Create 10-backup-files.sh for conflict handling - Create 20-setup-stow.sh for symlink creation - Create 90-post-install.sh for cleanup tasks - Add scripts/utils.sh with colored logging functions - Update install.sh to auto-discover and execute numbered scripts - Remove hardcoded logic in favor of flexible script discovery Benefits: - Clean separation of concerns (each script has one job) - Numbered execution order (SSH/systemd convention) - Colored output for better UX - Easy to extend with additional scripts - Same entry point for all branches
This commit is contained in:
66
install.sh
66
install.sh
@@ -4,44 +4,48 @@ set -euo pipefail
|
|||||||
DOTFILES_REPO="https://gitea.purpleraft.com/ryan/dotfiles"
|
DOTFILES_REPO="https://gitea.purpleraft.com/ryan/dotfiles"
|
||||||
DOTFILES_DIR="$HOME/.dotfiles"
|
DOTFILES_DIR="$HOME/.dotfiles"
|
||||||
|
|
||||||
# Check if stow is installed
|
# Source utilities if available
|
||||||
if ! command -v stow &> /dev/null; then
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
echo "❌ GNU Stow is not installed. Please install it first:"
|
if [ -f "$SCRIPT_DIR/scripts/utils.sh" ]; then
|
||||||
echo " Ubuntu/Debian: sudo apt install stow"
|
source "$SCRIPT_DIR/scripts/utils.sh"
|
||||||
echo " macOS: brew install stow"
|
else
|
||||||
echo " Or use the alias: install_stow"
|
# Fallback logging functions if utils not available
|
||||||
exit 1
|
log_info() { echo "ℹ️ $1"; }
|
||||||
|
log_success() { echo "✅ $1"; }
|
||||||
|
log_warning() { echo "⚠️ $1"; }
|
||||||
|
log_error() { echo "❌ $1"; }
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
log_info "🚀 Starting dotfiles installation..."
|
||||||
|
|
||||||
# Clone or update the repo
|
# Clone or update the repo
|
||||||
if [ -d "$DOTFILES_DIR/.git" ]; then
|
if [ -d "$DOTFILES_DIR/.git" ]; then
|
||||||
echo "Updating existing dotfiles repo..."
|
log_info "Updating existing dotfiles repo..."
|
||||||
git -C "$DOTFILES_DIR" pull --quiet
|
git -C "$DOTFILES_DIR" pull --quiet
|
||||||
else
|
else
|
||||||
echo "Cloning dotfiles into $DOTFILES_DIR..."
|
log_info "Cloning dotfiles into $DOTFILES_DIR..."
|
||||||
git clone "$DOTFILES_REPO" "$DOTFILES_DIR"
|
git clone "$DOTFILES_REPO" "$DOTFILES_DIR"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Backup existing files that would conflict with stow (excluding SSH config - it's machine-specific)
|
|
||||||
for file in .bashrc .bash_aliases .inputrc .gitconfig; do
|
|
||||||
if [ -f "$HOME/$file" ] && [ ! -L "$HOME/$file" ]; then
|
|
||||||
echo "⚠️ Backing up existing file: $HOME/$file -> $HOME/${file}.bak"
|
|
||||||
mv "$HOME/$file" "$HOME/${file}.bak"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
# Change to dotfiles directory and use stow to create symlinks
|
|
||||||
cd "$DOTFILES_DIR"
|
cd "$DOTFILES_DIR"
|
||||||
echo "🔗 Using Stow to symlink dotfiles..."
|
|
||||||
if ! stow --adopt -t "$HOME" . 2>/dev/null; then
|
# Auto-discover and run setup scripts
|
||||||
echo "🔄 Adopting failed, trying regular stow..."
|
if [ -d "scripts" ]; then
|
||||||
stow -t "$HOME" .
|
log_info "Running setup scripts..."
|
||||||
|
|
||||||
|
# Look for numbered scripts and run them in order
|
||||||
|
for script in scripts/[0-9][0-9]-*.sh; do
|
||||||
|
if [ -f "$script" ]; then
|
||||||
|
# Make executable and run
|
||||||
|
chmod +x "$script" 2>/dev/null || true
|
||||||
|
script_name=$(basename "$script")
|
||||||
|
log_info "Running $script_name..."
|
||||||
|
"$script" "$DOTFILES_DIR"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
else
|
||||||
|
log_error "No scripts directory found! Something went wrong with the installation."
|
||||||
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Optionally source the new bashrc
|
log_success "Dotfiles install complete!"
|
||||||
if [[ $- == *i* ]]; then
|
|
||||||
echo "Reloading Bash config..."
|
|
||||||
source ~/.bashrc
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "✅ Dotfiles install complete."
|
|
||||||
|
|||||||
57
scripts/00-check-dependencies.sh
Normal file
57
scripts/00-check-dependencies.sh
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# scripts/00-check-dependencies.sh - Check for required dependencies
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# Source utilities
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
source "$SCRIPT_DIR/utils.sh"
|
||||||
|
|
||||||
|
check_dependencies() {
|
||||||
|
log_info "Checking dependencies..."
|
||||||
|
|
||||||
|
local missing_deps=()
|
||||||
|
|
||||||
|
# Check for git
|
||||||
|
if ! command_exists git; then
|
||||||
|
missing_deps+=("git")
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check for stow
|
||||||
|
if ! command_exists stow; then
|
||||||
|
missing_deps+=("stow")
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ${#missing_deps[@]} -gt 0 ]; then
|
||||||
|
log_error "Missing required dependencies: ${missing_deps[*]}"
|
||||||
|
echo ""
|
||||||
|
echo "Please install the missing dependencies:"
|
||||||
|
|
||||||
|
for dep in "${missing_deps[@]}"; do
|
||||||
|
case "$dep" in
|
||||||
|
"git")
|
||||||
|
echo " Git:"
|
||||||
|
echo " Ubuntu/Debian: sudo apt install git"
|
||||||
|
echo " macOS: brew install git"
|
||||||
|
echo " Or visit: https://git-scm.com/downloads"
|
||||||
|
;;
|
||||||
|
"stow")
|
||||||
|
echo " GNU Stow:"
|
||||||
|
echo " Ubuntu/Debian: sudo apt install stow"
|
||||||
|
echo " macOS: brew install stow"
|
||||||
|
echo " Or use the alias: install_stow"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
echo ""
|
||||||
|
done
|
||||||
|
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
log_success "All dependencies satisfied"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Run if called directly
|
||||||
|
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
|
||||||
|
check_dependencies
|
||||||
|
fi
|
||||||
41
scripts/10-backup-files.sh
Normal file
41
scripts/10-backup-files.sh
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# scripts/10-backup-files.sh - Backup existing files that would conflict
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# Source utilities
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
source "$SCRIPT_DIR/utils.sh"
|
||||||
|
|
||||||
|
backup_files() {
|
||||||
|
local dotfiles_dir="$1"
|
||||||
|
|
||||||
|
log_info "Checking for file conflicts..."
|
||||||
|
|
||||||
|
# Files that might conflict with stow
|
||||||
|
local files_to_check=(.bashrc .bash_aliases .inputrc .gitconfig)
|
||||||
|
local backed_up=()
|
||||||
|
|
||||||
|
for file in "${files_to_check[@]}"; do
|
||||||
|
if [ -f "$HOME/$file" ] && [ ! -L "$HOME/$file" ]; then
|
||||||
|
log_warning "Backing up existing file: $HOME/$file -> $HOME/${file}.bak"
|
||||||
|
mv "$HOME/$file" "$HOME/${file}.bak"
|
||||||
|
backed_up+=("$file")
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ ${#backed_up[@]} -gt 0 ]; then
|
||||||
|
log_info "Backed up ${#backed_up[@]} file(s): ${backed_up[*]}"
|
||||||
|
else
|
||||||
|
log_info "No file conflicts found"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Run if called directly
|
||||||
|
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
|
||||||
|
if [ $# -ne 1 ]; then
|
||||||
|
log_error "Usage: $0 <dotfiles_directory>"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
backup_files "$1"
|
||||||
|
fi
|
||||||
32
scripts/20-setup-stow.sh
Normal file
32
scripts/20-setup-stow.sh
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# scripts/20-setup-stow.sh - Handle GNU Stow operations
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# Source utilities
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
source "$SCRIPT_DIR/utils.sh"
|
||||||
|
|
||||||
|
setup_stow() {
|
||||||
|
local dotfiles_dir="$1"
|
||||||
|
|
||||||
|
# Change to dotfiles directory and use stow to create symlinks
|
||||||
|
cd "$dotfiles_dir"
|
||||||
|
log_info "Using Stow to symlink dotfiles..."
|
||||||
|
|
||||||
|
if ! stow --adopt -t "$HOME" . 2>/dev/null; then
|
||||||
|
log_warning "Adopting failed, trying regular stow..."
|
||||||
|
stow -t "$HOME" .
|
||||||
|
fi
|
||||||
|
|
||||||
|
log_success "Stow setup complete"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Run if called directly
|
||||||
|
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
|
||||||
|
if [ $# -ne 1 ]; then
|
||||||
|
log_error "Usage: $0 <dotfiles_directory>"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
setup_stow "$1"
|
||||||
|
fi
|
||||||
26
scripts/90-post-install.sh
Normal file
26
scripts/90-post-install.sh
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# scripts/90-post-install.sh - Post-installation tasks
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# Source utilities
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
source "$SCRIPT_DIR/utils.sh"
|
||||||
|
|
||||||
|
post_install() {
|
||||||
|
log_info "Running post-installation tasks..."
|
||||||
|
|
||||||
|
# Source the new bashrc if in interactive shell
|
||||||
|
if is_interactive && [ -f "$HOME/.bashrc" ]; then
|
||||||
|
log_info "Reloading Bash config..."
|
||||||
|
source "$HOME/.bashrc"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Show completion message
|
||||||
|
log_success "Post-installation tasks complete"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Run if called directly
|
||||||
|
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
|
||||||
|
post_install
|
||||||
|
fi
|
||||||
36
scripts/utils.sh
Normal file
36
scripts/utils.sh
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# scripts/utils.sh - Shared utilities and functions
|
||||||
|
|
||||||
|
# Colors for output
|
||||||
|
RED='\033[0;31m'
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
YELLOW='\033[1;33m'
|
||||||
|
BLUE='\033[0;34m'
|
||||||
|
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}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check if command exists
|
||||||
|
command_exists() {
|
||||||
|
command -v "$1" &> /dev/null
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check if we're in an interactive shell
|
||||||
|
is_interactive() {
|
||||||
|
[[ $- == *i* ]]
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user