#!/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 " 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 }