added install and update script to get more comfort and easyer way to work
This commit is contained in:
937
install.bash
Normal file
937
install.bash
Normal file
@@ -0,0 +1,937 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Dotfiles Installation Script - Cross-Platform
|
||||
# Test Developer Setup: Fish or Zsh + Ghostty + Tools
|
||||
|
||||
set -e # Exit on error
|
||||
|
||||
DOTFILES_DIR="$HOME/git/dotfiles"
|
||||
BACKUP_DIR="$HOME/.config-backup-$(date +%Y%m%d-%H%M%S)"
|
||||
|
||||
# Colors
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
RED='\033[0;31m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m'
|
||||
|
||||
# Package manager and OS detection
|
||||
PACKAGE_MANAGER=""
|
||||
OS=""
|
||||
|
||||
log() { echo -e "${GREEN}[INFO]${NC} $1"; }
|
||||
warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
|
||||
error() { echo -e "${RED}[ERROR]${NC} $1"; }
|
||||
|
||||
detect_os() {
|
||||
log "Detecting operating system..."
|
||||
|
||||
if [[ "$OSTYPE" == "darwin"* ]]; then
|
||||
OS="macos"
|
||||
PACKAGE_MANAGER="brew"
|
||||
elif [[ -f /etc/arch-release ]]; then
|
||||
OS="arch"
|
||||
PACKAGE_MANAGER="pacman"
|
||||
elif [[ -f /etc/debian_version ]]; then
|
||||
OS="debian"
|
||||
PACKAGE_MANAGER="apt"
|
||||
elif [[ -f /etc/fedora-release ]]; then
|
||||
OS="fedora"
|
||||
PACKAGE_MANAGER="dnf"
|
||||
elif [[ -f /etc/redhat-release ]]; then
|
||||
OS="rhel"
|
||||
PACKAGE_MANAGER="yum"
|
||||
elif [[ -f /etc/opensuse-release ]]; then
|
||||
OS="opensuse"
|
||||
PACKAGE_MANAGER="zypper"
|
||||
else
|
||||
error "Unsupported operating system"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log "Detected: $OS with $PACKAGE_MANAGER"
|
||||
}
|
||||
|
||||
install_package_manager() {
|
||||
case $PACKAGE_MANAGER in
|
||||
"brew")
|
||||
if ! command -v brew &> /dev/null; then
|
||||
log "Installing Homebrew..."
|
||||
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
|
||||
fi
|
||||
;;
|
||||
"pacman")
|
||||
log "Pacman detected - updating package database..."
|
||||
sudo pacman -Sy
|
||||
;;
|
||||
"apt")
|
||||
log "APT detected - updating package database..."
|
||||
sudo apt update
|
||||
;;
|
||||
"dnf")
|
||||
log "DNF detected - updating package database..."
|
||||
sudo dnf check-update || true
|
||||
;;
|
||||
"yum")
|
||||
log "YUM detected - updating package database..."
|
||||
sudo yum check-update || true
|
||||
;;
|
||||
"zypper")
|
||||
log "Zypper detected - updating package database..."
|
||||
sudo zypper refresh
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
install_package() {
|
||||
local package=$1
|
||||
log "Installing $package..."
|
||||
|
||||
case $PACKAGE_MANAGER in
|
||||
"brew")
|
||||
brew install "$package"
|
||||
;;
|
||||
"pacman")
|
||||
sudo pacman -S --noconfirm "$package"
|
||||
;;
|
||||
"apt")
|
||||
sudo apt install -y "$package"
|
||||
;;
|
||||
"dnf")
|
||||
sudo dnf install -y "$package"
|
||||
;;
|
||||
"yum")
|
||||
sudo yum install -y "$package"
|
||||
;;
|
||||
"zypper")
|
||||
sudo zypper install -y "$package"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
install_cask() {
|
||||
local app=$1
|
||||
log "Installing $app..."
|
||||
|
||||
case $PACKAGE_MANAGER in
|
||||
"brew")
|
||||
brew install --cask "$app"
|
||||
;;
|
||||
"pacman")
|
||||
# This shouldn't be called for Arch anymore since we use yay directly
|
||||
warn "Arch Linux packages should be installed via yay, not individual pacman calls"
|
||||
;;
|
||||
"apt")
|
||||
case $app in
|
||||
"brave-browser")
|
||||
# Add Brave repository
|
||||
curl -fsSLo /usr/share/keyrings/brave-browser-archive-keyring.gpg https://brave-browser-apt-release.s3.brave.com/brave-browser-archive-keyring.gpg
|
||||
echo "deb [signed-by=/usr/share/keyrings/brave-browser-archive-keyring.gpg arch=amd64] https://brave-browser-apt-release.s3.brave.com/ stable main" | sudo tee /etc/apt/sources.list.d/brave-browser-release.list
|
||||
sudo apt update
|
||||
sudo apt install -y brave-browser
|
||||
;;
|
||||
"postman")
|
||||
warn "Install Postman via Snap: sudo snap install postman"
|
||||
;;
|
||||
"1password")
|
||||
# Add 1Password repository
|
||||
curl -sS https://downloads.1password.com/linux/keys/1password.asc | sudo gpg --dearmor --output /usr/share/keyrings/1password-archive-keyring.gpg
|
||||
echo 'deb [arch=amd64 signed-by=/usr/share/keyrings/1password-archive-keyring.gpg] https://downloads.1password.com/linux/debian/amd64 stable main' | sudo tee /etc/apt/sources.list.d/1password.list
|
||||
sudo apt update
|
||||
sudo apt install -y 1password
|
||||
;;
|
||||
"parsec")
|
||||
warn "Download Parsec manually from parseapp.com"
|
||||
;;
|
||||
"ghostty")
|
||||
warn "Ghostty needs manual installation or Flatpak"
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
"dnf"|"yum")
|
||||
case $app in
|
||||
"brave-browser")
|
||||
sudo dnf config-manager --add-repo https://brave-browser-rpm-release.s3.brave.com/x86_64/
|
||||
sudo rpm --import https://brave-browser-rpm-release.s3.brave.com/brave-core.asc
|
||||
sudo dnf install -y brave-browser
|
||||
;;
|
||||
*)
|
||||
warn "Install $app via Flatpak: flatpak install $app"
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
*)
|
||||
warn "GUI app installation for $app not implemented for $PACKAGE_MANAGER"
|
||||
warn "Consider using Flatpak: flatpak install $app"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
header() {
|
||||
echo -e "${BLUE}
|
||||
╔════════════════════════════════════╗
|
||||
║ Complete Development Setup ║
|
||||
║ Cross-Platform Tool Installer ║
|
||||
╚════════════════════════════════════╝${NC}"
|
||||
}
|
||||
|
||||
check_prerequisites() {
|
||||
log "Checking prerequisites..."
|
||||
|
||||
detect_os
|
||||
install_package_manager
|
||||
|
||||
# Check dotfiles directory
|
||||
if [ ! -d "$DOTFILES_DIR" ]; then
|
||||
error "Dotfiles directory not found: $DOTFILES_DIR"
|
||||
log "Please ensure your dotfiles are at: $DOTFILES_DIR"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
backup_configs() {
|
||||
log "Creating backup..."
|
||||
mkdir -p "$BACKUP_DIR"
|
||||
|
||||
# Backup existing configs
|
||||
[ -d ~/.config/fish ] && cp -r ~/.config/fish "$BACKUP_DIR/"
|
||||
[ -f ~/.zshrc ] && cp ~/.zshrc "$BACKUP_DIR/"
|
||||
[ -d ~/.config/ghostty ] && cp -r ~/.config/ghostty "$BACKUP_DIR/"
|
||||
[ -d ~/.config/neofetch ] && cp -r ~/.config/neofetch "$BACKUP_DIR/"
|
||||
[ -f ~/.config/starship.toml ] && cp ~/.config/starship.toml "$BACKUP_DIR/"
|
||||
|
||||
log "Backup created: $BACKUP_DIR"
|
||||
}
|
||||
|
||||
install_tools() {
|
||||
log "Installing development tools..."
|
||||
|
||||
# Core tools - OS specific package names
|
||||
case $OS in
|
||||
"macos")
|
||||
# Command line tools
|
||||
install_package starship
|
||||
install_package neofetch
|
||||
install_package btop
|
||||
install_package git
|
||||
install_package fzf
|
||||
install_package ripgrep
|
||||
install_package fd
|
||||
install_package bat
|
||||
install_package go
|
||||
install_package python3
|
||||
install_package node
|
||||
install_package syncthing
|
||||
install_package tailscale
|
||||
install_package vim
|
||||
|
||||
# GUI Applications
|
||||
install_cask parsec
|
||||
install_cask postman
|
||||
install_cask 1password
|
||||
install_cask brave-browser
|
||||
install_cask ghostty
|
||||
;;
|
||||
"arch")
|
||||
# Check if yay is installed, install if not
|
||||
if ! command -v yay &> /dev/null; then
|
||||
log "Installing yay AUR helper..."
|
||||
sudo pacman -S --needed base-devel git
|
||||
git clone https://aur.archlinux.org/yay.git /tmp/yay
|
||||
cd /tmp/yay && makepkg -si --noconfirm
|
||||
cd - && rm -rf /tmp/yay
|
||||
fi
|
||||
|
||||
# Install everything via yay (handles both official repos + AUR)
|
||||
log "Installing all packages via yay..."
|
||||
yay -S --noconfirm \
|
||||
starship \
|
||||
neofetch \
|
||||
btop \
|
||||
git \
|
||||
fzf \
|
||||
ripgrep \
|
||||
fd \
|
||||
bat \
|
||||
go \
|
||||
python \
|
||||
nodejs \
|
||||
npm \
|
||||
syncthing \
|
||||
tailscale \
|
||||
vim \
|
||||
parsec \
|
||||
postman-bin \
|
||||
1password \
|
||||
brave-bin \
|
||||
ghostty
|
||||
;;
|
||||
"debian")
|
||||
# Command line tools
|
||||
install_package git
|
||||
install_package fzf
|
||||
install_package ripgrep
|
||||
install_package fd-find
|
||||
install_package bat
|
||||
install_package golang-go
|
||||
install_package python3
|
||||
install_package nodejs
|
||||
install_package npm
|
||||
install_package syncthing
|
||||
install_package vim
|
||||
|
||||
# Install starship manually
|
||||
curl -sS https://starship.rs/install.sh | sh
|
||||
install_package neofetch
|
||||
|
||||
# Tailscale
|
||||
curl -fsSL https://tailscale.com/install.sh | sh
|
||||
|
||||
warn "GUI applications need manual installation on Debian/Ubuntu:"
|
||||
warn "- Parsec, Postman, 1Password, Brave Browser"
|
||||
warn "- btop may need manual installation on older versions"
|
||||
;;
|
||||
"fedora"|"rhel")
|
||||
# Command line tools
|
||||
install_package git
|
||||
install_package fzf
|
||||
install_package ripgrep
|
||||
install_package fd-find
|
||||
install_package bat
|
||||
install_package golang
|
||||
install_package python3
|
||||
install_package nodejs
|
||||
install_package npm
|
||||
install_package syncthing
|
||||
install_package vim
|
||||
|
||||
# Install starship manually
|
||||
curl -sS https://starship.rs/install.sh | sh
|
||||
install_package neofetch
|
||||
|
||||
# Tailscale
|
||||
curl -fsSL https://tailscale.com/install.sh | sh
|
||||
|
||||
warn "GUI applications available via Flatpak or manual installation"
|
||||
;;
|
||||
"opensuse")
|
||||
# Command line tools
|
||||
install_package git
|
||||
install_package fzf
|
||||
install_package ripgrep
|
||||
install_package fd
|
||||
install_package bat
|
||||
install_package go
|
||||
install_package python3
|
||||
install_package nodejs
|
||||
install_package npm
|
||||
install_package syncthing
|
||||
install_package vim
|
||||
|
||||
# Install starship manually
|
||||
curl -sS https://starship.rs/install.sh | sh
|
||||
install_package neofetch
|
||||
|
||||
# Tailscale
|
||||
curl -fsSL https://tailscale.com/install.sh | sh
|
||||
|
||||
warn "GUI applications may need manual installation"
|
||||
;;
|
||||
esac
|
||||
|
||||
# Setup vim and other tools
|
||||
setup_vim
|
||||
install_node_tools
|
||||
|
||||
log "Tools installation complete!"
|
||||
|
||||
# Show post-installation notes
|
||||
show_post_install_notes
|
||||
}
|
||||
|
||||
show_post_install_notes() {
|
||||
case $OS in
|
||||
"macos"|"arch")
|
||||
log "All tools installed successfully!"
|
||||
;;
|
||||
"debian"|"fedora"|"rhel"|"opensuse")
|
||||
warn "Additional GUI apps can be installed via:"
|
||||
warn "• Flatpak: flatpak install brave postman"
|
||||
warn "• Snap: snap install brave postman"
|
||||
warn "• Manual downloads from official websites"
|
||||
warn "• AppImage versions where available"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
install_node_tools() {
|
||||
log "Installing Node.js tools..."
|
||||
|
||||
# Ensure npm is available
|
||||
if command -v npm &> /dev/null; then
|
||||
npm install -g @playwright/test
|
||||
npx playwright install
|
||||
else
|
||||
warn "npm not found, skipping Playwright installation"
|
||||
fi
|
||||
}
|
||||
|
||||
setup_vim() {
|
||||
log "Setting up Kickstart Vim..."
|
||||
|
||||
# Backup existing .vimrc
|
||||
[ -f ~/.vimrc ] && mv ~/.vimrc ~/.vimrc.backup.$(date +%Y%m%d-%H%M%S)
|
||||
|
||||
# Clone or update kickstart.vim
|
||||
if [ -d ~/kickstart.vim ]; then
|
||||
cd ~/kickstart.vim && git pull
|
||||
else
|
||||
git clone https://github.com/theopn/kickstart.vim.git ~/kickstart.vim
|
||||
fi
|
||||
|
||||
# Create symlink
|
||||
ln -sf ~/kickstart.vim/.vimrc ~/.vimrc
|
||||
|
||||
# Install plugins
|
||||
vim +PlugInstall +qa
|
||||
}
|
||||
|
||||
setup_dotfiles_symlinks() {
|
||||
log "Creating dotfiles symlinks..."
|
||||
|
||||
# Remove existing configs
|
||||
rm -rf ~/.config/neofetch ~/.config/btop
|
||||
rm -f ~/.config/starship.toml
|
||||
|
||||
# Create symlinks to dotfiles - common configs
|
||||
ln -sf "$DOTFILES_DIR/neofetch" ~/.config/neofetch
|
||||
ln -sf "$DOTFILES_DIR/terminal/starship.toml" ~/.config/starship.toml
|
||||
|
||||
# Ghostty (only if directory exists in dotfiles)
|
||||
if [ -d "$DOTFILES_DIR/terminal/ghostty" ]; then
|
||||
rm -rf ~/.config/ghostty
|
||||
ln -sf "$DOTFILES_DIR/terminal/ghostty" ~/.config/ghostty
|
||||
fi
|
||||
|
||||
# Btop config
|
||||
mkdir -p ~/.config/btop
|
||||
if [ -f "$DOTFILES_DIR/btop/btop.conf" ]; then
|
||||
ln -sf "$DOTFILES_DIR/btop/btop.conf" ~/.config/btop/btop.conf
|
||||
fi
|
||||
if [ -d "$DOTFILES_DIR/btop/themes" ]; then
|
||||
ln -sf "$DOTFILES_DIR/btop/themes" ~/.config/btop/themes
|
||||
fi
|
||||
|
||||
log "Dotfiles symlinks created!"
|
||||
}
|
||||
|
||||
setup_auto_updates() {
|
||||
log "Setting up automatic system updates..."
|
||||
|
||||
# Create update script
|
||||
local update_script="$HOME/.local/bin/update-system.sh"
|
||||
mkdir -p "$(dirname "$update_script")"
|
||||
:
|
||||
# Copy the update script content (same as before)
|
||||
cat > "$update_script" << 'EOF'
|
||||
#!/bin/bash
|
||||
|
||||
# System Update Script
|
||||
# Updates all packages, dotfiles, and development tools
|
||||
|
||||
DOTFILES_DIR="$HOME/git/dotfiles"
|
||||
LOG_FILE="$HOME/.local/share/system-updates.log"
|
||||
LAST_UPDATE_FILE="$HOME/.local/share/last-system-update"
|
||||
DATE=$(date '+%Y-%m-%d %H:%M:%S')
|
||||
|
||||
# Colors for output
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
RED='\033[0;31m'
|
||||
NC='\033[0m'
|
||||
|
||||
log() {
|
||||
echo -e "${GREEN}[INFO]${NC} $1"
|
||||
echo "[$DATE] INFO: $1" >> "$LOG_FILE"
|
||||
}
|
||||
|
||||
warn() {
|
||||
echo -e "${YELLOW}[WARN]${NC} $1"
|
||||
echo "[$DATE] WARN: $1" >> "$LOG_FILE"
|
||||
}
|
||||
|
||||
error() {
|
||||
echo -e "${RED}[ERROR]${NC} $1"
|
||||
echo "[$DATE] ERROR: $1" >> "$LOG_FILE"
|
||||
}
|
||||
|
||||
detect_os() {
|
||||
if [[ "$OSTYPE" == "darwin"* ]]; then
|
||||
OS="macos"
|
||||
PACKAGE_MANAGER="brew"
|
||||
elif [[ -f /etc/arch-release ]]; then
|
||||
OS="arch"
|
||||
PACKAGE_MANAGER="yay"
|
||||
elif [[ -f /etc/debian_version ]]; then
|
||||
OS="debian"
|
||||
PACKAGE_MANAGER="apt"
|
||||
elif [[ -f /etc/fedora-release ]]; then
|
||||
OS="fedora"
|
||||
PACKAGE_MANAGER="dnf"
|
||||
elif [[ -f /etc/redhat-release ]]; then
|
||||
OS="rhel"
|
||||
PACKAGE_MANAGER="yum"
|
||||
else
|
||||
OS="unknown"
|
||||
PACKAGE_MANAGER="unknown"
|
||||
fi
|
||||
}
|
||||
|
||||
is_update_needed() {
|
||||
if [ ! -f "$LAST_UPDATE_FILE" ]; then
|
||||
return 0 # No previous update, run it
|
||||
fi
|
||||
|
||||
local last_update=$(cat "$LAST_UPDATE_FILE" 2>/dev/null || echo "0")
|
||||
local current_date=$(date +%s)
|
||||
local days_since_update=$(( (current_date - last_update) / 86400 ))
|
||||
|
||||
if [ $days_since_update -ge 30 ]; then
|
||||
log "Last update was $days_since_update days ago, running update..."
|
||||
return 0
|
||||
else
|
||||
log "Last update was $days_since_update days ago, skipping..."
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
update_system_packages() {
|
||||
log "Updating system packages ($OS)..."
|
||||
|
||||
case $PACKAGE_MANAGER in
|
||||
"brew")
|
||||
brew update
|
||||
brew upgrade
|
||||
brew cleanup
|
||||
;;
|
||||
"yay")
|
||||
yay -Syu --noconfirm
|
||||
yay -Yc --noconfirm
|
||||
;;
|
||||
"apt")
|
||||
sudo apt update
|
||||
sudo apt upgrade -y
|
||||
sudo apt autoremove -y
|
||||
sudo apt autoclean
|
||||
;;
|
||||
"dnf")
|
||||
sudo dnf upgrade -y
|
||||
sudo dnf autoremove -y
|
||||
;;
|
||||
"yum")
|
||||
sudo yum update -y
|
||||
sudo yum clean all
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
update_dotfiles() {
|
||||
log "Updating dotfiles..."
|
||||
|
||||
if [ -d "$DOTFILES_DIR/.git" ]; then
|
||||
cd "$DOTFILES_DIR"
|
||||
git fetch origin
|
||||
LOCAL=$(git rev-parse @)
|
||||
REMOTE=$(git rev-parse @{u})
|
||||
|
||||
if [ "$LOCAL" != "$REMOTE" ]; then
|
||||
git pull origin main || git pull origin master
|
||||
log "Dotfiles updated"
|
||||
else
|
||||
log "Dotfiles up to date"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
update_vim_plugins() {
|
||||
if [ -f "$HOME/.vimrc" ] && command -v vim &> /dev/null; then
|
||||
vim +PlugUpdate +PlugClean! +qa
|
||||
log "Vim plugins updated"
|
||||
fi
|
||||
}
|
||||
|
||||
update_node_packages() {
|
||||
if command -v npm &> /dev/null; then
|
||||
npm update -g
|
||||
log "npm packages updated"
|
||||
fi
|
||||
|
||||
if command -v npx &> /dev/null; then
|
||||
npx playwright install 2>/dev/null || true
|
||||
fi
|
||||
}
|
||||
|
||||
mark_update_completed() {
|
||||
date +%s > "$LAST_UPDATE_FILE"
|
||||
log "Update timestamp saved"
|
||||
}
|
||||
|
||||
main() {
|
||||
mkdir -p "$(dirname "$LOG_FILE")"
|
||||
mkdir -p "$(dirname "$LAST_UPDATE_FILE")"
|
||||
|
||||
# Check if running with --force flag
|
||||
if [[ "$1" == "--force" ]] || is_update_needed; then
|
||||
echo "[$DATE] Starting system update..." >> "$LOG_FILE"
|
||||
|
||||
detect_os
|
||||
log "Starting update process..."
|
||||
|
||||
update_system_packages
|
||||
update_dotfiles
|
||||
update_vim_plugins
|
||||
update_node_packages
|
||||
|
||||
mark_update_completed
|
||||
log "Update completed!"
|
||||
echo "[$DATE] Update completed" >> "$LOG_FILE"
|
||||
fi
|
||||
}
|
||||
|
||||
main "$@"
|
||||
EOF
|
||||
|
||||
chmod +x "$update_script"
|
||||
|
||||
# Create startup check script
|
||||
create_startup_check "$update_script"
|
||||
|
||||
# Setup traditional cron job (for always-on systems)
|
||||
setup_cron_job "$update_script"
|
||||
|
||||
# Setup system-specific startup methods
|
||||
setup_startup_updates "$update_script"
|
||||
|
||||
log "Auto-update system configured!"
|
||||
log "Updates will run:"
|
||||
log "• Monthly on 1st at 2:00 AM (if system is on)"
|
||||
log "• At startup if update is overdue (30+ days)"
|
||||
log "• Manual: $update_script --force"
|
||||
log "View logs: tail -f ~/.local/share/system-updates.log"
|
||||
}
|
||||
|
||||
create_startup_check() {
|
||||
local update_script="$1"
|
||||
local startup_check="$HOME/.local/bin/check-updates-on-startup.sh"
|
||||
|
||||
cat > "$startup_check" << EOF
|
||||
#!/bin/bash
|
||||
# Check for overdue updates on startup (runs max once per day)
|
||||
|
||||
DAILY_CHECK_FILE="\$HOME/.local/share/daily-update-check"
|
||||
TODAY=\$(date +%Y-%m-%d)
|
||||
|
||||
# Only run once per day
|
||||
if [ -f "\$DAILY_CHECK_FILE" ] && [ "\$(cat "\$DAILY_CHECK_FILE" 2>/dev/null)" = "\$TODAY" ]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Mark today as checked
|
||||
echo "\$TODAY" > "\$DAILY_CHECK_FILE"
|
||||
|
||||
# Run update check in background (non-blocking)
|
||||
nohup "$update_script" > /dev/null 2>&1 &
|
||||
EOF
|
||||
|
||||
chmod +x "$startup_check"
|
||||
return "$startup_check"
|
||||
}
|
||||
|
||||
setup_startup_updates() {
|
||||
local update_script="$1"
|
||||
local startup_check="$HOME/.local/bin/check-updates-on-startup.sh"
|
||||
|
||||
case $OS in
|
||||
"macos")
|
||||
setup_macos_startup "$startup_check"
|
||||
;;
|
||||
"arch"|"debian"|"fedora"|"rhel")
|
||||
setup_linux_startup "$startup_check"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
setup_macos_startup() {
|
||||
local startup_check="$1"
|
||||
local plist_file="$HOME/Library/LaunchAgents/com.user.system-updates.plist"
|
||||
|
||||
log "Setting up macOS LaunchAgent for startup updates..."
|
||||
|
||||
mkdir -p "$HOME/Library/LaunchAgents"
|
||||
|
||||
cat > "$plist_file" << EOF
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>Label</key>
|
||||
<string>com.user.system-updates</string>
|
||||
<key>ProgramArguments</key>
|
||||
<array>
|
||||
<string>$startup_check</string>
|
||||
</array>
|
||||
<key>RunAtLoad</key>
|
||||
<true/>
|
||||
<key>StandardOutPath</key>
|
||||
<string>$HOME/.local/share/startup-updates.log</string>
|
||||
<key>StandardErrorPath</key>
|
||||
<string>$HOME/.local/share/startup-updates-error.log</string>
|
||||
</dict>
|
||||
</plist>
|
||||
EOF
|
||||
|
||||
# Load the LaunchAgent
|
||||
launchctl load "$plist_file" 2>/dev/null || warn "LaunchAgent setup may need manual activation"
|
||||
log "macOS startup updates configured"
|
||||
}
|
||||
|
||||
setup_linux_startup() {
|
||||
local startup_check="$1"
|
||||
|
||||
# Try systemd user service first
|
||||
if command -v systemctl &> /dev/null; then
|
||||
setup_systemd_user_service "$startup_check"
|
||||
else
|
||||
# Fallback to shell profile
|
||||
setup_shell_profile_check "$startup_check"
|
||||
fi
|
||||
}
|
||||
|
||||
setup_systemd_user_service() {
|
||||
local startup_check="$1"
|
||||
local service_dir="$HOME/.config/systemd/user"
|
||||
|
||||
log "Setting up systemd user service for startup updates..."
|
||||
|
||||
mkdir -p "$service_dir"
|
||||
|
||||
# Create service file
|
||||
cat > "$service_dir/system-updates.service" << EOF
|
||||
[Unit]
|
||||
Description=System Updates Check
|
||||
After=network-online.target
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=$startup_check
|
||||
StandardOutput=append:$HOME/.local/share/startup-updates.log
|
||||
StandardError=append:$HOME/.local/share/startup-updates-error.log
|
||||
|
||||
[Install]
|
||||
WantedBy=default.target
|
||||
EOF
|
||||
|
||||
# Enable the service
|
||||
systemctl --user daemon-reload
|
||||
systemctl --user enable system-updates.service
|
||||
|
||||
log "systemd user service configured"
|
||||
}
|
||||
|
||||
setup_shell_profile_check() {
|
||||
local startup_check="$1"
|
||||
|
||||
log "Adding startup update check to shell profiles..."
|
||||
|
||||
# Add to shell profiles (as fallback)
|
||||
local check_line="# Auto-update check (once per day)
|
||||
if [ -f \"$startup_check\" ]; then
|
||||
\"$startup_check\" &
|
||||
fi"
|
||||
|
||||
# Add to profiles that exist
|
||||
for profile in ~/.profile ~/.bash_profile ~/.zprofile; do
|
||||
if [ -f "$profile" ]; then
|
||||
if ! grep -q "check-updates-on-startup" "$profile"; then
|
||||
echo "$check_line" >> "$profile"
|
||||
log "Added to $profile"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
setup_cron_job() {
|
||||
local script_path="$1"
|
||||
|
||||
log "Setting up monthly cron job..."
|
||||
|
||||
# Create cron job entry
|
||||
local cron_job="0 2 1 * * $script_path >> ~/.local/share/cron-updates.log 2>&1"
|
||||
|
||||
# Add to crontab if not already present
|
||||
(crontab -l 2>/dev/null | grep -v "$script_path"; echo "$cron_job") | crontab -
|
||||
|
||||
log "Cron job installed: Monthly updates on 1st at 2:00 AM"
|
||||
|
||||
# Show current crontab
|
||||
log "Current cron jobs:"
|
||||
crontab -l | grep -v "^#" || warn "No cron jobs found"
|
||||
}
|
||||
|
||||
setup_fish() {
|
||||
log "Setting up Fish shell..."
|
||||
|
||||
# Install Fish
|
||||
install_package fish
|
||||
|
||||
# Install Fisher (Fish plugin manager)
|
||||
if ! command -v fisher &> /dev/null; then
|
||||
fish -c "curl -sL https://git.io/fisher | source && fisher install jorgebucaran/fisher"
|
||||
fi
|
||||
|
||||
# Remove existing fish config
|
||||
rm -rf ~/.config/fish
|
||||
|
||||
# Create symlink to dotfiles
|
||||
ln -sf "$DOTFILES_DIR/shells/fish" ~/.config/fish
|
||||
|
||||
# Install Fish plugins
|
||||
log "Installing Fish plugins..."
|
||||
fish -c "fisher install jorgebucaran/nvm.fish"
|
||||
fish -c "fisher install PatrickF1/fzf.fish"
|
||||
fish -c "fisher install franciscolourenco/done"
|
||||
|
||||
# Install Node.js via NVM (if available)
|
||||
if command -v fish &> /dev/null; then
|
||||
fish -c "nvm install latest && nvm use latest" || warn "NVM setup failed, Node.js should be available via system package"
|
||||
fi
|
||||
|
||||
# Set as default shell
|
||||
local fish_path=$(which fish)
|
||||
if ! grep -q "$fish_path" /etc/shells; then
|
||||
echo "$fish_path" | sudo tee -a /etc/shells
|
||||
fi
|
||||
chsh -s "$fish_path"
|
||||
|
||||
log "Fish shell configured!"
|
||||
}
|
||||
|
||||
setup_zsh() {
|
||||
log "Setting up Zsh shell..."
|
||||
|
||||
# Install Zsh
|
||||
install_package zsh
|
||||
|
||||
# Remove existing configs
|
||||
rm -rf ~/.zshrc ~/.oh-my-zsh
|
||||
|
||||
# Install Oh My Zsh
|
||||
RUNZSH=no sh -c "$(curl -fsSL https://raw.github.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"
|
||||
|
||||
# Install NVM for Zsh (cross-platform)
|
||||
if [ ! -d "$HOME/.nvm" ]; then
|
||||
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash
|
||||
fi
|
||||
|
||||
# Create symlink to dotfiles
|
||||
ln -sf "$DOTFILES_DIR/shells/zsh/.zshrc" ~/.zshrc
|
||||
|
||||
# Install Node.js via NVM
|
||||
export NVM_DIR="$HOME/.nvm"
|
||||
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
|
||||
if command -v nvm &> /dev/null; then
|
||||
nvm install node && nvm use node
|
||||
else
|
||||
warn "NVM setup failed, using system Node.js"
|
||||
fi
|
||||
|
||||
# Set as default shell
|
||||
local zsh_path=$(which zsh)
|
||||
if ! grep -q "$zsh_path" /etc/shells; then
|
||||
echo "$zsh_path" | sudo tee -a /etc/shells
|
||||
fi
|
||||
chsh -s "$zsh_path"
|
||||
|
||||
log "Zsh shell configured!"
|
||||
}
|
||||
|
||||
show_menu() {
|
||||
echo -e "${BLUE}
|
||||
Select your shell setup:
|
||||
|
||||
1) Fish Shell
|
||||
- Modern auto-completion
|
||||
- Clean configuration
|
||||
- User-friendly syntax
|
||||
|
||||
2) Zsh Shell
|
||||
- POSIX compatible
|
||||
- Oh-My-Zsh framework
|
||||
- Traditional Unix shell
|
||||
|
||||
Detected OS: $OS ($PACKAGE_MANAGER)
|
||||
|
||||
Tools to be installed:
|
||||
• Development: Go, Python, Node.js, Git, Vim
|
||||
• Terminal: Starship, Neofetch, btop, fzf, ripgrep, fd, bat
|
||||
• Networking: Syncthing, Tailscale
|
||||
• Applications: Parsec, Postman, 1Password, Brave Browser
|
||||
• Testing: Playwright framework
|
||||
|
||||
${NC}"
|
||||
read -p "Choose (1-2): " choice
|
||||
}
|
||||
|
||||
main() {
|
||||
header
|
||||
check_prerequisites
|
||||
backup_configs
|
||||
install_tools
|
||||
setup_dotfiles_symlinks
|
||||
setup_auto_updates
|
||||
|
||||
show_menu
|
||||
|
||||
case $choice in
|
||||
1)
|
||||
setup_fish
|
||||
log "Fish setup complete! Restart your terminal."
|
||||
;;
|
||||
2)
|
||||
setup_zsh
|
||||
log "Zsh setup complete! Restart your terminal."
|
||||
;;
|
||||
*)
|
||||
error "Invalid choice. Exiting."
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
echo -e "${GREEN}
|
||||
╔══════════════════════════════════════════════════════════╗
|
||||
║ Setup Complete! ║
|
||||
║ ║
|
||||
║ ✓ $OS system detected ║
|
||||
║ ✓ Development tools installed ║
|
||||
║ ✓ Dotfiles symlinked ║
|
||||
║ ✓ Shell configured ║
|
||||
║ ✓ Smart auto-updates enabled ║
|
||||
║ ║
|
||||
║ Updates run automatically: ║
|
||||
║ • Monthly (1st at 2 AM) if system is on ║
|
||||
║ • At startup if overdue (30+ days) ║
|
||||
║ • Max once per day (non-blocking) ║
|
||||
║ ║
|
||||
║ Manual commands: ║
|
||||
║ • Force update: ~/.local/bin/update-system.sh --force ║
|
||||
║ • View logs: tail -f ~/.local/share/system-updates.log ║
|
||||
║ ║
|
||||
║ Perfect for laptops and desktops! ║
|
||||
║ ║
|
||||
║ Restart terminal to see changes! ║
|
||||
║ ║
|
||||
║ Backup: $BACKUP_DIR ║
|
||||
╚══════════════════════════════════════════════════════════╝${NC}"
|
||||
}
|
||||
|
||||
main "$@"
|
||||
Reference in New Issue
Block a user