diff --git a/.dotfiles.env.example b/.dotfiles.env.example new file mode 100644 index 00000000..05d76b05 --- /dev/null +++ b/.dotfiles.env.example @@ -0,0 +1,26 @@ +# Dotfiles Configuration File +# Copy to ~/.dotfiles.env and customize + +# Installation behavior +FORCE_INSTALL=false +DRY_RUN=false +NON_INTERACTIVE=false + +# Component selection (comma-separated) +# SKIP_COMPONENTS="rust,lua" +# ONLY_COMPONENTS="shell,neovim,tmux" + +# Backup +BACKUP_DIR="$HOME/.dotfiles.backup.$(date +%Y%m%d_%H%M%S)" + +# Package manager override (auto-detected if not set) +# PACKAGE_MANAGER="brew" # brew, apt, pacman, dnf, yum + +# Logging +LOG_FILE="$HOME/.dotfiles/.install.log" + +# Desktop environment (for Linux) +USE_DESKTOP_ENV=FALSE + +# Operating system (usually auto-detected) +# OS="mac" # mac or linux diff --git a/.github/workflows/test-install.yml b/.github/workflows/test-install.yml new file mode 100644 index 00000000..f27a7188 --- /dev/null +++ b/.github/workflows/test-install.yml @@ -0,0 +1,138 @@ +name: Test Installation + +on: + push: + branches: [ main, develop ] + pull_request: + branches: [ main, develop ] + workflow_dispatch: + +jobs: + shellcheck: + name: ShellCheck + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Run ShellCheck + run: | + sudo apt-get update + sudo apt-get install -y shellcheck + chmod +x scripts/test-shellcheck.sh + ./scripts/test-shellcheck.sh + + test-macos: + name: Test on macOS + runs-on: macos-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Run installation (dry-run) + run: | + chmod +x install.sh + ./install.sh --dry-run --non-interactive + + - name: Display system info + run: | + echo "=== System Information ===" + sw_vers + echo "=== Homebrew ===" + which brew || echo "Homebrew not found" + echo "=== Shell ===" + echo $SHELL + + test-ubuntu: + name: Test on Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Install dependencies + run: | + sudo apt-get update + sudo apt-get install -y curl git + + - name: Run installation (dry-run) + run: | + chmod +x install.sh + ./install.sh --dry-run --non-interactive + + - name: Display system info + run: | + echo "=== System Information ===" + lsb_release -a + echo "=== Shell ===" + echo $SHELL + + test-ubuntu-full: + name: Test Full Installation on Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Install dependencies + run: | + sudo apt-get update + sudo apt-get install -y curl git stow + + - name: Run full installation + run: | + chmod +x install.sh + # Skip components that require user interaction or are macOS-only + ./install.sh --non-interactive --skip homebrew,vscode,fonts,macos-defaults + + - name: Run integration tests + continue-on-error: true # Don't fail the job on integration test failures for now + run: | + chmod +x scripts/test-integration.sh + ./scripts/test-integration.sh + + - name: Display installed tools + run: | + echo "=== Installed Tools ===" + which git || echo "git not found" + which zsh || echo "zsh not found" + which stow || echo "stow not found" + which fzf || echo "fzf not found" + which nvim || echo "nvim not found" + which tmux || echo "tmux not found" + + validate-packages: + name: Validate Package Files + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Run package validator + run: | + chmod +x scripts/validate-packages.sh + ./scripts/validate-packages.sh + + test-scripts: + name: Test Scripts + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Test help flags + run: | + chmod +x install.sh uninstall.sh update.sh + ./install.sh --help + ./uninstall.sh --help + ./update.sh --help + + - name: Test version flags + run: | + ./install.sh --version + ./uninstall.sh --version + ./update.sh --version + + - name: Test list components + run: | + ./install.sh --list-components diff --git a/.gitignore b/.gitignore index de54cb08..f0328791 100644 --- a/.gitignore +++ b/.gitignore @@ -18,3 +18,11 @@ files/.config/raycast files/.config/uv files/.config/zed files/.tmux/plugins +.install.log + +# Test artifacts +shellcheck-report.txt +.install.log + +# cagent files +files/.config/cagent/ diff --git a/.shellcheckrc b/.shellcheckrc new file mode 100644 index 00000000..14779626 --- /dev/null +++ b/.shellcheckrc @@ -0,0 +1,11 @@ +# ShellCheck configuration for dotfiles project +# See: https://www.shellcheck.net/wiki/ + +# Disable multiple checks - use comma-separated list for compatibility with older versions +# SC2155 - Declare and assign separately (verbose without significant benefit) +# SC1091 - Not following sourced files (verified at runtime) +# SC2034 - Variables appear unused (library definitions for external use) +# SC2086 - Double quote to prevent globbing (intentional in safe contexts) +# SC2059 - Don't use variables in printf (intentional color variables) +# SC2129 - Consider using { cmd1; cmd2; } >> file (style preference) +disable=SC2155,SC1091,SC2034,SC2086,SC2059,SC2129 diff --git a/Brewfile b/Brewfile index 69380e39..21164a84 100644 --- a/Brewfile +++ b/Brewfile @@ -1,3 +1,28 @@ +# ============================================================================ +# DEPRECATION NOTICE +# ============================================================================ +# +# This Brewfile is kept for reference but is NO LONGER USED by install.sh +# +# The dotfiles now use a new cross-platform package management system located +# in the packages/ directory. This provides: +# +# - Cross-platform support (macOS, Linux, WSL) +# - Better organization (common, optional, platform-specific) +# - Package name mappings for different package managers +# - Validation tools to ensure consistency +# +# To see the migration status: +# ./scripts/migrate-brewfile.sh +# +# To install packages: +# ./install.sh (now uses packages/ directory automatically) +# +# For more information: +# See packages/README.md +# +# ============================================================================ + brew "mas" brew "neovim" brew "noti" diff --git a/CLAUDE.md b/CLAUDE.md index a8be35b4..44c9b1ed 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -4,31 +4,127 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co ## Overview -This is a personal dotfiles repository for macOS that manages system configuration through GNU Stow for symlinking. The setup includes configurations for: -- **Shell**: zsh with Powerlevel10k theme and zap plugin manager +This is a cross-platform dotfiles repository that manages system configuration through GNU Stow for symlinking. The setup includes configurations for: +- **Platforms**: macOS (Intel & ARM), Linux (Ubuntu, Fedora, Arch), WSL (WSL1 & WSL2) +- **Shell**: zsh with Powerlevel10k theme (macOS) or Starship (Linux/WSL), zap plugin manager - **Editors**: Neovim (LazyVim), VS Code, Cursor - **Terminal emulators**: Ghostty, Alacritty, Kitty, WezTerm -- **Window management**: yabai + skhd + sketchybar +- **Window management**: yabai + skhd + sketchybar (macOS), i3/sway (Linux) - **Terminal multiplexers**: tmux, zellij - **Version managers**: Volta (Node.js), rustup (Rust) +- **Package management**: Cross-platform package system with OS-specific mappings ## Installation & Setup +### Platform Support Matrix + +| Platform | Status | Package Manager | Notes | +|----------|--------|----------------|-------| +| macOS (Intel) | ✅ Fully Supported | Homebrew | Main development platform | +| macOS (ARM) | ✅ Fully Supported | Homebrew | Rosetta for compatibility | +| Ubuntu/Debian | ✅ Fully Supported | apt-get | Tested on 20.04+ | +| Fedora/RHEL | ✅ Fully Supported | dnf | Tested on Fedora 38+ | +| Arch Linux | ✅ Fully Supported | pacman | AUR via yay (optional) | +| WSL1/WSL2 | ✅ Fully Supported | apt-get/dnf/pacman | Based on distro | + ### Initial Installation + ```bash -# Fresh install (from remote) +# Fresh install (from remote) - Auto-detects OS bash <(curl -L https://raw.githubusercontent.com/jrock2004/dotfiles/main/scripts/curl-install.sh) -# Local install +# Local install - Interactive mode ./install.sh + +# Non-interactive install (CI/automation) +./install.sh --non-interactive + +# Dry-run (preview without executing) +./install.sh --dry-run + +# Install only specific components +./install.sh --only shell,neovim,tmux + +# Skip specific components +./install.sh --skip lua,rust ``` -The installer will: -1. Ask for OS choice (Mac OSX only currently supported) -2. Install Homebrew if not present -3. Run `brew bundle` to install all dependencies from Brewfile -4. Set up directories, FZF, Lua, Neovim, Rust, Volta, tmux, and Claude CLI -5. Use Stow to symlink all files from `files/` to `$HOME` +### Installation Process + +The modular installer will: +1. **Detect OS and architecture** (macOS/Linux/WSL, Intel/ARM) +2. **Install package manager** if not present (Homebrew/apt/dnf/pacman) +3. **Install packages** from cross-platform package files +4. **Set up components** based on selection (shell, neovim, tmux, rust, volta, etc.) +5. **Configure OS-specific features** (macOS defaults, WSL systemd, etc.) +6. **Symlink dotfiles** using GNU Stow from `files/` to `$HOME` +7. **Create backups** before overwriting existing configs + +### CLI Flags + +```bash +# Display help +./install.sh --help + +# Show version +./install.sh --version + +# List all available components +./install.sh --list-components + +# Preview actions without executing +./install.sh --dry-run + +# Skip all prompts (use defaults) +./install.sh --non-interactive + +# Force reinstall even if already installed +./install.sh --force + +# Skip specific components +./install.sh --skip , + +# Install only specific components +./install.sh --only , +``` + +### Configuration File + +Create `~/.dotfiles.env` to set default options: + +```bash +# Skip specific components +SKIP_COMPONENTS="rust,lua" + +# Install only specific components +ONLY_COMPONENTS="shell,neovim" + +# Custom backup location +BACKUP_DIR="$HOME/.config/dotfiles-backups" + +# Force specific package manager +PACKAGE_MANAGER="brew" # or apt, dnf, pacman + +# Non-interactive mode +NON_INTERACTIVE=true + +# Dry-run mode +DRY_RUN=true + +# Force reinstall +FORCE_INSTALL=true + +# Custom log file +LOG_FILE="$HOME/.dotfiles-install.log" + +# Desktop environment flag +USE_DESKTOP_ENV=true + +# Override OS detection +OS="linux" # or macos, wsl +``` + +See `.dotfiles.env.example` for all available options. ### Managing Dotfiles with Stow @@ -50,32 +146,175 @@ unsync ``` . -├── files/ # All files to be symlinked to $HOME -│ ├── .config/ # XDG config directory -│ │ ├── nvim/ # LazyVim configuration -│ │ ├── ghostty/ # Ghostty terminal config -│ │ ├── sketchybar/ # macOS status bar -│ │ ├── yabai/ # Window manager -│ │ ├── skhd/ # Hotkey daemon -│ │ └── ... # Other app configs -│ ├── .zshrc # Main zsh config -│ ├── .zprofile # Zsh profile -│ ├── .tmux.conf # Tmux configuration +├── files/ # All files to be symlinked to $HOME +│ ├── .config/ # XDG config directory +│ │ ├── nvim/ # LazyVim configuration +│ │ ├── ghostty/ # Ghostty terminal config +│ │ ├── sketchybar/ # macOS status bar +│ │ ├── yabai/ # macOS window manager +│ │ ├── skhd/ # macOS hotkey daemon +│ │ ├── starship.toml # Starship prompt (Linux/WSL) +│ │ └── ... # Other app configs +│ ├── .zshrc # Main zsh config (OS detection) +│ ├── .zprofile # Zsh profile +│ ├── .tmux.conf # Tmux configuration │ └── ... +├── packages/ # Cross-platform package management +│ ├── common.txt # Cross-platform CLI tools +│ ├── optional.txt # Nice-to-have tools +│ ├── macos/ # macOS-specific packages +│ │ ├── core.txt # Homebrew formulae +│ │ ├── gui-apps.txt # Homebrew casks +│ │ ├── fonts.txt # Nerd fonts +│ │ ├── macos-only.txt # Window managers, status bars +│ │ └── taps.txt # Homebrew taps +│ ├── linux/ # Linux-specific packages +│ │ ├── core.txt # Distribution packages +│ │ ├── gui-apps.txt # Native packages +│ │ ├── gui-apps-flatpak.txt # Flatpak apps +│ │ └── gui-apps-snap.txt # Snap apps +│ ├── wsl/ # WSL-specific packages +│ │ └── wsl-specific.txt # WSL utilities +│ ├── mappings/ # Package name mappings +│ │ ├── common-to-macos.map +│ │ ├── common-to-ubuntu.map +│ │ ├── common-to-arch.map +│ │ └── common-to-fedora.map +│ └── README.md # Package system documentation +├── scripts/ # Modular installation scripts +│ ├── install.sh # Main entry point (339 lines) +│ ├── uninstall.sh # Uninstall script +│ ├── update.sh # Update script +│ ├── lib/ # Shared libraries +│ │ ├── common.sh # Logging, backup, retry, error handling +│ │ ├── detect.sh # OS/distro/arch detection +│ │ ├── package-manager.sh # Package abstraction layer +│ │ ├── ui.sh # UI functions (colors, symbols) +│ │ └── gum-wrapper.sh # Interactive prompts with fallbacks +│ ├── os/ # OS-specific orchestration +│ │ ├── macos.sh # macOS setup +│ │ ├── linux.sh # Linux setup +│ │ └── wsl.sh # WSL setup +│ ├── components/ # Component setup functions +│ │ ├── directories.sh # Directory creation +│ │ ├── shell.sh # Shell setup (zsh, zap, FZF) +│ │ ├── neovim.sh # Neovim dependencies +│ │ ├── tmux.sh # Tmux plugin manager +│ │ ├── rust.sh # Rust toolchain +│ │ ├── volta.sh # Volta/Node setup +│ │ ├── lua.sh # Lua language server +│ │ ├── claude.sh # Claude Code CLI +│ │ └── stow.sh # GNU Stow symlinking +│ ├── validate-packages.sh # Package consistency validator +│ ├── migrate-brewfile.sh # Brewfile migration tool +│ ├── test-shellcheck.sh # ShellCheck linting +│ └── test-integration.sh # Integration tests +├── test/ # Docker test environments +│ ├── Dockerfile.ubuntu +│ ├── Dockerfile.fedora +│ ├── Dockerfile.arch +│ └── test-docker.sh +├── .github/workflows/ # CI/CD pipelines +│ └── test-install.yml # GitHub Actions tests ├── zsh/ -│ ├── functions/ # Autoloaded zsh functions -│ └── utils.zsh # Shared zsh utilities -├── bin/ # Custom scripts (added to PATH) -│ ├── tm # Tmux session manager -│ ├── update # System update script +│ ├── functions/ # Autoloaded zsh functions +│ └── utils.zsh # Shared zsh utilities +├── bin/ # Custom scripts (added to PATH) +│ ├── tm # Tmux session manager +│ ├── update # System update script │ └── ... -├── instructions/ # AI assistant instructions -│ ├── cursor/rules/ # Cursor AI rules -│ └── vscode/ # VS Code Copilot instructions -├── scripts/ # Installation scripts -├── Brewfile # Homebrew dependencies -└── install.sh # Main installation script +├── instructions/ # AI assistant instructions +│ ├── cursor/rules/ # Cursor AI rules +│ └── vscode/ # VS Code Copilot instructions +├── Brewfile # Legacy Homebrew (kept for compatibility) +├── install.sh # Root wrapper (calls scripts/install.sh) +├── uninstall.sh # Root wrapper (calls scripts/uninstall.sh) +├── update.sh # Root wrapper (calls scripts/update.sh) +├── .dotfiles.env.example # Configuration file example +├── .shellcheckrc # ShellCheck configuration +└── tasks.md # Development task tracking +``` + +### Package Management System + +The dotfiles use a **cross-platform package management system** that: +- Defines common tools in `packages/common.txt` (should exist on all platforms) +- Defines optional tools in `packages/optional.txt` (nice-to-have) +- Uses OS-specific package files for platform-specific tools +- Maps package names across platforms via `packages/mappings/*.map` +- Validates package consistency with `scripts/validate-packages.sh` + +**Package abstraction layer** (`scripts/lib/package-manager.sh`): +- `pkg_install()`: Installs packages using appropriate package manager +- `pkg_update()`: Updates all packages +- Supports: Homebrew, apt-get, dnf, pacman, flatpak, snap +- Handles package name lookups via mapping files +- Gracefully handles optional packages (warns but continues) + +**Example**: Installing `fd` (file search tool) +- macOS: `brew install fd` +- Ubuntu: `apt-get install fd-find` (mapped via `common-to-ubuntu.map`) +- Arch: `pacman -S fd` +- Fedora: `dnf install fd-find` + +### Component-Based Architecture + +The installation system is **modular and component-based**: + +**Available Components**: +- `directories`: Create standard directories (~/.local/bin, ~/projects, etc.) +- `homebrew`: Install Homebrew and packages (macOS) +- `vscode`: Install VS Code extensions +- `fonts`: Install Nerd Fonts +- `claude`: Install Claude Code CLI +- `fzf`: Install FZF (fuzzy finder) +- `lua`: Install Lua language server +- `neovim`: Install Neovim dependencies (pynvim) +- `rust`: Install Rust toolchain (rustup) +- `shell`: Configure zsh, zap plugin manager +- `tmux`: Install Tmux Plugin Manager (tpm) +- `volta`: Install Volta and Node.js +- `stow`: Symlink dotfiles with GNU Stow +- `macos-defaults`: Configure macOS defaults (macOS only) + +**Component Dependencies**: ``` +directories → none +shell → git, curl, zsh, brew (optional) +neovim → python, pip +tmux → git, curl +rust → curl, bash +volta → curl, bash +lua → git, curl, luarocks (optional) +claude → curl, bash +stow → stow +``` + +Components are **idempotent** (safe to run multiple times) and include: +- Pre-installation checks (skip if already installed) +- Retry logic for network operations +- Rollback on failure +- Progress tracking +- Detailed logging + +### OS Detection and Platform-Specific Setup + +**Detection** (`scripts/lib/detect.sh`): +- Detects OS: macOS, Linux, WSL +- Detects distro: Ubuntu, Debian, Fedora, Arch, etc. +- Detects architecture: x86_64, arm64, aarch64 +- Exports: `$OS`, `$DISTRO`, `$ARCH`, `$BREW_PREFIX`, `$IS_WSL` + +**Platform Orchestration** (`scripts/os/*.sh`): +- **macOS** (`os/macos.sh`): Xcode CLI tools, Homebrew, Rosetta (ARM) +- **Linux** (`os/linux.sh`): Build tools, package manager setup, Starship +- **WSL** (`os/wsl.sh`): systemd, Windows interop, clipboard integration + +**Conditional Configuration**: +- `.zshrc` detects OS and loads appropriate theme (Powerlevel10k vs Starship) +- Stow skips platform-specific configs (e.g., yabai on Linux, i3 on macOS) +- Package installation uses OS-appropriate package manager +- Fonts installed differently (Homebrew on macOS, ~/.local/share/fonts on Linux) ### Neovim Configuration @@ -96,8 +335,9 @@ Key files: ### Shell Configuration The shell setup uses: -- **zap** plugin manager (loaded from `~/.local/share/zap/zap.zsh`) +- **zap** plugin manager (installed in `~/.local/share/zap/zap.zsh`) - **Powerlevel10k** theme (macOS only, via Homebrew) +- **Starship** prompt (Linux/WSL, cross-platform) - Custom functions in `zsh/functions/` (autoloaded) - Utilities in `zsh/utils.zsh` @@ -106,6 +346,8 @@ Key environment variables: - `$VOLTA_HOME`: Volta installation directory - `$RIPGREP_CONFIG_PATH`: Ripgrep config at `~/.rgrc` - `$PNPM_HOME`: pnpm global packages +- `$OS`: Detected operating system +- `$DISTRO`: Linux distribution (if applicable) Custom path order (prepended in `.zshrc`): 1. `~/.local/bin` @@ -113,7 +355,81 @@ Custom path order (prepended in `.zshrc`): 3. `$VOLTA_HOME/bin` 4. `$DOTFILES/bin` 5. `/usr/local/sbin` -6. `/usr/local/opt/grep/libexec/gnubin` +6. `/usr/local/opt/grep/libexec/gnubin` (macOS) + +### UI/UX Library + +The installer includes a UI library (`scripts/lib/ui.sh` and `scripts/lib/gum-wrapper.sh`) that: +- Uses **gum** if available (optional dependency) +- Falls back to **fzf** or **bash select** if gum not installed +- Provides colored output, symbols (✓, ✗, →, ℹ, ⚠) +- Implements progress bars and spinners +- Handles interactive prompts with graceful fallbacks + +**Wrapper functions**: +- `ui_choose()`: Single selection (gum choose → fzf → select) +- `ui_multi_select()`: Multi-selection (gum choose --no-limit → fzf --multi) +- `ui_confirm()`: Yes/no prompts (gum confirm → read -p) +- `ui_input()`: Text input (gum input → read -p) +- `ui_spin()`: Spinner for background tasks + +All prompts are skipped when `--non-interactive` flag is set. + +### Error Handling and Reliability + +**Error Handling** (`scripts/lib/common.sh`): +- `set -euo pipefail` in all scripts (exit on error, undefined vars, pipe failures) +- `trap` for cleanup on error (ERR, EXIT, INT, TERM signals) +- `error_handler()`: Logs errors with stack trace +- `cleanup_on_error()`: Automatic rollback to backups + +**Backup System**: +- Backups created before overwriting configs +- Timestamp-based backup directories: `~/.dotfiles.backup.` +- Automatic restore if installation fails +- Manual restore with `restore_backup()` function + +**Retry Logic**: +- Network operations (curl, git clone) retry up to 3 times +- Exponential backoff between retries +- `retry_command()` wrapper function in common.sh + +**Logging**: +- `log_info()`, `log_success()`, `log_warning()`, `log_error()` +- Timestamps on all log messages +- Optional log file via `LOG_FILE` env variable +- Progress tracking (e.g., "Step 3/10") + +### Testing Infrastructure + +**Testing Tools**: +- **ShellCheck**: All 27 scripts pass shellcheck validation +- **Integration tests**: `scripts/test-integration.sh` (verifies installation) +- **Docker tests**: `test/test-docker.sh` (Ubuntu, Fedora, Arch containers) +- **CI/CD**: GitHub Actions (`.github/workflows/test-install.yml`) + +**Running Tests**: +```bash +# ShellCheck linting +./scripts/test-shellcheck.sh + +# Integration tests +./scripts/test-integration.sh + +# Docker tests (Ubuntu) +./test/test-docker.sh ubuntu + +# Docker tests (all distros) +./test/test-docker.sh ubuntu fedora arch +``` + +**CI Pipeline**: +- Tests on macOS-latest +- Tests on ubuntu-latest +- Dry-run and non-interactive tests +- Full installation test on Ubuntu +- Package validation +- Help/version flag tests ### AI Assistant Instructions @@ -136,21 +452,121 @@ When working on TypeScript/React code, follow these guidelines from the instruct ### Installing New Packages +**Cross-platform tools** (should work on all OSes): +```bash +# Add to packages/common.txt +echo "newtool" >> packages/common.txt + +# Add platform-specific name mappings if needed +echo "newtool=newtool-bin" >> packages/mappings/common-to-ubuntu.map + +# Validate +./scripts/validate-packages.sh + +# Install +./scripts/install.sh --only homebrew +``` + +**macOS-only tools**: ```bash -# Install via Homebrew (preferred for system tools) -brew install -brew install --cask +# Add to appropriate file +echo "package-name" >> packages/macos/core.txt # CLI tool +echo "app-name" >> packages/macos/gui-apps.txt # GUI app (cask) +echo "font-name" >> packages/macos/fonts.txt # Font +echo "yabai" >> packages/macos/macos-only.txt # macOS-specific -# Update Brewfile to persist -brew bundle dump --force +# For Homebrew taps +echo "homebrew/cask-fonts" >> packages/macos/taps.txt -# Install Node packages globally via Volta +# Reinstall packages +./scripts/install.sh --only homebrew --force +``` + +**Linux-only tools**: +```bash +# Add to appropriate file +echo "package-name" >> packages/linux/core.txt # Distribution package +echo "flatpak-id" >> packages/linux/gui-apps-flatpak.txt # Flatpak +echo "snap-name" >> packages/linux/gui-apps-snap.txt # Snap + +# Reinstall +./scripts/install.sh --only homebrew --force +``` + +**Node packages via Volta**: +```bash +# Install globally via Volta volta install # Or use the alias (installs common language servers) npmpackages ``` +**Migrating from old Brewfile**: +```bash +# Run migration script +./scripts/migrate-brewfile.sh + +# Validates mapping and reports differences +``` + +### Package Validation + +```bash +# Validate package consistency +./scripts/validate-packages.sh + +# This checks: +# - All common packages have mappings for each platform +# - No duplicate packages across files +# - Package name format is correct +# - Reports missing packages per OS +``` + +### Updating Dotfiles + +```bash +# Pull latest changes and re-apply +./update.sh + +# Update without updating packages +./update.sh --no-packages + +# Update without restarting services +./update.sh --no-restart + +# Preview update without executing +./update.sh --dry-run +``` + +The update script will: +1. Show git diff of changes +2. Pull latest changes from git +3. Optionally update installed packages +4. Re-run stow for new configs +5. Optionally restart services (tmux, yabai, etc.) +6. Create backup before updating + +### Uninstalling + +```bash +# Remove dotfile symlinks only +./uninstall.sh + +# Remove symlinks and installed packages +./uninstall.sh --remove-packages + +# Preview what would be removed +./uninstall.sh --dry-run +``` + +The uninstall script will: +1. Show confirmation prompt +2. Backup current configs +3. Remove symlinks via stow +4. Optionally remove installed packages +5. Provide rollback instructions + ### Testing Neovim Changes ```bash @@ -173,6 +589,7 @@ tmux-work # or zellij-work for zellij ### System Updates +**macOS**: ```bash # Update Homebrew and all packages updateSystem @@ -182,6 +599,33 @@ updateSystem update ``` +**Linux (Ubuntu/Debian)**: +```bash +# Update apt packages +sudo apt update && sudo apt upgrade + +# Or use the update script +./update.sh +``` + +**Linux (Arch)**: +```bash +# Update pacman packages +sudo pacman -Syu + +# Update AUR packages (if using yay) +yay -Syu +``` + +**Linux (Fedora)**: +```bash +# Update dnf packages +sudo dnf update + +# Or use the update script +./update.sh +``` + ### Git Aliases Available in `.zshrc`: @@ -200,23 +644,374 @@ switchtopnpm switchtonpm ``` +### Running Tests + +```bash +# Run ShellCheck on all scripts +./scripts/test-shellcheck.sh + +# Run integration tests +./scripts/test-integration.sh + +# Test in Docker (Ubuntu) +./test/test-docker.sh ubuntu --build + +# Test in all distros +for distro in ubuntu fedora arch; do + ./test/test-docker.sh "$distro" --build +done +``` + +### Dry-Run Mode + +```bash +# Preview installation without executing +./install.sh --dry-run + +# Preview update without executing +./update.sh --dry-run + +# Preview uninstall without executing +./uninstall.sh --dry-run +``` + +## Platform-Specific Notes + +### macOS + +**Prerequisites**: +- Xcode Command Line Tools (installed automatically) +- Rosetta 2 (ARM Macs, installed automatically if needed) + +**macOS-specific features**: +- Homebrew package manager +- yabai window manager +- skhd hotkey daemon +- sketchybar status bar +- Powerlevel10k zsh theme +- macOS defaults configuration + +**Installation**: +```bash +./install.sh +``` + +### Linux (Ubuntu/Debian) + +**Prerequisites**: +```bash +sudo apt-get update +sudo apt-get install -y git curl build-essential +``` + +**Linux-specific features**: +- apt-get package manager +- Starship prompt +- Optional: i3/sway window manager +- Optional: Flatpak/Snap for GUI apps + +**Installation**: +```bash +./install.sh --non-interactive +``` + +### Linux (Fedora/RHEL) + +**Prerequisites**: +```bash +sudo dnf update +sudo dnf groupinstall -y "Development Tools" +sudo dnf install -y git curl +``` + +**Installation**: +```bash +./install.sh --non-interactive +``` + +### Linux (Arch) + +**Prerequisites**: +```bash +sudo pacman -Syu +sudo pacman -S --needed base-devel git curl +``` + +**Optional AUR helper**: +```bash +# Install yay for AUR packages +git clone https://aur.archlinux.org/yay.git +cd yay +makepkg -si +``` + +**Installation**: +```bash +./install.sh --non-interactive +``` + +### WSL (Windows Subsystem for Linux) + +**Prerequisites**: +- WSL2 recommended (better performance) +- Base distro installed (Ubuntu, Fedora, or Arch) + +**WSL-specific setup**: +- systemd enabled (WSL2 only) +- Windows interop configured +- Clipboard integration (`clip.exe`) +- BROWSER env variable set to Windows browser + +**Installation**: +```bash +./install.sh --non-interactive +``` + +**WSL notes**: +- Desktop environment configs (yabai, i3) are skipped +- Audio configs are skipped +- Uses distro's native package manager +- Optional Windows Terminal integration + +## Troubleshooting + +### Common Issues + +**"Command not found" after installation**: +```bash +# Reload shell configuration +exec zsh + +# Or source manually +source ~/.zshrc +``` + +**Stow conflicts**: +```bash +# Backup and remove conflicting files +mv ~/.zshrc ~/.zshrc.backup +mv ~/.tmux.conf ~/.tmux.conf.backup + +# Re-run stow +./install.sh --only stow --force +``` + +**Homebrew not in PATH (macOS)**: +```bash +# Intel Macs +echo 'eval "$(/usr/local/bin/brew shellenv)"' >> ~/.zprofile + +# ARM Macs (M1/M2/M3) +echo 'eval "$(/opt/homebrew/bin/brew shellenv)"' >> ~/.zprofile + +# Reload +source ~/.zprofile +``` + +**Permission denied errors (Linux)**: +```bash +# Ensure scripts are executable +chmod +x install.sh update.sh uninstall.sh +chmod +x scripts/*.sh +chmod +x scripts/lib/*.sh +chmod +x scripts/os/*.sh +chmod +x scripts/components/*.sh +``` + +**Git clone fails due to network**: +```bash +# Retry with force +./install.sh --force + +# Or manually retry +cd ~/.dotfiles +git pull origin main +./install.sh +``` + +**Neovim version too old (Linux)**: +```bash +# Ubuntu: Add Neovim PPA +sudo add-apt-repository ppa:neovim-ppa/unstable +sudo apt update +sudo apt install neovim + +# Fedora: Use copr +sudo dnf copr enable agriffis/neovim-nightly +sudo dnf install neovim + +# Arch: Use pacman +sudo pacman -S neovim +``` + +**Python dependencies missing (Neovim)**: +```bash +# Install pynvim +python3 -m pip install --user pynvim + +# Or use the installer +./install.sh --only neovim --force +``` + +**WSL systemd not working**: +```bash +# Enable systemd in /etc/wsl.conf +echo "[boot]" | sudo tee /etc/wsl.conf +echo "systemd=true" | sudo tee -a /etc/wsl.conf + +# Restart WSL +wsl.exe --shutdown +# Then reopen WSL +``` + +### Platform-Specific Troubleshooting + +**macOS**: +- See `docs/MACOS.md` (when created) +- Rosetta issues on ARM: `softwareupdate --install-rosetta --agree-to-license` +- Xcode issues: `sudo xcode-select --reset` + +**Linux**: +- See `docs/LINUX.md` (when created) +- Font cache issues: `fc-cache -fv` +- Shell not changed: `chsh -s $(which zsh)` + +**WSL**: +- See `docs/WSL.md` (when created) +- Clock drift: `sudo hwclock -s` +- Clipboard issues: Ensure `clip.exe` is in PATH + +### Getting Help + +```bash +# Show help +./install.sh --help + +# Check version +./install.sh --version + +# List components +./install.sh --list-components + +# Preview what would be installed +./install.sh --dry-run + +# Check logs +tail -f ~/.dotfiles-install.log +``` + ## Important Notes -- **macOS only**: Currently only supports Mac OSX +- **Cross-platform**: Supports macOS, Linux (Ubuntu, Fedora, Arch), and WSL - **Stow-based**: Never edit files in `$HOME` directly; edit in `files/` then run `sync` -- **Homebrew**: Main package manager, uses rosetta for Volta/Node compatibility +- **Package managers**: Homebrew (macOS), apt/dnf/pacman (Linux), automatic detection - **Volta**: Manages Node.js versions (not nvm/fnm) - **LazyVim**: Base Neovim config - consult LazyVim docs for built-in features - **Shell**: Uses zsh (not bash), switched automatically during install - **Git config**: `.gitconfig` is managed via Stow, so user-specific changes should be in `files/.gitconfig` +- **Modular**: Component-based architecture, skip or install only what you need +- **Idempotent**: Safe to run multiple times, includes rollback on failure +- **Tested**: CI/CD pipeline, Docker tests, integration tests, ShellCheck validation + +## Migration from Old System + +If upgrading from the old monolithic install.sh: + +1. **Backup your current setup**: + ```bash + cp -r ~/.dotfiles ~/.dotfiles.backup.old + ``` + +2. **Pull latest changes**: + ```bash + cd ~/.dotfiles + git pull origin main + ``` + +3. **Review breaking changes** (see `MIGRATION.md` when created) + +4. **Run new installer**: + ```bash + ./install.sh --dry-run # Preview first + ./install.sh # Then install + ``` + +5. **Migrate Brewfile** (macOS only): + ```bash + ./scripts/migrate-brewfile.sh + ``` + +The old `Brewfile` is kept for backward compatibility but will be deprecated in a future release. ## Key Dependencies -From Brewfile (91 total packages): -- **Core tools**: git, gh, stow, fzf, ripgrep, fd, eza, bat, jq -- **Languages**: go, python, lua, rust (via rustup) -- **Shells**: zsh, bash, tmux, zellij -- **Editors**: neovim, vim -- **macOS tools**: yabai, skhd, sketchybar -- **Dev tools**: lazygit, lazydocker, prettier, stylua, shellcheck -- **Terminals**: ghostty, alacritty, kitty, wezterm +From package files (cross-platform): +- **Core tools** (common.txt): git, gh, stow, fzf, ripgrep, fd, eza, bat, jq +- **Languages** (common.txt): go, python, lua, rust (via rustup) +- **Shells** (common.txt): zsh, bash, tmux +- **Editors** (common.txt): neovim, vim +- **Dev tools** (optional.txt): lazygit, lazydocker, prettier, stylua, shellcheck + +**macOS-specific** (packages/macos/): +- Window managers: yabai, skhd, sketchybar +- Terminals: ghostty, alacritty, kitty, wezterm +- Fonts: Nerd Fonts via Homebrew casks + +**Linux-specific** (packages/linux/): +- Window managers: i3, sway (optional) +- Terminals: alacritty, kitty (via Flatpak/Snap) +- Fonts: Nerd Fonts from GitHub releases + +**Total packages**: ~100+ packages across all platforms + +## Development + +### Adding New Components + +1. Create component file in `scripts/components/.sh` +2. Define `setup_()` function +3. Add component to `show_help()` in `scripts/install.sh` +4. Add component to OS orchestration script (`scripts/os/*.sh`) +5. Add dependencies to component file header +6. Test with `./install.sh --only --dry-run` + +### Running Development Tests + +```bash +# ShellCheck all scripts +./scripts/test-shellcheck.sh + +# Integration tests +./scripts/test-integration.sh + +# Docker tests +./test/test-docker.sh ubuntu --build --shell + +# CI locally (requires act) +act -j test-macos +act -j test-ubuntu +``` + +### Code Style + +- All scripts use `set -euo pipefail` +- Follow [Google Shell Style Guide](https://google.github.io/styleguide/shellguide.html) +- Pass ShellCheck with no warnings +- Include error handling and logging +- Make functions idempotent +- Add progress tracking for long operations +- Include `--dry-run` support +- Document dependencies in file header + +### Contributing + +See `CONTRIBUTING.md` (when created) for detailed contribution guidelines. + +## Version History + +- **v2.0.0** (Current): Cross-platform support, modular architecture, package system +- **v1.x.x**: macOS-only, monolithic install.sh, Brewfile-based + +## License + +See LICENSE file in repository root. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000..cfd10f34 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,663 @@ +# Contributing to Dotfiles + +Thank you for your interest in contributing to this dotfiles repository! Whether you're fixing bugs, adding new features, improving documentation, or adding support for new platforms, your contributions are welcome and appreciated. + +## Table of Contents + +- [Code of Conduct](#code-of-conduct) +- [Getting Started](#getting-started) +- [Development Workflow](#development-workflow) +- [Adding New Packages](#adding-new-packages) +- [Creating Package Mappings](#creating-package-mappings) +- [Adding New Components](#adding-new-components) +- [Testing](#testing) +- [Code Style Guidelines](#code-style-guidelines) +- [Submitting Changes](#submitting-changes) + +## Code of Conduct + +This project follows a simple code of conduct: +- Be respectful and considerate +- Welcome newcomers and help them learn +- Focus on what is best for the community +- Show empathy towards others + +## Getting Started + +### Fork and Clone + +1. **Fork the repository** on GitHub +2. **Clone your fork** locally: + ```bash + git clone https://github.com/YOUR_USERNAME/dotfiles.git ~/.dotfiles + cd ~/.dotfiles + ``` +3. **Add upstream remote**: + ```bash + git remote add upstream https://github.com/jrock2004/dotfiles.git + ``` +4. **Create a feature branch**: + ```bash + git checkout -b feature/your-feature-name + ``` + +### Development Setup + +1. **Install prerequisites** for your platform (see README.md) +2. **Run dry-run** to verify setup: + ```bash + ./install.sh --dry-run + ``` +3. **Test your changes** before committing + +## Development Workflow + +1. **Update your fork** before starting work: + ```bash + git checkout main + git pull upstream main + git push origin main + ``` + +2. **Create a feature branch**: + ```bash + git checkout -b feature/descriptive-name + ``` + +3. **Make your changes** following the guidelines below + +4. **Test your changes** thoroughly (see [Testing](#testing)) + +5. **Commit with descriptive messages**: + ```bash + git add . + git commit -m "feat: Add support for XYZ" + ``` + +6. **Push to your fork**: + ```bash + git push origin feature/descriptive-name + ``` + +7. **Create a Pull Request** on GitHub + +## Adding New Packages + +### Cross-Platform Packages + +For tools that should be available on **all platforms** (macOS, Linux, WSL): + +1. **Add to `packages/common.txt`**: + ```bash + echo "your-package-name" >> packages/common.txt + ``` + +2. **Create mappings** for platforms where package name differs (see [Creating Package Mappings](#creating-package-mappings)) + +3. **Validate** the package configuration: + ```bash + ./scripts/validate-packages.sh + ``` + +4. **Test installation** on multiple platforms if possible: + ```bash + # macOS + ./install.sh --only homebrew --force --dry-run + + # Linux (Docker) + ./test/test-docker.sh ubuntu --build + ``` + +**Example**: Adding `htop` (cross-platform monitoring tool) +```bash +# Add to common.txt +echo "htop" >> packages/common.txt + +# Validate +./scripts/validate-packages.sh + +# Test +./install.sh --only homebrew --dry-run +``` + +### Platform-Specific Packages + +For packages that are **platform-specific**: + +#### macOS-Specific + +```bash +# CLI tools +echo "package-name" >> packages/macos/core.txt + +# GUI applications (Homebrew casks) +echo "app-name" >> packages/macos/gui-apps.txt + +# Fonts +echo "font-name" >> packages/macos/fonts.txt + +# macOS-only tools (yabai, skhd, etc.) +echo "tool-name" >> packages/macos/macos-only.txt + +# Homebrew taps (if needed) +echo "homebrew/tap-name" >> packages/macos/taps.txt +``` + +#### Linux-Specific + +```bash +# Distribution packages +echo "package-name" >> packages/linux/core.txt + +# GUI applications (native) +echo "app-name" >> packages/linux/gui-apps.txt + +# Flatpak applications +echo "com.example.App" >> packages/linux/gui-apps-flatpak.txt + +# Snap applications +echo "app-name" >> packages/linux/gui-apps-snap.txt +``` + +#### WSL-Specific + +```bash +# WSL-specific utilities +echo "package-name" >> packages/wsl/wsl-specific.txt +``` + +### Optional Packages + +For **nice-to-have** tools that may not be available on all platforms: + +```bash +echo "optional-tool" >> packages/optional.txt +``` + +The installer will warn but continue if these packages are unavailable. + +## Creating Package Mappings + +When a package has **different names** across platforms, create a mapping: + +### Mapping File Format + +``` +# Format: common-name=platform-specific-name +fd=fd-find +bat=batcat +ripgrep=rg +``` + +### Adding Mappings + +1. **Identify the common name** (used in `packages/common.txt`) +2. **Find platform-specific names**: + - Ubuntu/Debian: `apt-cache search ` + - Fedora: `dnf search ` + - Arch: `pacman -Ss ` + - macOS: `brew search ` + +3. **Add to appropriate mapping file**: + ```bash + # Ubuntu/Debian + echo "fd=fd-find" >> packages/mappings/common-to-ubuntu.map + + # Fedora + echo "fd=fd-find" >> packages/mappings/common-to-fedora.map + + # Arch (if different) + echo "fd=fd" >> packages/mappings/common-to-arch.map + + # macOS (usually same as common name) + echo "fd=fd" >> packages/mappings/common-to-macos.map + ``` + +4. **Validate mappings**: + ```bash + ./scripts/validate-packages.sh + ``` + +### Example: Adding `eza` (modern `ls` replacement) + +```bash +# 1. Add to common.txt +echo "eza" >> packages/common.txt + +# 2. Create mappings (if needed) +# Ubuntu - check if name differs +apt-cache search eza +# Fedora - check if name differs +dnf search eza +# Add mappings if different from "eza" + +# 3. Validate +./scripts/validate-packages.sh +``` + +## Adding New Components + +Components are modular installation units (e.g., `shell`, `neovim`, `tmux`). + +### Creating a New Component + +1. **Create component file** in `scripts/components/.sh`: + ```bash + touch scripts/components/.sh + chmod +x scripts/components/.sh + ``` + +2. **Define component function**: + ```bash + #!/bin/bash + # Component: + # Description: What this component does + # Dependencies: list, of, dependencies + # Platforms: macos, linux, wsl (or "all") + + setup_() { + local component="" + + # Idempotency check + if [ -f "$HOME/.-installed" ] && [ "$FORCE_INSTALL" != "true" ]; then + log_info "$component already installed (use --force to reinstall)" + return 0 + fi + + log_info "Installing $component..." + + # Installation steps here + # Example: + # pkg_install "package-name" || { + # log_error "Failed to install package-name" + # return 1 + # } + + # Mark as installed + touch "$HOME/.-installed" + + log_success "$component installed successfully" + return 0 + } + ``` + +3. **Add to component list** in `scripts/install.sh`: + ```bash + # In show_help() function + echo " - Description of component" + ``` + +4. **Add to OS orchestration** in `scripts/os/macos.sh`, `scripts/os/linux.sh`, or `scripts/os/wsl.sh`: + ```bash + # Source the component + source "$SCRIPT_DIR/components/.sh" + + # Add to installation sequence + run_component "" "setup_" + ``` + +5. **Document dependencies** in component file header + +6. **Test the component**: + ```bash + ./install.sh --only --dry-run + ./install.sh --only --force + ``` + +### Component Best Practices + +- **Make it idempotent**: Check if already installed, use `--force` to override +- **Handle errors gracefully**: Use `|| return 1` for critical failures +- **Log progress**: Use `log_info`, `log_success`, `log_warning`, `log_error` +- **Support dry-run**: Check `$DRY_RUN` variable before executing +- **Retry network operations**: Use `retry_command` for downloads +- **Document dependencies**: List in file header + +### Example Component + +See `scripts/components/shell.sh` or `scripts/components/tmux.sh` for complete examples. + +## Testing + +### Running Tests Locally + +#### ShellCheck (Required) + +All shell scripts must pass ShellCheck: + +```bash +# Check all scripts +./scripts/test-shellcheck.sh + +# Check specific script +shellcheck scripts/install.sh +``` + +**Fix common issues**: +- Quote variables: `"$VAR"` not `$VAR` +- Check exit codes: `command || handle_error` +- Use `[[ ]]` for tests, not `[ ]` + +#### Integration Tests + +Test that installation works correctly: + +```bash +# Run all integration tests +./scripts/test-integration.sh + +# This tests: +# - Dotfiles are symlinked correctly +# - Required binaries are installed +# - Shell is changed to zsh +# - Neovim starts without errors +# - Git, tmux, volta work correctly +``` + +#### Docker Tests + +Test on multiple Linux distributions: + +```bash +# Test on Ubuntu +./test/test-docker.sh ubuntu --build + +# Test on Fedora +./test/test-docker.sh fedora --build + +# Test on Arch +./test/test-docker.sh arch --build + +# Test on all distros +for distro in ubuntu fedora arch; do + ./test/test-docker.sh "$distro" --build +done + +# Drop into shell for debugging +./test/test-docker.sh ubuntu --build --shell +``` + +#### Dry-Run Testing + +Always test with dry-run before actual installation: + +```bash +# Preview installation +./install.sh --dry-run + +# Preview specific component +./install.sh --only --dry-run + +# Preview with different settings +DRY_RUN=true ./install.sh +``` + +### CI/CD Testing + +Pull requests are automatically tested via GitHub Actions: +- **macOS**: Tests on macOS-latest +- **Linux**: Tests on ubuntu-latest +- **ShellCheck**: All scripts must pass +- **Dry-run**: Validates installation process +- **Package validation**: Checks package consistency + +View CI results at: `.github/workflows/test-install.yml` + +### Adding New Tests + +To add new integration tests, edit `scripts/test-integration.sh`: + +```bash +test_your_feature() { + log_info "Testing your feature..." + + # Your test logic here + if [ condition ]; then + log_success "Feature test passed" + return 0 + else + log_error "Feature test failed" + return 1 + fi +} + +# Add to main test sequence +test_your_feature || exit 1 +``` + +## Code Style Guidelines + +### Shell Script Style + +Follow the [Google Shell Style Guide](https://google.github.io/styleguide/shellguide.html) with these key points: + +#### 1. Shebang and Settings + +```bash +#!/bin/bash +# Description of script +# Exit on error, undefined variables, and pipe failures +set -euo pipefail +``` + +#### 2. Error Handling + +```bash +# Use error handling +command || { + log_error "Command failed" + return 1 +} + +# Use trap for cleanup +trap cleanup_on_error ERR EXIT INT TERM +``` + +#### 3. Functions + +```bash +# Function naming: lowercase with underscores +function_name() { + local var="value" # Use local for function variables + + # Do something + return 0 +} +``` + +#### 4. Variables + +```bash +# Global variables: UPPERCASE +GLOBAL_VAR="value" + +# Local variables: lowercase +local_var="value" + +# Always quote variables +echo "$var" +echo "${var}" + +# Use arrays properly +my_array=("item1" "item2") +for item in "${my_array[@]}"; do + echo "$item" +done +``` + +#### 5. Conditionals + +```bash +# Use [[ ]] for tests +if [[ "$var" == "value" ]]; then + # Do something +fi + +# Check exit codes +if command; then + # Success +else + # Failure +fi +``` + +#### 6. Logging + +```bash +# Use logging functions +log_info "Information message" +log_success "Success message" +log_warning "Warning message" +log_error "Error message" +``` + +#### 7. Comments + +```bash +# File header +#!/bin/bash +# Script: name.sh +# Description: What this script does +# Dependencies: what it needs +# Platforms: macos, linux, wsl + +# Function documentation +# Description: What the function does +# Arguments: $1 - description +# Returns: 0 on success, 1 on failure +function_name() { + # Implementation +} +``` + +### ShellCheck Rules + +All scripts must pass ShellCheck with our configuration (`.shellcheckrc`): + +**Disabled warnings** (with justification): +- `SC2155`: Declare and assign separately (allows `local var="$(command)"`) +- `SC2034`: Variable appears unused (for exported variables) +- `SC2086`: Double quote to prevent globbing (sometimes needed) +- `SC2059`: Don't use variables in printf format (allows dynamic formats) +- `SC2129`: Multiple redirects (allows `echo >> file` style) +- `SC1091`: Not following sourced files (can't follow dynamic sources) + +**Enabled and enforced**: +- Quote all variables +- Check command exit codes +- Use `[[ ]]` for tests +- Proper array handling +- No unused variables (except exports) + +### Commit Message Format + +Use [Conventional Commits](https://www.conventionalcommits.org/): + +``` +(): + +[optional body] + +[optional footer] +``` + +**Types**: +- `feat`: New feature +- `fix`: Bug fix +- `docs`: Documentation changes +- `style`: Code style (formatting, no logic change) +- `refactor`: Code refactoring +- `test`: Adding or updating tests +- `chore`: Maintenance tasks + +**Examples**: +```bash +feat(packages): Add support for Neovim 0.10 +fix(shell): Fix zsh plugin loading order +docs(readme): Update installation instructions +test(docker): Add Fedora 39 test +chore(ci): Update GitHub Actions versions +``` + +## Submitting Changes + +### Pull Request Process + +1. **Ensure all tests pass**: + ```bash + ./scripts/test-shellcheck.sh + ./scripts/test-integration.sh + ``` + +2. **Update documentation** if needed: + - Update `README.md` for user-facing changes + - Update `CLAUDE.md` for AI assistant context + - Update `CONTRIBUTING.md` for contributor guidelines + +3. **Validate package changes**: + ```bash + ./scripts/validate-packages.sh + ``` + +4. **Create pull request** with: + - Clear title following commit message format + - Description of changes + - Testing performed + - Screenshots (if UI changes) + - Breaking changes (if any) + +5. **Address review feedback** promptly + +6. **Squash commits** if requested + +### Pull Request Template + +```markdown +## Description +Brief description of changes + +## Type of Change +- [ ] Bug fix (non-breaking change which fixes an issue) +- [ ] New feature (non-breaking change which adds functionality) +- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected) +- [ ] Documentation update + +## Testing Performed +- [ ] ShellCheck passed +- [ ] Integration tests passed +- [ ] Docker tests passed (Ubuntu/Fedora/Arch) +- [ ] Tested on macOS +- [ ] Tested on Linux +- [ ] Tested on WSL + +## Checklist +- [ ] Code follows style guidelines +- [ ] Self-review of code completed +- [ ] Documentation updated +- [ ] No new warnings generated +- [ ] Tests added/updated as needed +- [ ] Commit messages follow conventional commits +``` + +## Additional Resources + +- [README.md](README.md) - User-facing documentation +- [CLAUDE.md](CLAUDE.md) - AI assistant context +- [MIGRATION.md](MIGRATION.md) - Migration guide (to be created) +- [Google Shell Style Guide](https://google.github.io/styleguide/shellguide.html) +- [Conventional Commits](https://www.conventionalcommits.org/) + +## Questions or Need Help? + +- Open an issue for questions +- Check existing issues and PRs first +- Be specific and provide context +- Include error messages and logs + +## License + +By contributing, you agree that your contributions will be licensed under the same license as this project (MIT License). + +--- + +Thank you for contributing! Your efforts help make this dotfiles repository better for everyone. 🎉 diff --git a/MIGRATION.md b/MIGRATION.md new file mode 100644 index 00000000..d3951d19 --- /dev/null +++ b/MIGRATION.md @@ -0,0 +1,834 @@ +# Migration Guide + +This guide will help you migrate from the old monolithic dotfiles system (v1.x.x) to the new modular, cross-platform architecture (v2.0.0). + +## Table of Contents + +- [What's Changed](#whats-changed) +- [Breaking Changes](#breaking-changes) +- [Before You Migrate](#before-you-migrate) +- [Migration Steps](#migration-steps) +- [Brewfile to Packages Migration](#brewfile-to-packages-migration) +- [Configuration Changes](#configuration-changes) +- [Rollback Instructions](#rollback-instructions) +- [Troubleshooting](#troubleshooting) +- [FAQ](#faq) + +## What's Changed + +### Version 2.0.0 (Current) + +The new version introduces a **modular, component-based architecture** with **cross-platform support**: + +#### Major Improvements + +1. **Cross-Platform Support** + - **Old**: macOS only + - **New**: macOS, Ubuntu, Fedora, Arch Linux, WSL + +2. **Package Management** + - **Old**: Single `Brewfile` (Homebrew only) + - **New**: Cross-platform package system with mappings + - `packages/common.txt` - Cross-platform tools + - `packages/optional.txt` - Optional tools + - `packages/macos/` - macOS-specific packages + - `packages/linux/` - Linux-specific packages + - `packages/wsl/` - WSL-specific packages + - `packages/mappings/` - Package name mappings + +3. **Installation System** + - **Old**: Monolithic `install.sh` (1159 lines) + - **New**: Modular architecture (339-line main script + components) + - `scripts/lib/` - Shared libraries + - `scripts/os/` - OS-specific orchestration + - `scripts/components/` - Component setup functions + +4. **New Features** + - Component-based installation (install only what you need) + - Dry-run mode (`--dry-run`) + - Non-interactive mode (`--non-interactive`) + - Selective installation (`--only`, `--skip`) + - Configuration file support (`~/.dotfiles.env`) + - Automatic backups and rollback on failure + - Update script (`./update.sh`) + - Uninstall script (`./uninstall.sh`) + - Package validation (`./scripts/validate-packages.sh`) + +5. **Testing & CI** + - **Old**: No automated testing + - **New**: ShellCheck, integration tests, Docker tests, GitHub Actions CI + +## Breaking Changes + +### 1. Installation Command Location + +**Old**: +```bash +./install.sh # Monolithic script in root +``` + +**New**: +```bash +./install.sh # Wrapper that calls scripts/install.sh +# Or directly: +./scripts/install.sh +``` + +**Impact**: Minimal - root wrapper maintained for backward compatibility + +### 2. Package Management + +**Old**: +```bash +# Single Brewfile +brew bundle dump --force +``` + +**New**: +```bash +# Multiple package files +echo "package" >> packages/common.txt +./scripts/validate-packages.sh +``` + +**Impact**: Moderate - see [Brewfile to Packages Migration](#brewfile-to-packages-migration) + +### 3. Environment Variables + +**New variables** available: +- `$OS` - Detected operating system (macos, linux, wsl) +- `$DISTRO` - Linux distribution (ubuntu, fedora, arch, etc.) +- `$ARCH` - Architecture (x86_64, arm64, aarch64) +- `$IS_WSL` - WSL detection flag + +**Impact**: Minimal - backward compatible + +### 4. Component Installation + +**Old**: +```bash +# All components installed by default +./install.sh +``` + +**New**: +```bash +# Interactive component selection +./install.sh + +# Or selective installation +./install.sh --only shell,neovim,tmux +./install.sh --skip lua,rust +``` + +**Impact**: Positive - more control over what gets installed + +### 5. Configuration Files + +**Old**: +```bash +# No configuration file support +# All settings via prompts +``` + +**New**: +```bash +# Optional configuration file +~/.dotfiles.env +``` + +**Impact**: Positive - can automate installation + +### 6. Shell Theme + +**macOS**: No change - still uses Powerlevel10k + +**Linux/WSL**: Now uses **Starship** instead of attempting Powerlevel10k + +**Impact**: Moderate for Linux users - may need to reconfigure prompt preferences + +## Before You Migrate + +### 1. Backup Your Current Setup + +**Critical**: Always backup before migrating! + +```bash +# Backup entire dotfiles directory +cp -r ~/.dotfiles ~/.dotfiles.backup.v1 +tar -czf ~/dotfiles-backup-$(date +%Y%m%d).tar.gz ~/.dotfiles + +# Backup important configs +cp ~/.zshrc ~/.zshrc.backup +cp ~/.tmux.conf ~/.tmux.conf.backup +cp ~/.config/nvim ~/.config/nvim.backup -r +``` + +### 2. Note Your Customizations + +Document any custom changes you've made: + +```bash +# Check for uncommitted changes +cd ~/.dotfiles +git status +git diff + +# Note any custom packages in Brewfile +diff Brewfile <(brew bundle dump --file=/dev/stdout) +``` + +### 3. Check Disk Space + +Ensure sufficient space for backups: + +```bash +df -h ~ +# Need at least 1GB free +``` + +### 4. Review Prerequisites + +Ensure you have required tools: + +```bash +# macOS +xcode-select -p + +# Linux +git --version +curl --version +``` + +## Migration Steps + +### Step 1: Backup (Required) + +```bash +# Navigate to dotfiles +cd ~/.dotfiles + +# Create backup +cp -r ~/.dotfiles ~/.dotfiles.backup.v1 + +# Note current commit +git log -1 --oneline > ~/dotfiles-migration-commit.txt +``` + +### Step 2: Pull Latest Changes + +```bash +# Fetch latest version +git fetch origin + +# Checkout main branch +git checkout main + +# Pull latest (v2.0.0) +git pull origin main +``` + +### Step 3: Review Changes + +```bash +# See what changed +git log --oneline $(cat ~/dotfiles-migration-commit.txt | cut -d' ' -f1)..HEAD + +# Preview new structure +tree -L 2 packages/ +tree -L 2 scripts/ +``` + +### Step 4: Dry-Run Installation + +**Important**: Always dry-run first! + +```bash +# Preview what would be installed +./install.sh --dry-run + +# Preview with specific components only +./install.sh --only shell,neovim --dry-run +``` + +### Step 5: Run Migration + +#### Option A: Full Installation (Recommended) + +```bash +# Run new installer +./install.sh + +# Follow interactive prompts +# Select components you want +``` + +#### Option B: Non-Interactive + +```bash +# Use defaults, no prompts +./install.sh --non-interactive +``` + +#### Option C: Selective Installation + +```bash +# Install only specific components +./install.sh --only shell,neovim,tmux,volta,stow + +# Or skip components you don't want +./install.sh --skip lua,rust,claude +``` + +### Step 6: Migrate Brewfile (macOS Only) + +If you have custom packages in your Brewfile: + +```bash +# Run migration script +./scripts/migrate-brewfile.sh + +# This will: +# - Read your current Brewfile +# - Map packages to new package files +# - Report any unmapped packages +# - Show suggested package file locations +``` + +**Manually review** the migration: + +```bash +# Check what got migrated +diff Brewfile packages/macos/core.txt +cat packages/macos/gui-apps.txt +cat packages/macos/fonts.txt + +# Add any missing custom packages +echo "my-custom-package" >> packages/macos/core.txt +``` + +### Step 7: Validate Configuration + +```bash +# Validate package consistency +./scripts/validate-packages.sh + +# Check for conflicts +stow -n -v -R -t ~ -d "$DOTFILES" files +``` + +### Step 8: Test Installation + +```bash +# Reload shell +exec zsh + +# Test commands +nvim --version +tmux -V +volta --version +git --version + +# Check dotfiles are symlinked +ls -la ~/. | grep "\.dotfiles" +``` + +### Step 9: Verify Everything Works + +**Test checklist**: +- [ ] Shell starts without errors +- [ ] Neovim opens and plugins load +- [ ] Tmux starts and plugins work +- [ ] Git configured correctly +- [ ] Volta/Node.js available +- [ ] Custom aliases/functions work +- [ ] Terminal theme looks correct + +## Brewfile to Packages Migration + +### Understanding the New Structure + +**Old**: Single `Brewfile` +```ruby +# Brewfile +brew "git" +brew "neovim" +cask "ghostty" +cask "font-meslo-lg-nerd-font" +``` + +**New**: Multiple package files +``` +packages/ +├── common.txt # git, neovim (cross-platform) +├── macos/ +│ ├── core.txt # macOS-specific CLI tools +│ ├── gui-apps.txt # ghostty (GUI apps) +│ └── fonts.txt # font-meslo-lg-nerd-font +``` + +### Automated Migration + +```bash +# Run migration script +./scripts/migrate-brewfile.sh + +# Review output +# - Shows where each package was categorized +# - Reports unmapped packages +# - Suggests manual additions +``` + +### Manual Migration + +If you prefer manual control: + +#### 1. Export Current Packages + +```bash +# Get current Homebrew packages +brew leaves > ~/brew-packages.txt +brew list --cask > ~/brew-casks.txt +``` + +#### 2. Categorize Packages + +**Cross-platform CLI tools** → `packages/common.txt`: +```bash +# Examples: git, neovim, fzf, ripgrep +# These should work on Linux too +``` + +**macOS-only CLI tools** → `packages/macos/core.txt`: +```bash +# Examples: m-cli, trash, mas +# These are macOS-specific +``` + +**GUI applications** → `packages/macos/gui-apps.txt`: +```bash +# Examples: ghostty, alacritty, visual-studio-code +# These are Homebrew casks +``` + +**Fonts** → `packages/macos/fonts.txt`: +```bash +# Examples: font-meslo-lg-nerd-font +# These are font casks +``` + +**Window managers** → `packages/macos/macos-only.txt`: +```bash +# Examples: yabai, skhd, sketchybar +# macOS-specific system tools +``` + +#### 3. Add Custom Packages + +```bash +# Add your custom packages to appropriate files +echo "my-custom-tool" >> packages/macos/core.txt +echo "my-custom-app" >> packages/macos/gui-apps.txt +``` + +#### 4. Validate + +```bash +./scripts/validate-packages.sh +``` + +### Keeping Brewfile Temporarily + +The old `Brewfile` is **kept for backward compatibility** during the transition: + +```bash +# You can still use Brewfile +brew bundle install + +# But new system is recommended +./install.sh --only homebrew --force +``` + +**Deprecation timeline**: +- **v2.0.0 - v2.2.0**: Brewfile kept, both systems work +- **v2.3.0+**: Brewfile will be removed (planned) + +## Configuration Changes + +### Configuration File Support + +**New**: Create `~/.dotfiles.env` to set defaults: + +```bash +# Example ~/.dotfiles.env +SKIP_COMPONENTS="rust,lua" +ONLY_COMPONENTS="shell,neovim" +NON_INTERACTIVE=true +BACKUP_DIR="$HOME/.config/dotfiles-backups" +``` + +See `.dotfiles.env.example` for all options. + +### Platform Detection + +The new system auto-detects your platform: + +```bash +# In .zshrc, configs, etc. +if [[ "$OS" == "macos" ]]; then + # macOS-specific config +elif [[ "$OS" == "linux" ]]; then + # Linux-specific config +fi +``` + +### Conditional Stowing + +Platform-specific configs are automatically skipped: + +- **macOS**: yabai, skhd, sketchybar configs are used +- **Linux**: i3, rofi configs are used (if present) +- **WSL**: Desktop environment configs are skipped + +## Rollback Instructions + +If something goes wrong, you can rollback to the old version. + +### Quick Rollback + +```bash +# Stop if something breaks +cd ~/.dotfiles + +# Restore backup +rm -rf ~/.dotfiles +mv ~/.dotfiles.backup.v1 ~/.dotfiles + +# Restore configs +cp ~/.zshrc.backup ~/.zshrc +cp ~/.tmux.conf.backup ~/.tmux.conf + +# Reload shell +exec zsh +``` + +### Detailed Rollback + +#### 1. Restore Dotfiles Repository + +```bash +cd ~/.dotfiles + +# Find commit before migration +git log --oneline +# Note the commit hash before v2.0.0 + +# Reset to old version +git reset --hard + +# Or restore from backup +cd ~ +rm -rf ~/.dotfiles +mv ~/.dotfiles.backup.v1 ~/.dotfiles +``` + +#### 2. Restore Symlinks + +```bash +# Remove new symlinks +cd ~/.dotfiles +stow -D -t ~ -d "$DOTFILES" files + +# Restore old symlinks (if different) +stow -R -t ~ -d "$DOTFILES" files +``` + +#### 3. Restore Packages + +```bash +# macOS: Use old Brewfile +cd ~/.dotfiles +brew bundle install + +# Clean up any v2.0.0 packages +# (optional, only if you want to remove new packages) +``` + +#### 4. Verify Rollback + +```bash +# Check git version +cd ~/.dotfiles +git log -1 --oneline + +# Test shell +exec zsh + +# Test commands +nvim --version +tmux -V +``` + +### Reporting Issues + +If you had to rollback, please report the issue: + +```bash +# Include: +# - OS and version +# - Error messages +# - Steps that led to the problem +# - Contents of ~/.dotfiles-install.log (if exists) +``` + +[Open an issue on GitHub](https://github.com/jrock2004/dotfiles/issues) + +## Troubleshooting + +### Issue: "Command not found" after migration + +**Solution**: +```bash +# Reload shell configuration +exec zsh + +# Or source manually +source ~/.zshrc + +# Check PATH +echo $PATH +``` + +### Issue: Stow conflicts + +**Symptom**: `WARNING! stowing files would cause conflicts` + +**Solution**: +```bash +# Backup conflicting files +mv ~/.zshrc ~/.zshrc.old +mv ~/.tmux.conf ~/.tmux.conf.old + +# Re-run stow +./install.sh --only stow --force +``` + +### Issue: Missing packages after migration + +**Symptom**: Some tools not installed + +**Solution**: +```bash +# Check what packages were migrated +./scripts/validate-packages.sh + +# Manually add missing packages +echo "missing-package" >> packages/macos/core.txt + +# Reinstall +./install.sh --only homebrew --force +``` + +### Issue: Brewfile migration fails + +**Symptom**: `migrate-brewfile.sh` reports errors + +**Solution**: +```bash +# Manual migration +# 1. List current packages +brew leaves > ~/packages.txt + +# 2. Categorize manually +# 3. Add to appropriate package files + +# 4. Validate +./scripts/validate-packages.sh +``` + +### Issue: Neovim plugins broken + +**Symptom**: Neovim errors on startup + +**Solution**: +```bash +# Remove plugin cache +rm -rf ~/.local/share/nvim +rm -rf ~/.local/state/nvim + +# Reinstall plugins +nvim --headless "+Lazy! sync" +qa + +# Or use setup component +./install.sh --only neovim --force +``` + +### Issue: Tmux plugins missing + +**Symptom**: Tmux plugins not loading + +**Solution**: +```bash +# Reinstall TPM +./install.sh --only tmux --force + +# Install plugins +tmux +# Press: Ctrl-b + I (capital I) +``` + +### Issue: Shell theme broken + +**Symptom**: Prompt looks wrong + +**macOS**: +```bash +# Reconfigure Powerlevel10k +p10k configure +``` + +**Linux/WSL**: +```bash +# Check Starship config +cat ~/.config/starship.toml + +# Reinstall Starship +curl -sS https://starship.rs/install.sh | sh +``` + +## FAQ + +### Q: Do I need to migrate? + +**A**: Not immediately, but recommended for: +- Cross-platform support +- New features (dry-run, selective install, etc.) +- Better error handling and reliability +- Future updates and improvements + +### Q: Can I keep using the old Brewfile? + +**A**: Yes, for now. Brewfile is kept for backward compatibility but will be deprecated in a future version (v2.3.0+). + +### Q: Will my customizations be lost? + +**A**: No, if you: +1. Backup before migrating +2. Review your custom changes (`git status`, `git diff`) +3. Re-apply customizations after migration +4. Add custom packages to new package files + +### Q: How long does migration take? + +**A**: +- Dry-run: 1-2 minutes +- Full migration: 10-30 minutes +- With manual package review: 30-60 minutes + +### Q: Can I migrate incrementally? + +**A**: Yes! Use selective installation: + +```bash +# Migrate shell first +./install.sh --only shell + +# Then neovim +./install.sh --only neovim + +# Continue with other components +./install.sh --only tmux,volta,stow +``` + +### Q: What if I'm on Linux, not macOS? + +**A**: Great! The new system fully supports Linux: + +```bash +# Ubuntu +./install.sh --non-interactive + +# Fedora +./install.sh --non-interactive + +# Arch +./install.sh --non-interactive +``` + +Packages will be installed via apt/dnf/pacman automatically. + +### Q: Will this break my current setup? + +**A**: Not if you: +1. Backup first +2. Use dry-run mode +3. Test before committing +4. Follow rollback instructions if needed + +The installer creates automatic backups before overwriting configs. + +### Q: Can I use v2.0.0 on multiple machines? + +**A**: Yes! That's one of the benefits: + +```bash +# Machine 1 (macOS) +./install.sh --non-interactive + +# Machine 2 (Linux) +./install.sh --non-interactive + +# Same dotfiles, different platform detection +``` + +### Q: Where can I get help? + +**A**: +- Check this migration guide +- Read `README.md` for usage +- Check `CLAUDE.md` for detailed architecture +- Open GitHub issue for bugs +- Check existing issues for solutions + +## Success Checklist + +After migration, verify these are working: + +- [ ] Shell starts without errors +- [ ] Prompt theme displays correctly +- [ ] Neovim opens and plugins load +- [ ] Tmux starts and plugins work +- [ ] Git configured with your info +- [ ] Node.js available via Volta +- [ ] All custom aliases work +- [ ] All custom functions work +- [ ] Window manager works (if using) +- [ ] Terminal emulator configured correctly +- [ ] No error messages in logs +- [ ] Can edit files in `files/` and run `sync` +- [ ] `./update.sh --dry-run` works +- [ ] `./uninstall.sh --dry-run` works + +## Next Steps + +After successful migration: + +1. **Star the repository** on GitHub (if helpful) +2. **Share feedback** via issues or discussions +3. **Contribute improvements** (see CONTRIBUTING.md) +4. **Set up other machines** with the new system +5. **Explore new features**: + - Try dry-run mode + - Test selective installation + - Use configuration file + - Run package validation + +--- + +**Need more help?** Open an issue on [GitHub](https://github.com/jrock2004/dotfiles/issues) with: +- OS and version +- Error messages +- Steps you've tried +- Contents of `~/.dotfiles-install.log` + +Happy migrating! 🚀 diff --git a/README.md b/README.md index c59975e4..e3f09d5c 100644 --- a/README.md +++ b/README.md @@ -10,32 +10,536 @@ :sparkles: John's Dotfiles :sparkles:

