diff --git a/README.md b/README.md index 01dee29..5db55be 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,62 @@ # Ryan's Dotfiles -Minimal Bash dotfiles for SSH and remote environments. +A comprehensive dotfiles repository for SSH, remote environments, and development setups. + +## Structure + +``` +~/.dotfiles/ +├── stow/ # Configs organized for GNU Stow +│ ├── bash/ # Bash configuration (.bashrc, .bash_aliases, .inputrc) +│ ├── git/ # Git configuration (.gitconfig) +│ └── [other configs] # Additional configurations as needed +├── packages/ +│ ├── base.txt # MUST HAVE - Core system utilities +│ ├── cli-tools.txt # Nice-to-haves - Enhanced CLI tools +│ ├── dev.txt # Development tools (docker, node, etc) +│ └── gui.txt # Desktop applications +├── install.sh # Bootstrap script with package management +└── README.md # Documentation +``` ## Install ```bash bash <(curl -sL https://ryans.tools/dotfiles) +``` + +The installer will: + +1. Clone this repository to `~/.dotfiles` +2. Prompt you to choose which package sets to install +3. Backup any existing conflicting files +4. Use GNU Stow to symlink configurations +5. Set up bash aliases including the `dotpull` update alias + +## Package Categories + +- **Base**: Essential system utilities (curl, git, stow, vim, etc.) +- **CLI Tools**: Enhanced command-line tools (bat, fzf, ripgrep, etc.) +- **Development**: Programming languages and dev tools (nodejs, python, docker, etc.) +- **GUI**: Desktop applications (firefox, code, vlc, etc.) + +## Updating + +After initial installation, use the `dotpull` alias to update your dotfiles: + +```bash +dotpull +``` + +This alias will pull the latest changes and re-stow all configurations. + +## Manual Management + +To manage individual configurations: + +```bash +cd ~/.dotfiles/stow +stow -t ~ bash # Link bash config +stow -t ~ git # Link git config +stow -D bash # Unlink bash config +``` diff --git a/install.sh b/install.sh index 2da1367..c4a2832 100644 --- a/install.sh +++ b/install.sh @@ -4,6 +4,50 @@ set -euo pipefail DOTFILES_REPO="https://gitea.purpleraft.com/ryan/dotfiles" DOTFILES_DIR="$HOME/.dotfiles" +# Function to install packages from a file +install_packages() { + local package_file="$1" + local description="$2" + + if [ -f "$package_file" ]; then + echo "📦 Installing $description..." + + # Read packages into array, skipping comments and empty lines + packages=() + while IFS= read -r line; do + # Skip comments and empty lines + [[ "$line" =~ ^[[:space:]]*# ]] && continue + [[ -z "${line// }" ]] && continue + packages+=("$line") + done < "$package_file" + + if [ ${#packages[@]} -eq 0 ]; then + echo " No packages found in $package_file" + return + fi + + # Detect package manager and install packages + if command -v apt &> /dev/null; then + # Debian/Ubuntu + sudo apt update && sudo apt install -y "${packages[@]}" + elif command -v yum &> /dev/null; then + # RHEL/CentOS + sudo yum install -y "${packages[@]}" + elif command -v dnf &> /dev/null; then + # Fedora + sudo dnf install -y "${packages[@]}" + elif command -v pacman &> /dev/null; then + # Arch Linux + sudo pacman -S --noconfirm "${packages[@]}" + elif command -v brew &> /dev/null; then + # macOS + brew install "${packages[@]}" + else + echo "⚠️ No supported package manager found. Please install packages manually from $package_file" + fi + fi +} + # Check if stow is installed if ! command -v stow &> /dev/null; then echo "❌ GNU Stow is not installed. Please install it first:" @@ -15,33 +59,81 @@ fi # Clone or update the repo if [ -d "$DOTFILES_DIR/.git" ]; then - echo "Updating existing dotfiles repo..." + echo "🔄 Updating existing dotfiles repo..." git -C "$DOTFILES_DIR" pull --quiet else - echo "Cloning dotfiles into $DOTFILES_DIR..." + echo "📥 Cloning dotfiles into $DOTFILES_DIR..." git clone "$DOTFILES_REPO" "$DOTFILES_DIR" 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 +cd "$DOTFILES_DIR" + +# Install packages (with user confirmation) +echo "" +echo "Package installation options:" +echo "1. Base packages (MUST HAVE) - curl, git, stow, vim, etc." +echo "2. CLI tools (Nice-to-haves) - bat, fzf, ripgrep, etc." +echo "3. Development tools - nodejs, python, docker, etc." +echo "4. GUI applications - firefox, code, vlc, etc." +echo "5. Skip package installation" +echo "" + +read -p "Choose packages to install (1-5, or comma-separated like 1,2): " package_choice + +# Install selected packages +if [[ "$package_choice" == *"1"* ]]; then + install_packages "packages/base.txt" "base packages" +fi +if [[ "$package_choice" == *"2"* ]]; then + install_packages "packages/cli-tools.txt" "CLI tools" +fi +if [[ "$package_choice" == *"3"* ]]; then + install_packages "packages/dev.txt" "development tools" +fi +if [[ "$package_choice" == *"4"* ]]; then + install_packages "packages/gui.txt" "GUI applications" +fi + +# Backup existing files that would conflict with stow +echo "" +echo "🔗 Setting up dotfile symlinks..." +for config_dir in stow/*/; do + if [ -d "$config_dir" ]; then + config_name=$(basename "$config_dir") + echo " Checking for conflicts with $config_name config..." + + # Find all files that would be stowed and backup if they exist + find "$config_dir" -type f | while read -r file; do + relative_file="${file#$config_dir}" + target_file="$HOME/$relative_file" + + if [ -f "$target_file" ] && [ ! -L "$target_file" ]; then + echo " ⚠️ Backing up existing file: $target_file -> ${target_file}.bak" + mv "$target_file" "${target_file}.bak" + fi + done + fi done -# Change to dotfiles directory and use stow to create symlinks -cd "$DOTFILES_DIR" -echo "🔗 Using Stow to symlink dotfiles..." -if ! stow --adopt -t "$HOME" . 2>/dev/null; then - echo "🔄 Adopting failed, trying regular stow..." - stow -t "$HOME" . -fi +# Use stow to create symlinks for each configuration +cd stow +for config_dir in */; do + if [ -d "$config_dir" ]; then + config_name=$(basename "$config_dir") + echo " 🔗 Stowing $config_name configuration..." + if ! stow -t "$HOME" "$config_name" 2>/dev/null; then + echo " ⚠️ Stow failed for $config_name, trying with --adopt..." + stow --adopt -t "$HOME" "$config_name" + fi + fi +done # Optionally source the new bashrc -if [[ $- == *i* ]]; then - echo "Reloading Bash config..." - source ~/.bashrc +if [[ $- == *i* ]] && [ -f "$HOME/.bashrc" ]; then + echo "🔄 Reloading Bash config..." + source ~/.bashrc fi -echo "✅ Dotfiles install complete." +echo "" +echo "✅ Dotfiles install complete!" +echo "💡 Use 'dotpull' alias to update your dotfiles in the future." diff --git a/packages/base.txt b/packages/base.txt new file mode 100644 index 0000000..8131853 --- /dev/null +++ b/packages/base.txt @@ -0,0 +1,13 @@ +# Base packages - MUST HAVE +# Core system utilities +curl +wget +git +stow +vim +nano +bash-completion +tree +htop +unzip +zip diff --git a/packages/cli-tools.txt b/packages/cli-tools.txt new file mode 100644 index 0000000..1b3f2c0 --- /dev/null +++ b/packages/cli-tools.txt @@ -0,0 +1,11 @@ +# CLI Tools - Nice-to-haves +# Enhanced command line tools +bat +fd-find +ripgrep +fzf +tmux +screen +jq +ncdu +exa diff --git a/packages/dev.txt b/packages/dev.txt new file mode 100644 index 0000000..d70da8a --- /dev/null +++ b/packages/dev.txt @@ -0,0 +1,15 @@ +# Development Tools +# Programming languages and tools +nodejs +npm +python3 +python3-pip +docker +docker-compose +build-essential +make +gcc +g++ +golang-go +rust +cargo diff --git a/packages/gui.txt b/packages/gui.txt new file mode 100644 index 0000000..ad45e98 --- /dev/null +++ b/packages/gui.txt @@ -0,0 +1,10 @@ +# GUI Applications +# Desktop applications (for systems with GUI) +firefox +code +vlc +gimp +thunderbird +libreoffice +chromium-browser +terminator diff --git a/.bash_aliases b/stow/bash/.bash_aliases similarity index 86% rename from .bash_aliases rename to stow/bash/.bash_aliases index 1165872..7d11949 100644 --- a/.bash_aliases +++ b/stow/bash/.bash_aliases @@ -7,7 +7,7 @@ alias h='history' alias grep='grep --color=auto' alias d='docker' alias dc='docker compose' -alias dotpull='echo "🔄 Updating dotfiles..." && git -C ~/.dotfiles pull && echo "🔗 Re-stowing dotfiles..." && (cd ~/.dotfiles && stow --adopt -t ~ . 2>/dev/null || stow -t ~ .) && echo "✅ Done."' +alias dotpull='echo "🔄 Updating dotfiles..." && git -C ~/.dotfiles pull && echo "🔗 Re-stowing dotfiles..." && (cd ~/.dotfiles/stow && for dir in */; do if [ -d "$dir" ]; then echo " Stowing $dir..." && stow -R -t ~ "$dir" || echo " ⚠️ Failed to stow $dir"; fi; done) && echo "✅ Done."' alias reloadbash='source ~/.bashrc && echo "Bash config reloaded."' diff --git a/.bashrc b/stow/bash/.bashrc similarity index 100% rename from .bashrc rename to stow/bash/.bashrc diff --git a/.inputrc b/stow/bash/.inputrc similarity index 100% rename from .inputrc rename to stow/bash/.inputrc diff --git a/.gitconfig b/stow/git/.gitconfig similarity index 100% rename from .gitconfig rename to stow/git/.gitconfig