1
0
Fork 0
mirror of https://github.com/SeriousBug/dotfiles synced 2026-05-01 05:05:18 -05:00
dotfiles/setup.sh
Kaan Barmore-Genc c82e17654e Add discord-send CLI and personal CLAUDE.md
discord-send is a Bun script that posts to a Discord webhook (URL read
from ~/.config/discord-send/webhook), with optional --attach for files.
The personal CLAUDE.md tells Claude Code to use it for notifications
and image sharing. Both deploy via Dotter.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-19 23:03:18 -05:00

274 lines
7.5 KiB
Bash
Executable file

#!/usr/bin/env bash
set -eo pipefail
# Function to manage directory symlinks
# Usage: ensure_dir_symlink <source_dir> <target_link> <force_flag>
# Args:
# source_dir: The actual directory to symlink to (must be absolute path)
# target_link: The symlink location to create
# force_flag: true/false - whether to force replacement if exists
ensure_dir_symlink() {
local source_dir="$1"
local target_link="$2"
local force_flag="$3"
# Expand tilde in paths
target_link="${target_link/#\~/$HOME}"
source_dir="${source_dir/#\~/$HOME}"
# Check if target exists
if [[ -e "$target_link" || -L "$target_link" ]]; then
# Check if it's already a symlink pointing to the right place
if [[ -L "$target_link" ]]; then
local current_target
current_target="$(readlink "$target_link")"
if [[ "$current_target" == "$source_dir" ]]; then
echo "$target_link already symlinked correctly"
return 0
else
# Symlink exists but points to wrong location
if [[ "$force_flag" == true ]]; then
echo "Replacing symlink $target_link (currently points to $current_target)"
rm "$target_link"
else
echo "⚠ Warning: $target_link exists but points to $current_target (expected $source_dir)"
echo " Run with --force-deploy to replace it"
return 0
fi
fi
else
# Path exists but is not a symlink
if [[ "$force_flag" == true ]]; then
echo "Replacing $target_link with symlink (was a regular file/directory)"
rm -rf "$target_link"
else
echo "⚠ Warning: $target_link exists but is not a symlink"
echo " Run with --force-deploy to replace it"
return 0
fi
fi
fi
# Create parent directory if needed
local parent_dir
parent_dir="$(dirname "$target_link")"
if [[ ! -d "$parent_dir" ]]; then
echo "Creating parent directory: $parent_dir"
mkdir -p "$parent_dir"
fi
# Create the symlink
echo "Creating symlink: $target_link -> $source_dir"
ln -s "$source_dir" "$target_link"
echo "✓ Successfully created symlink"
}
# Parse command line arguments
RESET_CONFIG=false
FORCE_DEPLOY=false
SKIP_BREW=false
for arg in "$@"; do
case $arg in
--reset)
RESET_CONFIG=true
echo "Resetting configuration (will re-prompt for all variables)..."
;;
--force-deploy)
FORCE_DEPLOY=true
echo "Force deployment mode enabled..."
;;
--skip-brew)
SKIP_BREW=true
echo "Skipping Homebrew package installation..."
;;
*)
echo "Unknown option: $arg"
echo "Usage: $0 [--reset] [--force-deploy] [--skip-brew]"
exit 1
;;
esac
done
echo "Setting up dotfiles environment..."
# Detect OS
OS="$(uname -s)"
if [[ "$SKIP_BREW" == false ]]; then
# Check if Homebrew is installed
if ! command -v brew &> /dev/null; then
echo "Homebrew is not installed. Please install it first:"
echo "https://brew.sh"
exit 1
fi
echo "Updating Homebrew..."
brew update
# Install packages (available on both macOS and Linux)
PACKAGES=(
dotter
fish
dust
eza
gh
htop
go
jq
lazygit
neovim
asdf
bat
pandoc
ripgrep
zoxide
zellij
p7zip
)
echo "Installing packages..."
for package in "${PACKAGES[@]}"; do
if brew list "$package" &>/dev/null; then
echo "$package already installed"
else
echo "Installing $package..."
brew install "$package"
fi
done
# Install casks on macOS only
if [[ "$OS" == "Darwin" ]]; then
echo "Installing macOS-specific casks..."
CASKS=(
iterm2
font-fira-code-nerd-font
orbstack
rectangle-pro
maccy
)
for cask in "${CASKS[@]}"; do
if brew list --cask "$cask" &>/dev/null; then
echo "$cask already installed"
else
echo "Installing $cask..."
brew install --cask "$cask"
fi
done
else
echo "Skipping macOS-specific casks (not on macOS)"
fi
fi
# Set up GitHub CLI authentication
if command -v gh &> /dev/null; then
if ! gh auth status &>/dev/null; then
echo ""
echo "GitHub CLI is installed but not authenticated."
echo "Please log in to GitHub CLI:"
gh auth login
else
echo "✓ GitHub CLI already authenticated"
fi
fi
# Configure Dotter
echo ""
echo "Configuring Dotter..."
# Path to user variables file
USER_VARS_FILE=".dotter/user_vars.sh"
# Source existing variables if not resetting
if [[ "$RESET_CONFIG" == false && -f "$USER_VARS_FILE" ]]; then
echo "Loading existing configuration..."
source "$USER_VARS_FILE"
fi
# Prompt for missing variables
if [[ -z "$GIT_NAME" ]]; then
read -p "Enter your Git user name: " GIT_NAME
fi
if [[ -z "$GIT_EMAIL" ]]; then
read -p "Enter your Git email: " GIT_EMAIL
fi
# Detect Homebrew path if not set
if [[ -z "$BREW_PATH" ]]; then
if [[ "$OS" == "Darwin" ]]; then
if [[ -d "/opt/homebrew" ]]; then
BREW_PATH="/opt/homebrew"
else
BREW_PATH="/usr/local"
fi
else
BREW_PATH="/home/linuxbrew/.linuxbrew"
fi
echo "Detected Homebrew path: $BREW_PATH"
fi
# Save variables to file
echo "Saving configuration..."
cat > "$USER_VARS_FILE" << EOF
# Dotter user variables
# This file is sourced by setup.sh to avoid re-prompting for values
# To reset and re-prompt for all values, run: ./setup.sh --reset
GIT_NAME="$GIT_NAME"
GIT_EMAIL="$GIT_EMAIL"
BREW_PATH="$BREW_PATH"
EOF
# Generate local.toml
echo "Generating Dotter configuration..."
cat > .dotter/local.toml << EOF
# Machine-specific Dotter configuration
# This file is generated by setup.sh
packages = ["git", "nvim", "fish", "zellij", "htop", "asdf", "claude", "bin"]
[variables]
git_name = "$GIT_NAME"
git_email = "$GIT_EMAIL"
brew_path = "$BREW_PATH"
EOF
# Deploy dotfiles
echo ""
echo "Deploying dotfiles..."
if [[ "$FORCE_DEPLOY" == true ]]; then
if dotter deploy -f -v; then
echo "✓ Dotfiles deployed successfully (forced)!"
else
echo "⚠ Dotter deployment failed."
fi
else
if dotter deploy -v; then
echo "✓ Dotfiles deployed successfully!"
else
echo "⚠ Dotter deployment failed. You may need to run 'dotter deploy -f' to force deployment."
fi
fi
# Manage directory symlinks (not handled by Dotter)
echo ""
echo "Setting up directory symlinks..."
DOTFILES_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
ensure_dir_symlink "$DOTFILES_DIR/fish/functions" "~/.config/fish/functions" "$FORCE_DEPLOY"
echo ""
echo "✓ Setup complete!"
echo ""
echo "Configuration saved to: $USER_VARS_FILE"
echo "To reconfigure, run: ./setup.sh --reset"
echo "To force deployment, run: ./setup.sh --force-deploy"
echo "To skip Homebrew packages, run: ./setup.sh --skip-brew"
echo ""
echo "Next steps:"
echo " 1. Consider setting fish as your default shell: chsh -s \$(which fish)"
echo " 2. Restart your terminal or source your new shell configuration"