+

+ Cross-platform dotfiles for macOS, Linux, and WSL +

+ +

+ Quick Start • + Features • + Platforms • + Installation • + Usage • + Troubleshooting +

+
# Thanks for dropping by! This repository contains my personal dotfiles, which are configuration files and scripts that customize various aspects of my system. By keeping my dotfiles under version control, I can easily synchronize them across multiple machines and ensure consistency in my development environment. -# Tested OS +These dotfiles use a **modular, component-based architecture** with **cross-platform support** for macOS, Linux distributions (Ubuntu, Fedora, Arch), and WSL. The installation system is **idempotent** (safe to run multiple times) and includes automatic backups, rollback on failure, and comprehensive error handling. + +## ✨ Features + +- **Cross-Platform Support**: Works on macOS (Intel & ARM), Ubuntu, Fedora, Arch Linux, and WSL +- **Modular Architecture**: Component-based installation system +- **Package Management**: Cross-platform package system with OS-specific mappings +- **Idempotent**: Safe to run multiple times without breaking your system +- **Automatic Backups**: Creates backups before overwriting configs +- **Rollback on Failure**: Automatically restores backups if installation fails +- **Interactive UI**: Beautiful prompts with gum/fzf fallbacks +- **Dry-Run Mode**: Preview changes before applying them +- **Selective Installation**: Install only the components you need +- **CI/CD Tested**: Automated testing on macOS and multiple Linux distros +- **Comprehensive Documentation**: Detailed guides for all platforms + +## 🖥️ Supported Platforms + +| Platform | Status | Package Manager | Notes | +|----------|--------|----------------|-------| +| macOS (Intel) | ✅ Fully Supported | Homebrew | Main development platform | +| macOS (ARM) | ✅ Fully Supported | Homebrew | M1/M2/M3 with Rosetta | +| Ubuntu/Debian | ✅ Fully Supported | apt-get | Tested on 20.04+ | +| Fedora/RHEL | ✅ Fully Supported | dnf | Tested on Fedora 38+ | +| Arch Linux | ✅ Fully Supported | pacman | AUR via yay (optional) | +| WSL1/WSL2 | ✅ Fully Supported | distro-based | Ubuntu, Fedora, or Arch | + +## 📦 What's Included + +### Core Tools +- **Shell**: zsh with Powerlevel10k (macOS) or Starship (Linux/WSL) +- **Editors**: Neovim (LazyVim), VS Code, Cursor +- **Terminal Emulators**: Ghostty, Alacritty, Kitty, WezTerm +- **Terminal Multiplexers**: tmux, zellij +- **Version Managers**: Volta (Node.js), rustup (Rust) +- **CLI Tools**: fzf, ripgrep, fd, eza, bat, jq, lazygit, lazydocker -- Mac OSX +### macOS-Specific +- **Window Management**: yabai + skhd + sketchybar +- **Package Manager**: Homebrew +- **Theme**: Powerlevel10k -# Installation +### Linux-Specific +- **Window Management**: i3/sway (optional) +- **Package Managers**: apt/dnf/pacman, Flatpak/Snap (optional) +- **Prompt**: Starship + +### Development +- **Languages**: Go, Python, Lua, Rust +- **Tools**: prettier, stylua, shellcheck +- **Git**: lazygit, gh (GitHub CLI) + +## 🚀 Quick Start + +### One-Line Install (All Platforms) ```bash +# Automatic OS detection and installation bash <(curl -L https://raw.githubusercontent.com/jrock2004/dotfiles/main/scripts/curl-install.sh) ``` -# Customize and Extend +### Local Install + +```bash +# Clone the repository +git clone https://github.com/jrock2004/dotfiles.git ~/.dotfiles +cd ~/.dotfiles + +# Run installer (interactive mode) +./install.sh + +# Or run in non-interactive mode (CI/automation) +./install.sh --non-interactive +``` + +## 📋 Prerequisites + +### macOS +- **Xcode Command Line Tools** (installed automatically) +- **Rosetta 2** (ARM Macs, installed automatically if needed) + +```bash +# Manual installation (if needed) +xcode-select --install +``` + +### Ubuntu/Debian +```bash +sudo apt-get update +sudo apt-get install -y git curl build-essential +``` + +### Fedora/RHEL +```bash +sudo dnf update +sudo dnf groupinstall -y "Development Tools" +sudo dnf install -y git curl +``` + +### Arch Linux +```bash +sudo pacman -Syu +sudo pacman -S --needed base-devel git curl +``` + +### WSL (Windows Subsystem for Linux) +- **WSL2** recommended for better performance +- **Base distro** installed (Ubuntu, Fedora, or Arch) +- Follow prerequisite steps for your chosen distro above + +## 📦 Installation + +### Interactive Installation (Recommended) + +```bash +./install.sh +``` + +This will: +1. Detect your OS and architecture +2. Install package manager if needed +3. Show component selection menu +4. Install selected components +5. Configure OS-specific features +6. Symlink dotfiles to your home directory +7. Create backups of existing configs + +### Non-Interactive Installation + +```bash +# Use defaults, skip all prompts +./install.sh --non-interactive +``` + +### Selective Installation + +```bash +# Install only specific components +./install.sh --only shell,neovim,tmux + +# Skip specific components +./install.sh --skip lua,rust + +# List all available components +./install.sh --list-components +``` + +### Dry-Run Mode + +```bash +# Preview what would be installed without executing +./install.sh --dry-run +``` + +## 🎛️ CLI Options + +```bash +# Display help +./install.sh --help + +# Show version +./install.sh --version + +# List all available components +./install.sh --list-components + +# Preview actions without executing +./install.sh --dry-run + +# Non-interactive mode (use defaults) +./install.sh --non-interactive + +# Force reinstall even if already installed +./install.sh --force + +# Skip specific components +./install.sh --skip , + +# Install only specific components +./install.sh --only , +``` + +## 🔧 Available Components + +- `directories` - Create standard directories (~/.local/bin, ~/projects, etc.) +- `homebrew` - Install Homebrew and packages (macOS) +- `vscode` - Install VS Code extensions +- `fonts` - Install Nerd Fonts +- `claude` - Install Claude Code CLI +- `fzf` - Install FZF (fuzzy finder) +- `lua` - Install Lua language server +- `neovim` - Install Neovim dependencies (pynvim) +- `rust` - Install Rust toolchain (rustup) +- `shell` - Configure zsh, zap plugin manager +- `tmux` - Install Tmux Plugin Manager (tpm) +- `volta` - Install Volta and Node.js +- `stow` - Symlink dotfiles with GNU Stow +- `macos-defaults` - Configure macOS defaults (macOS only) + +## 🔄 Usage + +### Managing Dotfiles + +```bash +# Apply/update symlinks (after editing files in files/) +sync + +# Remove symlinks +unsync +``` + +**Important**: All configuration files live in `files/` and are symlinked to `$HOME`. Always edit files in `files/.config/` or `files/`, never the symlinked versions in `$HOME`. + +### Updating Dotfiles + +```bash +# Pull latest changes and re-apply +./update.sh + +# Update without updating packages +./update.sh --no-packages + +# Preview update without executing +./update.sh --dry-run +``` + +### Uninstalling + +```bash +# Remove dotfile symlinks only +./uninstall.sh + +# Remove symlinks and installed packages +./uninstall.sh --remove-packages + +# Preview what would be removed +./uninstall.sh --dry-run +``` + +### Adding New Packages + +**Cross-platform tools**: +```bash +# Add to packages/common.txt +echo "newtool" >> packages/common.txt + +# Add platform-specific name mappings if needed +echo "newtool=newtool-bin" >> packages/mappings/common-to-ubuntu.map + +# Validate +./scripts/validate-packages.sh + +# Install +./scripts/install.sh --only homebrew --force +``` + +**Platform-specific tools**: +```bash +# macOS +echo "package-name" >> packages/macos/core.txt + +# Linux +echo "package-name" >> packages/linux/core.txt + +# Reinstall packages +./scripts/install.sh --only homebrew --force +``` + +### Testing Changes + +```bash +# Run ShellCheck on all scripts +./scripts/test-shellcheck.sh + +# Run integration tests +./scripts/test-integration.sh + +# Test in Docker (Ubuntu) +./test/test-docker.sh ubuntu --build +``` + +## 🛠️ Configuration + +### Configuration File + +Create `~/.dotfiles.env` to set default options: + +```bash +# Skip specific components +SKIP_COMPONENTS="rust,lua" + +# Install only specific components +ONLY_COMPONENTS="shell,neovim" + +# Custom backup location +BACKUP_DIR="$HOME/.config/dotfiles-backups" + +# Non-interactive mode +NON_INTERACTIVE=true + +# Dry-run mode +DRY_RUN=true + +# Force reinstall +FORCE_INSTALL=true +``` + +See `.dotfiles.env.example` for all available options. + +### Platform-Specific Configuration + +The dotfiles automatically detect your platform and apply the appropriate configuration: + +- **macOS**: Uses Homebrew, Powerlevel10k theme, yabai/skhd window management +- **Linux**: Uses apt/dnf/pacman, Starship prompt, optional i3/sway +- **WSL**: Uses distro package manager, Starship prompt, Windows interop + +## 🐛 Troubleshooting + +### Common Issues + +**"Command not found" after installation**: +```bash +# Reload shell configuration +exec zsh +``` + +**Stow conflicts**: +```bash +# Backup and remove conflicting files +mv ~/.zshrc ~/.zshrc.backup +mv ~/.tmux.conf ~/.tmux.conf.backup + +# Re-run stow +./install.sh --only stow --force +``` + +**Homebrew not in PATH (macOS)**: +```bash +# Intel Macs +echo 'eval "$(/usr/local/bin/brew shellenv)"' >> ~/.zprofile + +# ARM Macs (M1/M2/M3) +echo 'eval "$(/opt/homebrew/bin/brew shellenv)"' >> ~/.zprofile + +# Reload +source ~/.zprofile +``` + +**Permission denied errors (Linux)**: +```bash +# Ensure scripts are executable +chmod +x install.sh update.sh uninstall.sh +chmod +x scripts/*.sh +``` + +**Neovim version too old (Linux)**: +```bash +# Ubuntu: Add Neovim PPA +sudo add-apt-repository ppa:neovim-ppa/unstable +sudo apt update +sudo apt install neovim + +# Fedora: Use copr +sudo dnf copr enable agriffis/neovim-nightly +sudo dnf install neovim + +# Arch: Use pacman +sudo pacman -S neovim +``` + +**WSL systemd not working**: +```bash +# Enable systemd in /etc/wsl.conf +echo "[boot]" | sudo tee /etc/wsl.conf +echo "systemd=true" | sudo tee -a /etc/wsl.conf + +# Restart WSL +wsl.exe --shutdown +# Then reopen WSL +``` + +### Getting Help + +```bash +# Show help +./install.sh --help + +# Check version +./install.sh --version + +# Preview what would be installed +./install.sh --dry-run + +# Check logs +tail -f ~/.dotfiles-install.log +``` + +For more detailed troubleshooting, see `CLAUDE.md` or the platform-specific documentation in `docs/`. + +## 📚 Documentation + +- **CLAUDE.md** - Comprehensive guide for Claude Code (AI assistant) +- **CONTRIBUTING.md** - Contribution guidelines (to be created) +- **MIGRATION.md** - Migration guide from old system (to be created) +- **docs/MACOS.md** - macOS-specific documentation (to be created) +- **docs/LINUX.md** - Linux-specific documentation (to be created) +- **docs/WSL.md** - WSL-specific documentation (to be created) + +## 🏗️ Architecture + +This repository uses a **modular, component-based architecture**: + +``` +dotfiles/ +├── files/ # Dotfiles to be symlinked to $HOME +├── packages/ # Cross-platform package management +│ ├── common.txt # Cross-platform tools +│ ├── optional.txt # Optional tools +│ ├── macos/ # macOS-specific packages +│ ├── linux/ # Linux-specific packages +│ ├── wsl/ # WSL-specific packages +│ └── mappings/ # Package name mappings +├── scripts/ # Installation scripts +│ ├── lib/ # Shared libraries +│ ├── os/ # OS-specific orchestration +│ ├── components/ # Component setup functions +│ ├── install.sh # Main installer +│ ├── update.sh # Update script +│ └── uninstall.sh # Uninstall script +├── test/ # Docker test environments +└── .github/workflows/ # CI/CD pipelines +``` -Feel free to modify and customize these dotfiles to suit your needs. Add your own configurations, aliases, and functions, or remove those that you don't find useful. Don't forget to keep your modifications under version control to track your changes. +### Key Features -If you come across useful improvements or additions that you think would benefit others, please consider contributing them back to the repository through pull requests. Sharing your knowledge and enhancements with the community is highly appreciated. +- **Package Abstraction Layer**: Single interface for Homebrew, apt, dnf, pacman +- **OS Detection**: Automatically detects macOS, Linux distro, WSL +- **Component Dependencies**: Proper ordering and dependency management +- **Error Handling**: Comprehensive error handling with rollback +- **Idempotent**: All operations can be run multiple times safely +- **Testing**: CI/CD with GitHub Actions, Docker tests, ShellCheck -# Acknowledgements +## 🧪 Testing + +All shell scripts are tested with: +- **ShellCheck**: Static analysis for shell scripts +- **Integration Tests**: Verify installation works correctly +- **Docker Tests**: Test on Ubuntu, Fedora, and Arch +- **CI/CD**: Automated testing on macOS and Linux via GitHub Actions + +```bash +# Run all tests +./scripts/test-shellcheck.sh +./scripts/test-integration.sh +./test/test-docker.sh ubuntu fedora arch +``` + +## 🤝 Contributing + +Contributions are welcome! Whether it's bug fixes, new features, documentation improvements, or platform support, your help is appreciated. + +See `CONTRIBUTING.md` (to be created) for detailed guidelines. + +## 🔄 Migration from Old System + +If you're upgrading from the old monolithic install.sh: + +1. **Backup your current setup**: + ```bash + cp -r ~/.dotfiles ~/.dotfiles.backup.old + ``` + +2. **Pull latest changes**: + ```bash + cd ~/.dotfiles + git pull origin main + ``` + +3. **Run new installer**: + ```bash + ./install.sh --dry-run # Preview first + ./install.sh # Then install + ``` + +4. **Migrate Brewfile** (macOS only): + ```bash + ./scripts/migrate-brewfile.sh + ``` + +See `MIGRATION.md` (to be created) for detailed migration guide. + +## 📝 License + +This project is open source and available under the MIT License. + +## 🙏 Acknowledgements I would like to acknowledge the open-source community and the countless developers who have shared their dotfiles, tips, and tricks. Your contributions have been invaluable in shaping and improving my own setup. +Special thanks to: - [Nick Nisi](https://github.com/nicknisi/dotfiles) - [Christian Chiarulli](https://www.chrisatmachine.com/) - [Dorian Karter](https://github.com/dkarter/dotfiles) + +## ⭐ Show Your Support + +If you found this repository helpful, please consider giving it a star! It helps others discover these dotfiles and motivates me to keep improving them. + +--- + +

