Files
dotfiles/lib/profile_manager.sh
Eric Turner 3ddad4b543 feat: add core library functions for package and profile management
- Add package_manager.sh for handling system package installations
- Add profile_manager.sh for managing machine-specific configurations
- Add update_checker.sh for version control and updates

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-02 20:21:25 -06:00

300 lines
11 KiB
Bash
Executable File

#!/bin/bash
# Machine Profile Manager for Dotfiles
# Handles profile detection, selection, and package filtering
PROFILES_CONFIG="$HOME/.dotfiles/machine-profiles.yaml"
PROFILE_FILE="$HOME/.dotfiles/.machine_profile"
PROFILE_LOG="$HOME/.dotfiles/.profile.log"
# Function to log profile operations
profile_log() {
echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" >> "$PROFILE_LOG"
}
# Function to get current profile
get_current_profile() {
if [[ -f "$PROFILE_FILE" ]]; then
cat "$PROFILE_FILE"
else
echo "dev-lite" # Default fallback
fi
}
# Function to set profile
set_profile() {
local profile="$1"
echo "$profile" > "$PROFILE_FILE"
profile_log "Profile set to: $profile"
}
# Function to detect machine type automatically
detect_machine_profile() {
local server_score=0
local dev_score=0
local personal_score=0
profile_log "Starting automatic profile detection"
# Server detection
if systemctl is-active sshd >/dev/null 2>&1; then
server_score=$((server_score + 30))
profile_log "Server indicator: sshd active (+30)"
fi
if [[ -f /etc/systemd/system/multi-user.target ]]; then
server_score=$((server_score + 20))
profile_log "Server indicator: multi-user target (+20)"
fi
if [[ -n "$SSH_CONNECTION" ]]; then
server_score=$((server_score + 25))
profile_log "Server indicator: SSH connection (+25)"
fi
# Development detection
if command -v code >/dev/null 2>&1 || command -v vim >/dev/null 2>&1 || command -v nvim >/dev/null 2>&1; then
dev_score=$((dev_score + 25))
profile_log "Dev indicator: editor available (+25)"
fi
if [[ -d ~/projects ]] || [[ -d ~/dev ]] || [[ -d ~/src ]]; then
dev_score=$((dev_score + 20))
profile_log "Dev indicator: development directories (+20)"
fi
if command -v node >/dev/null 2>&1 || command -v python3 >/dev/null 2>&1 || command -v docker >/dev/null 2>&1; then
dev_score=$((dev_score + 30))
profile_log "Dev indicator: development tools (+30)"
fi
if [[ -n "$DISPLAY" ]]; then
dev_score=$((dev_score + 15))
profile_log "Dev indicator: GUI environment (+15)"
fi
# Personal machine detection
if [[ -d ~/Desktop ]] || [[ -d ~/Documents ]]; then
personal_score=$((personal_score + 20))
profile_log "Personal indicator: user directories (+20)"
fi
if command -v firefox >/dev/null 2>&1 || command -v chrome >/dev/null 2>&1 || command -v safari >/dev/null 2>&1; then
personal_score=$((personal_score + 25))
profile_log "Personal indicator: browsers available (+25)"
fi
if [[ "$HOME" == *"/Users/"* ]] || [[ "$HOME" == *"/home/eric"* ]]; then
personal_score=$((personal_score + 15))
profile_log "Personal indicator: personal home directory (+15)"
fi
# Determine profile based on scores
profile_log "Scores - Server: $server_score, Dev: $dev_score, Personal: $personal_score"
if [[ $server_score -gt $dev_score ]] && [[ $server_score -gt $personal_score ]]; then
echo "server"
elif [[ $personal_score -gt $dev_score ]] && [[ $personal_score -gt $server_score ]]; then
echo "personal"
elif [[ $dev_score -gt 0 ]]; then
echo "dev"
else
echo "minimal"
fi
}
# Function to prompt user for profile confirmation
prompt_profile_selection() {
local detected_profile="$1"
echo "🤖 Machine Profile Detection"
echo "=============================="
echo "Detected profile: $detected_profile"
echo ""
echo "Available profiles:"
echo " server - Minimal server setup (curl, git, vim, sshuttle, ripgrep, fd)"
echo " dev - Full development setup (all tools + claude, gemini, docker)"
echo " dev-lite - Development without heavy packages (no docker)"
echo " personal - Personal machine (all tools including task-master)"
echo " minimal - Bare bones (curl, git, vim only)"
echo ""
echo "Use detected profile '$detected_profile'? [Y/n/choose]: "
read -r response
case "$response" in
[nN]|[nN][oO])
echo "Available profiles: server, dev, dev-lite, personal, minimal"
echo "Enter profile name: "
read -r selected_profile
if [[ -n "$selected_profile" ]]; then
echo "$selected_profile"
else
echo "$detected_profile"
fi
;;
[cC]|[cC][hH]*)
echo "Available profiles: server, dev, dev-lite, personal, minimal"
echo "Enter profile name: "
read -r selected_profile
if [[ -n "$selected_profile" ]]; then
echo "$selected_profile"
else
echo "$detected_profile"
fi
;;
*)
echo "$detected_profile"
;;
esac
}
# Function to get packages for current profile
get_profile_packages() {
local profile=$(get_current_profile)
local package_type="$1"
case "$profile" in
"server")
case "$package_type" in
"system") echo "curl git vim sshuttle" ;;
"binary") echo "" ;;
"github") echo "ripgrep fd" ;;
"npm") echo "" ;;
"python") echo "" ;;
"zsh") echo "" ;;
"optional") echo "" ;;
esac
;;
"dev")
case "$package_type" in
"system") echo "curl git vim sshuttle" ;;
"binary") echo "claude-code gemini-cli" ;;
"github") echo "fzf bat ripgrep fd delta" ;;
"npm") echo "pm2" ;;
"python") echo "requests" ;;
"zsh") echo "zsh-syntax-highlighting zsh-autosuggestions" ;;
"optional") echo "docker docker-compose" ;;
esac
;;
"dev-lite")
case "$package_type" in
"system") echo "curl git vim sshuttle" ;;
"binary") echo "claude-code gemini-cli" ;;
"github") echo "fzf bat ripgrep fd delta" ;;
"npm") echo "" ;;
"python") echo "requests" ;;
"zsh") echo "zsh-syntax-highlighting zsh-autosuggestions" ;;
"optional") echo "" ;;
esac
;;
"personal")
case "$package_type" in
"system") echo "curl git vim sshuttle" ;;
"binary") echo "claude-code gemini-cli task-master" ;;
"github") echo "fzf bat ripgrep fd delta" ;;
"npm") echo "pm2" ;;
"python") echo "requests" ;;
"zsh") echo "zsh-syntax-highlighting zsh-autosuggestions" ;;
"optional") echo "docker docker-compose" ;;
esac
;;
"minimal")
case "$package_type" in
"system") echo "curl git vim" ;;
"binary") echo "" ;;
"github") echo "" ;;
"npm") echo "" ;;
"python") echo "" ;;
"zsh") echo "" ;;
"optional") echo "" ;;
esac
;;
*)
# Default to dev-lite
case "$package_type" in
"system") echo "curl git vim sshuttle" ;;
"binary") echo "claude-code gemini-cli" ;;
"github") echo "fzf bat ripgrep fd delta" ;;
"npm") echo "" ;;
"python") echo "requests" ;;
"zsh") echo "zsh-syntax-highlighting zsh-autosuggestions" ;;
"optional") echo "" ;;
esac
;;
esac
}
# Function to show current profile status
show_profile_status() {
local current_profile=$(get_current_profile)
echo "🖥️ Machine Profile Status"
echo "========================="
echo "Current profile: $current_profile"
echo ""
case "$current_profile" in
"server")
echo "📋 Server Profile - Minimal setup"
echo " ✅ Essential tools: curl, git, vim, sshuttle"
echo " ✅ Admin tools: ripgrep, fd"
echo " ❌ Development tools: Not installed"
echo " ❌ GUI tools: Not installed"
;;
"dev")
echo "🚀 Development Profile - Full setup"
echo " ✅ Essential tools: All included"
echo " ✅ Development tools: claude, gemini, docker"
echo " ✅ Modern CLI tools: fzf, bat, ripgrep, fd, delta"
echo " ✅ Optional tools: docker, docker-compose"
;;
"dev-lite")
echo "⚡ Development Lite Profile - No heavy packages"
echo " ✅ Essential tools: All included"
echo " ✅ Development tools: claude, gemini (no docker)"
echo " ✅ Modern CLI tools: fzf, bat, ripgrep, fd, delta"
echo " ❌ Heavy tools: docker excluded"
;;
"personal")
echo "🏠 Personal Profile - Everything included"
echo " ✅ Essential tools: All included"
echo " ✅ Development tools: claude, gemini, task-master"
echo " ✅ Modern CLI tools: All included"
echo " ✅ Personal tools: All conveniences"
;;
"minimal")
echo "🔧 Minimal Profile - Bare essentials"
echo " ✅ Core tools: curl, git, vim"
echo " ❌ Everything else: Excluded"
;;
esac
echo ""
echo "💡 Change profile with: dotprofile set <profile>"
echo " Available: server, dev, dev-lite, personal, minimal"
}
# Function to initialize profile (used during installation)
initialize_profile() {
local force_detect=${1:-false}
if [[ ! -f "$PROFILE_FILE" ]] || [[ "$force_detect" == "true" ]]; then
profile_log "Initializing machine profile"
local detected_profile=$(detect_machine_profile)
profile_log "Auto-detected profile: $detected_profile"
# In interactive mode, ask user
if [[ $- == *i* ]] && [[ "$force_detect" != "silent" ]]; then
local selected_profile=$(prompt_profile_selection "$detected_profile")
set_profile "$selected_profile"
profile_log "User selected profile: $selected_profile"
echo "✅ Profile set to: $selected_profile"
else
# Non-interactive or silent mode
set_profile "$detected_profile"
profile_log "Auto-set profile: $detected_profile"
echo "🤖 Auto-detected profile: $detected_profile"
fi
fi
get_current_profile
}