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