+ Made with ❤️ by John Costanzo +

diff --git a/docs/LINUX.md b/docs/LINUX.md new file mode 100644 index 00000000..632523c4 --- /dev/null +++ b/docs/LINUX.md @@ -0,0 +1,860 @@ +# Linux-Specific Documentation + +This guide covers Linux-specific features, configurations, and troubleshooting for the dotfiles across multiple distributions. + +## Table of Contents + +- [Overview](#overview) +- [Supported Distributions](#supported-distributions) +- [Prerequisites](#prerequisites) +- [Installation](#installation) +- [Package Management](#package-management) +- [Shell Configuration](#shell-configuration) +- [Window Management](#window-management) +- [Fonts](#fonts) +- [Distribution-Specific Notes](#distribution-specific-notes) +- [Troubleshooting](#troubleshooting) +- [Performance Tips](#performance-tips) + +## Overview + +The dotfiles support multiple Linux distributions with automatic detection and platform-specific package installation: + +**Supported Features**: +- **Package Management**: apt, dnf, pacman with automatic detection +- **Shell Theme**: Starship prompt (cross-platform, fast) +- **Fonts**: Nerd Fonts via direct downloads +- **Window Management**: i3/sway (optional, not installed by default) +- **Display Managers**: Works with GNOME, KDE, Xfce, i3, sway + +**Supported Architectures**: +- x86_64 (AMD64) +- ARM64 (aarch64) + +## Supported Distributions + +| Distribution | Package Manager | Status | Tested Versions | +|-------------|----------------|--------|----------------| +| Ubuntu | apt-get | ✅ Fully Supported | 20.04, 22.04, 24.04 | +| Debian | apt-get | ✅ Fully Supported | 11 (Bullseye), 12 (Bookworm) | +| Fedora | dnf | ✅ Fully Supported | 38, 39, 40 | +| RHEL/Rocky/Alma | dnf | ✅ Fully Supported | 8, 9 | +| Arch Linux | pacman | ✅ Fully Supported | Rolling | +| Manjaro | pacman | ✅ Fully Supported | Rolling | + +**Planned Support**: +- openSUSE (zypper) +- Gentoo (emerge) +- NixOS (nix) + +## Prerequisites + +### Ubuntu/Debian + +```bash +# Update package list +sudo apt-get update + +# Install build tools +sudo apt-get install -y build-essential + +# Install required tools +sudo apt-get install -y git curl wget + +# Optional: add-apt-repository (for PPAs) +sudo apt-get install -y software-properties-common +``` + +### Fedora/RHEL + +```bash +# Update system +sudo dnf update + +# Install development tools +sudo dnf groupinstall -y "Development Tools" + +# Install required tools +sudo dnf install -y git curl wget + +# Optional: enable EPEL (RHEL/Rocky/Alma) +sudo dnf install -y epel-release +``` + +### Arch Linux + +```bash +# Update system +sudo pacman -Syu + +# Install base development tools +sudo pacman -S --needed base-devel + +# Install required tools +sudo pacman -S git curl wget +``` + +**Optional: Install yay (AUR helper)**: +```bash +git clone https://aur.archlinux.org/yay.git +cd yay +makepkg -si +``` + +## Installation + +### Quick Install + +```bash +# One-line install (auto-detects distribution) +bash <(curl -L https://raw.githubusercontent.com/jrock2004/dotfiles/main/scripts/curl-install.sh) +``` + +### Local Install + +```bash +# Clone repository +git clone https://github.com/jrock2004/dotfiles.git ~/.dotfiles +cd ~/.dotfiles + +# Interactive installation +./install.sh + +# Non-interactive (recommended for Linux) +./install.sh --non-interactive +``` + +### Selective Installation + +```bash +# Install minimal setup +./install.sh --only shell,stow + +# Install development tools +./install.sh --only shell,neovim,tmux,volta,stow + +# Skip components +./install.sh --skip lua,rust,claude +``` + +## Package Management + +### Package Files Structure + +``` +packages/ +├── common.txt # Cross-platform CLI tools +├── optional.txt # Optional tools +├── linux/ +│ ├── core.txt # Linux-specific CLI tools +│ ├── gui-apps.txt # GUI apps (native packages) +│ ├── gui-apps-flatpak.txt # Flatpak apps +│ └── gui-apps-snap.txt # Snap apps +├── mappings/ +│ ├── common-to-ubuntu.map # Ubuntu package name mappings +│ ├── common-to-fedora.map # Fedora package name mappings +│ └── common-to-arch.map # Arch package name mappings +``` + +### Adding Packages + +**Cross-platform CLI tools**: +```bash +# Add to common.txt +echo "htop" >> packages/common.txt + +# Add mappings if package name differs +echo "htop=htop" >> packages/mappings/common-to-ubuntu.map +echo "htop=htop" >> packages/mappings/common-to-fedora.map +echo "htop=htop" >> packages/mappings/common-to-arch.map + +# Validate +./scripts/validate-packages.sh + +# Install +./scripts/install.sh --only homebrew --force +``` + +**Linux-specific packages**: +```bash +# Native packages +echo "package-name" >> packages/linux/core.txt + +# Flatpak apps +echo "org.gimp.GIMP" >> packages/linux/gui-apps-flatpak.txt + +# Snap apps +echo "vlc" >> packages/linux/gui-apps-snap.txt +``` + +### Package Manager Commands + +#### Ubuntu/Debian (apt-get) + +```bash +# Update package list +sudo apt-get update + +# Install package +sudo apt-get install -y package-name + +# Upgrade all packages +sudo apt-get upgrade + +# Search for package +apt-cache search package-name + +# Remove package +sudo apt-get remove package-name + +# Clean up +sudo apt-get autoremove +sudo apt-get autoclean +``` + +#### Fedora/RHEL (dnf) + +```bash +# Update system +sudo dnf update + +# Install package +sudo dnf install -y package-name + +# Search for package +dnf search package-name + +# Remove package +sudo dnf remove package-name + +# Clean up +sudo dnf autoremove +sudo dnf clean all +``` + +#### Arch Linux (pacman) + +```bash +# Update system +sudo pacman -Syu + +# Install package +sudo pacman -S package-name + +# Search for package +pacman -Ss package-name + +# Remove package +sudo pacman -R package-name + +# Clean cache +sudo pacman -Sc +``` + +**AUR packages (with yay)**: +```bash +# Install from AUR +yay -S package-name + +# Update AUR packages +yay -Syu +``` + +### Flatpak + +**Setup**: +```bash +# Ubuntu/Debian +sudo apt-get install -y flatpak + +# Fedora (usually pre-installed) +sudo dnf install -y flatpak + +# Arch +sudo pacman -S flatpak + +# Add Flathub repository +flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo +``` + +**Usage**: +```bash +# Install app +flatpak install flathub org.gimp.GIMP + +# List installed +flatpak list + +# Update all +flatpak update + +# Remove app +flatpak uninstall org.gimp.GIMP +``` + +### Snap + +**Setup**: +```bash +# Ubuntu (usually pre-installed) +sudo apt-get install -y snapd + +# Fedora +sudo dnf install -y snapd +sudo ln -s /var/lib/snapd/snap /snap + +# Arch +yay -S snapd +sudo systemctl enable --now snapd.socket +sudo ln -s /var/lib/snapd/snap /snap +``` + +**Usage**: +```bash +# Install app +sudo snap install app-name + +# List installed +snap list + +# Update all +sudo snap refresh + +# Remove app +sudo snap remove app-name +``` + +## Shell Configuration + +### Starship Prompt + +**Starship** replaces Powerlevel10k on Linux (cross-platform, Rust-based, fast): + +**Installation**: +```bash +# Via dotfiles installer +./install.sh --only shell + +# Or manually +curl -sS https://starship.rs/install.sh | sh +``` + +**Configuration**: `~/.config/starship.toml` + +**Customize**: +```bash +# Edit config +nvim ~/.config/starship.toml + +# Reload shell +exec zsh +``` + +**Example config**: +```toml +# Get editor completions based on the config schema +"$schema" = 'https://starship.rs/config-schema.json' + +# Prompt format +format = """ +[┌───────────────────>](bold green) +[│](bold green)$directory$git_branch$git_status +[└─>](bold green) """ + +# Directory module +[directory] +truncation_length = 3 +truncate_to_repo = true +format = "[$path]($style)[$read_only]($read_only_style) " + +# Git branch +[git_branch] +symbol = " " +format = "[$symbol$branch]($style) " + +# Git status +[git_status] +format = '([\[$all_status$ahead_behind\]]($style) )' +``` + +**Presets**: +```bash +# Try different presets +starship preset nerd-font-symbols -o ~/.config/starship.toml +starship preset pure-preset -o ~/.config/starship.toml +starship preset gruvbox-rainbow -o ~/.config/starship.toml +``` + +### zsh Configuration + +**Shell setup** via dotfiles includes: +- zsh as default shell +- zap plugin manager +- Starship prompt +- Custom functions and aliases +- fzf integration +- Syntax highlighting +- Autosuggestions + +**Change default shell**: +```bash +# Check current shell +echo $SHELL + +# Change to zsh +chsh -s $(which zsh) + +# Verify (requires logout/login) +echo $SHELL +``` + +## Window Management + +### i3 Window Manager + +**Optional i3 installation** (not included by default): + +#### Ubuntu/Debian + +```bash +sudo apt-get install -y i3-wm i3status i3lock dmenu + +# Add to .xinitrc +echo "exec i3" >> ~/.xinitrc +``` + +#### Fedora + +```bash +sudo dnf install -y i3 i3status i3lock dmenu + +# Select i3 from login screen +``` + +#### Arch + +```bash +sudo pacman -S i3-wm i3status i3lock dmenu + +# Add to .xinitrc +echo "exec i3" >> ~/.xinitrc +``` + +**Configuration**: `~/.config/i3/config` (create custom config if needed) + +### Sway (Wayland Compositor) + +**Modern i3 alternative** for Wayland: + +```bash +# Ubuntu/Debian +sudo apt-get install -y sway swaylock swayidle wofi + +# Fedora +sudo dnf install -y sway swaylock swayidle wofi + +# Arch +sudo pacman -S sway swaylock swayidle wofi +``` + +**Configuration**: `~/.config/sway/config` + +## Fonts + +### Nerd Fonts Installation + +**Fonts installed to**: `~/.local/share/fonts/` + +**Via dotfiles installer**: +```bash +./install.sh --only fonts +``` + +**Manual installation**: +```bash +# Create fonts directory +mkdir -p ~/.local/share/fonts + +# Download Nerd Font (example: Meslo) +cd ~/.local/share/fonts +curl -fLo "Meslo LG S Regular Nerd Font Complete.ttf" \ + https://github.com/ryanoasis/nerd-fonts/raw/master/patched-fonts/Meslo/S/Regular/MesloLGSNerdFont-Regular.ttf + +# Refresh font cache +fc-cache -fv + +# Verify +fc-list | grep -i meslo +``` + +**Recommended Nerd Fonts**: +- Meslo LG Nerd Font +- Hack Nerd Font +- JetBrains Mono Nerd Font +- Fira Code Nerd Font + +### Terminal Configuration + +**Alacritty** (`~/.config/alacritty/alacritty.yml`): +```yaml +font: + normal: + family: "MesloLGS Nerd Font" + size: 12.0 +``` + +**Kitty** (`~/.config/kitty/kitty.conf`): +``` +font_family MesloLGS Nerd Font +font_size 12.0 +``` + +**WezTerm** (`~/.config/wezterm/wezterm.lua`): +```lua +config.font = wezterm.font("MesloLGS Nerd Font") +config.font_size = 12.0 +``` + +**GNOME Terminal**: +```bash +# Set font via GUI: Preferences → Profile → Text → Custom font +# Or via gsettings: +gsettings set org.gnome.desktop.interface monospace-font-name 'MesloLGS Nerd Font 12' +``` + +## Distribution-Specific Notes + +### Ubuntu/Debian + +**PPAs for newer software**: +```bash +# Neovim (latest stable) +sudo add-apt-repository ppa:neovim-ppa/stable +sudo apt-get update +sudo apt-get install neovim + +# Zsh (latest) +sudo add-apt-repository ppa:zsh-users/zsh +sudo apt-get update +sudo apt-get install zsh +``` + +**Package name differences**: +- `fd` → `fd-find` +- `bat` → `batcat` + +**Create aliases** if needed: +```bash +# Add to ~/.zshrc +alias fd='fd-find' +alias bat='batcat' +``` + +### Fedora/RHEL + +**Enable EPEL** (RHEL/Rocky/Alma): +```bash +sudo dnf install -y epel-release +``` + +**Copr repositories** (like PPAs): +```bash +# Neovim nightly +sudo dnf copr enable agriffis/neovim-nightly +sudo dnf install neovim +``` + +**DNF config optimization**: +```bash +# Edit /etc/dnf/dnf.conf +sudo tee -a /etc/dnf/dnf.conf <