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