diff --git a/bin/dot b/bin/dot index 7d717ed1..8b2e7c6c 100755 --- a/bin/dot +++ b/bin/dot @@ -88,47 +88,36 @@ get_system_dir() { echo "$DOT_HOME/$installed_system" } -# Resolve module name (handles numeric prefixes like 00-, 01-) -resolve_module_path() { +# Resolve script name (handles numeric prefixes like 01-50-mise) +resolve_script_name() { local module="$1" + local command="$2" local system_dir="$(get_system_dir)" - - # First, try the module as-is - if [[ -d "$system_dir/$module" ]]; then + local command_dir="$system_dir/$command" + + # First, try the module name as-is + if [[ -f "$command_dir/$module" && -x "$command_dir/$module" ]]; then echo "$module" return 0 fi - - # If module contains /, handle each part - if [[ "$module" == */* ]]; then - local parent="${module%/*}" - local child="${module##*/}" - - # Try with numeric prefix on child - for prefix in {00..99}; do - if [[ -d "$system_dir/$parent/${prefix}-${child}" ]]; then - echo "$parent/${prefix}-${child}" - return 0 - fi - done - - # Try with numeric prefix on parent - for prefix in {00..99}; do - if [[ -d "$system_dir/${prefix}-${parent}/$child" ]]; then - echo "${prefix}-${parent}/$child" - return 0 - fi - done - else - # Try with numeric prefixes for top-level modules - for prefix in {00..99}; do - if [[ -d "$system_dir/${prefix}-${module}" ]]; then - echo "${prefix}-${module}" - return 0 - fi - done + + # Try to find a script that ends with the module name (e.g., "mise" -> "01-50-mise") + local found_script="" + for script in "$command_dir"/*; do + [[ ! -f "$script" || ! -x "$script" ]] && continue + local script_name=$(basename "$script") + # Check if script ends with -$module + if [[ "$script_name" == *-"$module" ]]; then + found_script="$script_name" + break + fi + done + + if [[ -n "$found_script" ]]; then + echo "$found_script" + return 0 fi - + # Return original if no match found echo "$module" return 1 @@ -151,7 +140,7 @@ check_system_for_list() { get_available_modules() { local command="$1" local modules=() - + # Get the installed system type local installed_system if [[ -n "${INSTALLATION:-}" ]]; then @@ -160,28 +149,30 @@ get_available_modules() { installed_system=$(head -n1 "$INSTALLATION_MARKER") fi local system_dir="$DOT_HOME/$installed_system" - - # Check if system directory exists - if [[ ! -d "$system_dir" ]]; then + local command_dir="$system_dir/$command" + + # Check if command directory exists + if [[ ! -d "$command_dir" ]]; then return fi - - # Find all modules with the given command script + + # Find all executable files in the command directory + # Use -perm for BSD find compatibility (macOS) while IFS= read -r -d '' script; do - local module_path=$(dirname "$script") - # Get the full relative path from system_dir - local module_name="${module_path#$system_dir/}" - - modules+=("$module_name") - done < <(find "$system_dir" -name "$command" -type f -executable -print0) - - printf '%s\n' "${modules[@]}" | sort + local script_name=$(basename "$script") + modules+=("$script_name") + done < <(find "$command_dir" -maxdepth 1 -type f -perm +111 -print0 2>/dev/null) + + # Handle empty array to avoid unbound variable error + if [[ ${#modules[@]} -gt 0 ]]; then + printf '%s\n' "${modules[@]}" | sort + fi } # Run install command cmd_install() { local module="${1:-all}" - + # Handle --list option if [[ "$module" == "--list" ]]; then check_system_for_list @@ -189,41 +180,65 @@ cmd_install() { get_available_modules "install" return 0 fi - + check_system_setup init_logging "install" - + log_header "Installing: $module" - + + # Export common variables for scripts + export DOT_HOME="$DOT_HOME" + export SYSTEM_DIR="$(get_system_dir)" + export SHARED_DIR="$DOT_HOME/shared" + if [[ "$module" == "all" ]]; then log_info "Installing all modules" - + # Get all available install scripts - local available_modules - mapfile -t available_modules < <(get_available_modules "install") - - for mod in "${available_modules[@]}"; do - log_step "Running install for module: $mod" - "$(get_system_dir)/$mod/install" + local available_modules=() + while IFS= read -r line; do + [[ -n "$line" ]] && available_modules+=("$line") + done < <(get_available_modules "install") + + for script_name in "${available_modules[@]}"; do + # Extract module name from script filename (e.g., "01-50-mise" -> "mise") + export MODULE_NAME="$(basename "$script_name" | sed 's/^[0-9]*-[0-9]*-//')" + + init_module_logging "$MODULE_NAME" + if "$SYSTEM_DIR/install/$script_name"; then + finalize_module_logging "success" + else + finalize_module_logging "failed" + exit 1 + fi done else # Install specific module - local resolved_module=$(resolve_module_path "$module") - if [[ -x "$(get_system_dir)/$resolved_module/install" ]]; then - "$(get_system_dir)/$resolved_module/install" + local script_name=$(resolve_script_name "$module" "install") + if [[ -x "$SYSTEM_DIR/install/$script_name" ]]; then + # Extract module name from script filename + export MODULE_NAME="$(basename "$script_name" | sed 's/^[0-9]*-[0-9]*-//')" + + init_module_logging "$MODULE_NAME" + if "$SYSTEM_DIR/install/$script_name"; then + finalize_module_logging "success" + else + finalize_module_logging "failed" + exit 1 + fi else log_error "Module $module does not have an install script" exit 1 fi fi - + finalize_logging "success" } # Run build command cmd_build() { local module="${1:-all}" - + # Handle --list option if [[ "$module" == "--list" ]]; then check_system_for_list @@ -231,41 +246,65 @@ cmd_build() { get_available_modules "build" return 0 fi - + check_system_setup init_logging "build" - + log_header "Building: $module" - + + # Export common variables for scripts + export DOT_HOME="$DOT_HOME" + export SYSTEM_DIR="$(get_system_dir)" + export SHARED_DIR="$DOT_HOME/shared" + if [[ "$module" == "all" ]]; then log_info "Building all modules" - + # Get all available build scripts - local available_modules - mapfile -t available_modules < <(get_available_modules "build") - - for mod in "${available_modules[@]}"; do - log_step "Running build for module: $mod" - "$(get_system_dir)/$mod/build" + local available_modules=() + while IFS= read -r line; do + [[ -n "$line" ]] && available_modules+=("$line") + done < <(get_available_modules "build") + + for script_name in "${available_modules[@]}"; do + # Extract module name from script filename (e.g., "03-00-git" -> "git") + export MODULE_NAME="$(basename "$script_name" | sed 's/^[0-9]*-[0-9]*-//')" + + init_module_logging "$MODULE_NAME" + if "$SYSTEM_DIR/build/$script_name"; then + finalize_module_logging "success" + else + finalize_module_logging "failed" + exit 1 + fi done else # Build specific module - local resolved_module=$(resolve_module_path "$module") - if [[ -x "$(get_system_dir)/$resolved_module/build" ]]; then - "$(get_system_dir)/$resolved_module/build" + local script_name=$(resolve_script_name "$module" "build") + if [[ -x "$SYSTEM_DIR/build/$script_name" ]]; then + # Extract module name from script filename + export MODULE_NAME="$(basename "$script_name" | sed 's/^[0-9]*-[0-9]*-//')" + + init_module_logging "$MODULE_NAME" + if "$SYSTEM_DIR/build/$script_name"; then + finalize_module_logging "success" + else + finalize_module_logging "failed" + exit 1 + fi else log_error "Module $module does not have a build script" exit 1 fi fi - + finalize_logging "success" } # Run upgrade command cmd_upgrade() { local module="${1:-all}" - + # Handle --list option if [[ "$module" == "--list" ]]; then check_system_for_list @@ -273,40 +312,64 @@ cmd_upgrade() { get_available_modules "upgrade" return 0 fi - + check_system_setup init_logging "upgrade" - + log_header "Upgrading: $module" - + + # Export common variables for scripts + export DOT_HOME="$DOT_HOME" + export SYSTEM_DIR="$(get_system_dir)" + export SHARED_DIR="$DOT_HOME/shared" + if [[ "$module" == "all" ]]; then log_info "Upgrading all modules" - + # Get all available upgrade scripts - local available_modules - mapfile -t available_modules < <(get_available_modules "upgrade") - + local available_modules=() + while IFS= read -r line; do + [[ -n "$line" ]] && available_modules+=("$line") + done < <(get_available_modules "upgrade") + if [[ ${#available_modules[@]} -eq 0 ]]; then log_info "No modules have upgrade scripts" finalize_logging "success" return fi - - for mod in "${available_modules[@]}"; do - log_step "Running upgrade for module: $mod" - "$(get_system_dir)/$mod/upgrade" + + for script_name in "${available_modules[@]}"; do + # Extract module name from script filename + export MODULE_NAME="$(basename "$script_name" | sed 's/^[0-9]*-[0-9]*-//')" + + init_module_logging "$MODULE_NAME" + if "$SYSTEM_DIR/upgrade/$script_name"; then + finalize_module_logging "success" + else + finalize_module_logging "failed" + exit 1 + fi done else # Upgrade specific module - local resolved_module=$(resolve_module_path "$module") - if [[ -x "$(get_system_dir)/$resolved_module/upgrade" ]]; then - "$(get_system_dir)/$resolved_module/upgrade" + local script_name=$(resolve_script_name "$module" "upgrade") + if [[ -x "$SYSTEM_DIR/upgrade/$script_name" ]]; then + # Extract module name from script filename + export MODULE_NAME="$(basename "$script_name" | sed 's/^[0-9]*-[0-9]*-//')" + + init_module_logging "$MODULE_NAME" + if "$SYSTEM_DIR/upgrade/$script_name"; then + finalize_module_logging "success" + else + finalize_module_logging "failed" + exit 1 + fi else log_error "Module $module does not have an upgrade script" exit 1 fi fi - + finalize_logging "success" } diff --git a/bin/install-macos b/bin/install-macos new file mode 100755 index 00000000..4ff11f90 --- /dev/null +++ b/bin/install-macos @@ -0,0 +1,102 @@ +#!/bin/bash + +set -euo pipefail + +# Check if running with --local flag (already cloned and running locally) +if [[ "${1:-}" != "--local" ]]; then + # Remote execution - clone repo and re-exec locally + echo "[INFO] Cloning dotfiles and running local setup..." + + DOTFILES_DIR="$HOME/Repositories/dotfiles" + + if [[ ! -d "$DOTFILES_DIR" ]]; then + echo "[INFO] Creating Repositories directory" + mkdir -p "$HOME/Repositories" + + echo "[INFO] Cloning dotfiles repository" + git clone https://github.com/vikdotdev/dotfiles.git "$DOTFILES_DIR" + else + echo "[INFO] Dotfiles repository already exists, pulling latest changes" + cd "$DOTFILES_DIR" + git pull origin master + fi + + # Re-exec the local script with --local flag + echo "[INFO] Running local install script..." + chmod +x "$DOTFILES_DIR/bin/install-macos" + exec "$DOTFILES_DIR/bin/install-macos" --local +fi + +# Local execution from here on +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +DOT_HOME="$(dirname "$SCRIPT_DIR")" + +# Source local utilities +source "$DOT_HOME/lib/macos/include.sh" + +# Initialize +init_logging "install-macos" + +# Don't run as root +if is_root; then + log_error "Don't run install-macos as root/sudo. It will ask for sudo when needed." + exit 1 +fi + +log_header "macOS Installation Setup" + +# Check if we're on macOS +if ! is_macos; then + log_error "This script is designed for macOS systems" + exit 1 +fi + +# Basic system setup +log_step "Setting up basic system requirements" + +# Install Homebrew if not present +if ! command_exists brew; then + log_info "Installing Homebrew" + /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" + + # Add Homebrew to PATH for Apple Silicon Macs + if [[ -f "/opt/homebrew/bin/brew" ]]; then + eval "$(/opt/homebrew/bin/brew shellenv)" + fi +else + log_info "Homebrew already installed" +fi + +# Update Homebrew +log_info "Updating Homebrew" +brew update + +# Install essential tools +log_info "Installing minimal essential packages" +ESSENTIAL_FORMULAS=( + "curl" + "wget" + "git" + "gnupg" +) + +brew install "${ESSENTIAL_FORMULAS[@]}" + +# Mark system as installed +mark_system_installed "macos" +log_success "System marked as macOS installation" + +# Run dot install to install all packages and applications +log_step "Running dot install to set up all packages and applications" +"$DOT_HOME/bin/dot" install + +# Run dot build to configure all dotfiles +log_step "Running dot build to configure all dotfiles" +"$DOT_HOME/bin/dot" build + +log_success "macOS setup complete!" +echo +echo "All packages installed and dotfiles configured!" +echo "You may need to restart your shell for some changes to take effect." + +finalize_logging "success" diff --git a/debian/kmonad/build b/debian/kmonad/build index 2ea898ec..d62366c6 100755 --- a/debian/kmonad/build +++ b/debian/kmonad/build @@ -29,10 +29,11 @@ log_step "Deploying KMonad configuration" CONFIG_DIR="$HOME/.config/kmonad" mkdir -p "$CONFIG_DIR" -# Deploy keyboard configuration -if [[ -f "$SCRIPT_DIR/config/laptop.kbd" ]]; then +# Deploy keyboard configuration from shared +SHARED_CONFIG="$DOT_HOME/shared/kmonad/config/laptop.kbd" +if [[ -f "$SHARED_CONFIG" ]]; then log_info "Deploying keyboard configuration" - cp "$SCRIPT_DIR/config/laptop.kbd" "$CONFIG_DIR/config.kbd" + cp "$SHARED_CONFIG" "$CONFIG_DIR/config.kbd" else log_warning "No keyboard configuration found" fi diff --git a/debian/kmonad/config/laptop.kbd b/debian/kmonad/config/laptop.kbd deleted file mode 100644 index db472b47..00000000 --- a/debian/kmonad/config/laptop.kbd +++ /dev/null @@ -1,57 +0,0 @@ -(defcfg - input (device-file "/dev/input/by-path/platform-i8042-serio-0-event-kbd") - output (uinput-sink "KMonad output" "/usr/bin/sleep 1") - cmp-seq ralt - cmp-seq-delay 5 - fallthrough true - allow-cmd true -) - -(defalias - mta (tap-hold-next-release 150 tab lmet) - rta (tap-hold-next-release 150 \ rmet) - qta (tap-hold-next-release 150 ' lalt) - ces (tap-hold-next-release 150 esc lctl) - laa (tap-hold-next-release 300 a lalt) - lac (tap-hold-next-release 300 ; rctl) - lsb (tap-hold-next-release 170 lbrc lsft) - cst (tap-macro (around-next lsft) (around-next lctl)) - rsb (tap-hold-next-release 170 rbrc rsft) - sid (tap-hold-next-release 300 spc (layer-toggle side)) - ;; browser history navigation - hfo (around lalt right) - hba (around lalt left) - ;; browser tab navigation - tba (around lctl (around lsft tab)) - tfo (around lctl tab) -) - -(defsrc - esc mute vold volu end ins del - grv 1 2 3 4 5 6 7 8 9 0 - = bspc - tab q w e r t y u i o p [ ] \ - caps a s d f g h j k l ; ' ret - lsft z x c v b n m , . / rsft - lctl lmet lalt spc ralt prnt rctl pgup up pgdn - left down rght -) - -(deflayer main - esc mute vold volu end ins del - = 1 2 3 4 5 6 7 8 9 0 - grv XX - @mta q w e r t y u i o p @rta XX XX - @ces @laa s d f g h j k l @lac @qta ret - @lsb z x c v b n m , . / @rsb - caps _ lalt @sid ralt prnt rctl pgup up pgdn - left down rght -) - -(deflayer side - _ _ _ _ _ _ _ - _ _ _ _ _ _ _ _ _ _ _ _ _ _ - _ @hba @hfo @tba @tfo _ _ _ _ _ up _ _ _ - _ _ _ bspc rght ret _ _ _ _ _ _ _ - _ _ _ _ _ left down @cst _ _ _ _ - _ _ _ _ _ _ _ _ _ _ - _ _ _ -) diff --git a/debian/shell/build b/debian/shell/build index 7b8f86c3..625ca7fe 100755 --- a/debian/shell/build +++ b/debian/shell/build @@ -5,68 +5,5 @@ set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" DOT_HOME="$(dirname "$(dirname "$SCRIPT_DIR")")" -source "$DOT_HOME/lib/debian/include.sh" - -MODULE="shell" -init_module_logging "$MODULE" - -log_header "Building Shell Configuration" - -# Deploy shell configuration files from existing plans -log_step "Deploying shell configuration" - -# Bash configuration -log_step "Installing bash configuration" - -# Copy bash configuration files -if [[ -f "$SCRIPT_DIR/config/.bashrc" ]]; then - cp "$SCRIPT_DIR/config/.bashrc" "$HOME/.bashrc" - log_info "Deployed .bashrc" -fi - -if [[ -f "$SCRIPT_DIR/config/.profile" ]]; then - cp "$SCRIPT_DIR/config/.profile" "$HOME/.profile" - log_info "Deployed .profile" -fi - -if [[ -f "$SCRIPT_DIR/config/.bash_profile" ]]; then - cp "$SCRIPT_DIR/config/.bash_profile" "$HOME/.bash_profile" - log_info "Deployed .bash_profile" -fi - -# Pry configuration -if [[ -f "$SCRIPT_DIR/config/.pryrc" ]]; then - cp "$SCRIPT_DIR/config/.pryrc" "$HOME/.pryrc" - log_info "Deployed .pryrc" -fi - -# IRB configuration -if [[ -f "$SCRIPT_DIR/config/.irbrc" ]]; then - cp "$SCRIPT_DIR/config/.irbrc" "$HOME/.irbrc" - log_info "Deployed .irbrc" -fi - -# Readline configuration -if [[ -f "$SCRIPT_DIR/config/.inputrc" ]]; then - cp "$SCRIPT_DIR/config/.inputrc" "$HOME/.inputrc" - log_info "Deployed .inputrc" -fi - -# Deploy .profile.local example if it doesn't exist -if [[ ! -f "$HOME/.profile.local" ]] && [[ -f "$SCRIPT_DIR/config/.profile.local.example" ]]; then - cp "$SCRIPT_DIR/config/.profile.local.example" "$HOME/.profile.local" - log_info "Deployed .profile.local from example (customize as needed)" -fi - -# Bash completions -log_step "Installing bash completions" -mkdir -p "$HOME/.bashrc.d" - -# Source dot completions from top-level -if [[ -f "$DOT_HOME/completions/dot.bash" ]]; then - cp "$DOT_HOME/completions/dot.bash" "$HOME/.bashrc.d/dot-completion.bash" - log_info "Deployed dot command completions" -fi - -log_success "Shell configuration completed" -finalize_module_logging "success" +# Call shared build script +"$DOT_HOME/shared/shell/build" diff --git a/debian/tools/00-mise/build b/debian/tools/00-mise/build index 4e6f0e90..003100fa 100755 --- a/debian/tools/00-mise/build +++ b/debian/tools/00-mise/build @@ -15,7 +15,7 @@ log_header "Building Mise Configuration" if command_exists mise; then log_step "Creating mise.toml" mkdir -p "$HOME/.config/mise/" - cp "$SCRIPT_DIR/config/mise.toml" "$HOME/.config/mise/config.toml" + cp "$DOT_HOME/shared/tools/mise/config/mise.toml" "$HOME/.config/mise/config.toml" log_success "Deployed mise config to ~/.config/mise/config.toml" log_step "Installing tools" mise install diff --git a/debian/tools/01-ghostty/build b/debian/tools/01-ghostty/build index 9175d879..4bbbbe40 100755 --- a/debian/tools/01-ghostty/build +++ b/debian/tools/01-ghostty/build @@ -16,13 +16,14 @@ log_header "Building Ghostty Configuration" log_step "Creating Ghostty config directory" mkdir -p "$HOME/.config/ghostty" -# Deploy Ghostty configuration +# Deploy Ghostty configuration from shared log_step "Deploying Ghostty configuration" -if [[ -f "$SCRIPT_DIR/config/config" ]]; then - cp "$SCRIPT_DIR/config/config" "$HOME/.config/ghostty/config" +SHARED_CONFIG="$DOT_HOME/shared/ghostty/config/config" +if [[ -f "$SHARED_CONFIG" ]]; then + cp "$SHARED_CONFIG" "$HOME/.config/ghostty/config" log_info "Deployed Ghostty config to ~/.config/ghostty/config" else - log_error "Ghostty config file not found" + log_error "Ghostty config file not found at $SHARED_CONFIG" finalize_module_logging "failed" exit 1 fi diff --git a/debian/tools/emacs/build b/debian/tools/emacs/build index c713ec3e..0361f70d 100755 --- a/debian/tools/emacs/build +++ b/debian/tools/emacs/build @@ -4,6 +4,7 @@ set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" DOT_HOME="$(dirname "$(dirname "$(dirname "$SCRIPT_DIR")")")" +SHARED_CONFIG_DIR="$DOT_HOME/shared/tools/emacs/config" source "$DOT_HOME/lib/debian/include.sh" @@ -24,11 +25,11 @@ cleanup_temp() { trap cleanup_temp EXIT # Tangle the org file to extract elisp code blocks -if [[ -f "$SCRIPT_DIR/config/config.org" ]]; then +if [[ -f "$SHARED_CONFIG_DIR/config.org" ]]; then log_info "Extracting elisp code from config.org..." emacs --batch \ --eval "(require 'org)" \ - --eval "(org-babel-tangle-file \"$SCRIPT_DIR/config/config.org\" \"$TEMP_EL\")" \ + --eval "(org-babel-tangle-file \"$SHARED_CONFIG_DIR/config.org\" \"$TEMP_EL\")" \ 2>&1 | grep -v "^Loading" || true if [[ ! -f "$TEMP_EL" ]]; then @@ -64,18 +65,18 @@ log_step "Deploying Emacs configuration" EMACS_CONFIG_DIR="$HOME/.emacs.d" mkdir -p "$EMACS_CONFIG_DIR" -if [[ -f "$SCRIPT_DIR/config/early-init.el" ]]; then - cp "$SCRIPT_DIR/config/early-init.el" "$EMACS_CONFIG_DIR/early-init.el" +if [[ -f "$SHARED_CONFIG_DIR/early-init.el" ]]; then + cp "$SHARED_CONFIG_DIR/early-init.el" "$EMACS_CONFIG_DIR/early-init.el" log_info "Deployed early-init.el" fi -if [[ -f "$SCRIPT_DIR/config/init.el" ]]; then - cp "$SCRIPT_DIR/config/init.el" "$EMACS_CONFIG_DIR/init.el" +if [[ -f "$SHARED_CONFIG_DIR/init.el" ]]; then + cp "$SHARED_CONFIG_DIR/init.el" "$EMACS_CONFIG_DIR/init.el" log_info "Deployed init.el" fi -if [[ -f "$SCRIPT_DIR/config/config.org" ]]; then - cp "$SCRIPT_DIR/config/config.org" "$EMACS_CONFIG_DIR/config.org" +if [[ -f "$SHARED_CONFIG_DIR/config.org" ]]; then + cp "$SHARED_CONFIG_DIR/config.org" "$EMACS_CONFIG_DIR/config.org" log_info "Deployed config.org" fi diff --git a/debian/tools/git/build b/debian/tools/git/build index 7024cc5c..7657848f 100755 --- a/debian/tools/git/build +++ b/debian/tools/git/build @@ -5,48 +5,11 @@ set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" DOT_HOME="$(dirname "$(dirname "$(dirname "$SCRIPT_DIR")")")" -source "$DOT_HOME/lib/debian/include.sh" +# Call shared build script +"$DOT_HOME/shared/tools/git/build" -MODULE="git" -init_module_logging "$MODULE" - -log_header "Building Git Configuration" - -log_step "Installing Git configuration" - -# Copy .gitconfig file -if [[ -f "$SCRIPT_DIR/config/.gitconfig" ]]; then - cp "$SCRIPT_DIR/config/.gitconfig" "$HOME/.gitconfig" - log_success "Git configuration installed" -else - log_warning "Git configuration file not found" -fi - -# Copy global gitignore file -if [[ -f "$SCRIPT_DIR/config/ignore" ]]; then - mkdir -p "$HOME/.config/git" - cp "$SCRIPT_DIR/config/ignore" "$HOME/.config/git/ignore" - log_success "Global gitignore installed" -else - log_warning "Global gitignore file not found" +# Copy Debian-specific git configuration +if [[ -f "$SCRIPT_DIR/config/gitconfig.os" ]]; then + cp "$SCRIPT_DIR/config/gitconfig.os" "$HOME/.gitconfig.os" + echo "[Debian] OS-specific git configuration installed" fi - -log_step "Installing git scripts" - -# Create scripts directory -mkdir -p "$HOME/.local/bin" - -# Copy git utility scripts -if [[ -d "$SCRIPT_DIR/scripts" ]]; then - for script in "$SCRIPT_DIR/scripts"/*; do - if [[ -f "$script" ]]; then - script_name=$(basename "$script") - cp "$script" "$HOME/.local/bin/$script_name" - chmod +x "$HOME/.local/bin/$script_name" - log_info "Installed script: $script_name" - fi - done -fi - -log_success "Git configuration build completed" -finalize_module_logging "success" diff --git a/debian/tools/git/config/gitconfig.os b/debian/tools/git/config/gitconfig.os new file mode 100644 index 00000000..4bf4bebd --- /dev/null +++ b/debian/tools/git/config/gitconfig.os @@ -0,0 +1,5 @@ +# Debian-specific git configuration +[credential "https://github.com"] + helper = !/usr/bin/gh auth git-credential +[credential "https://gist.github.com"] + helper = !/usr/bin/gh auth git-credential diff --git a/debian/tools/gpg/build b/debian/tools/gpg/build index 4d74de1f..7b88cc8b 100755 --- a/debian/tools/gpg/build +++ b/debian/tools/gpg/build @@ -5,32 +5,5 @@ set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" DOT_HOME="$(dirname "$(dirname "$(dirname "$SCRIPT_DIR")")")" -source "$DOT_HOME/lib/debian/include.sh" - -MODULE="gpg" -init_module_logging "$MODULE" - -log_header "Building GPG Configuration" - -log_step "Installing GPG agent configuration" - -# Create GPG directory if it doesn't exist -mkdir -p "$HOME/.gnupg" - -# Set proper permissions for GPG directory -chmod 700 "$HOME/.gnupg" - -# Copy GPG agent configuration -if [[ -f "$SCRIPT_DIR/config/gpg-agent.conf" ]]; then - cp "$SCRIPT_DIR/config/gpg-agent.conf" "$HOME/.gnupg/gpg-agent.conf" - chmod 600 "$HOME/.gnupg/gpg-agent.conf" - - # Restart GPG agent to pick up new config - if command_exists gpgconf; then - log_info "Reloading GPG agent configuration" - gpgconf --reload gpg-agent || log_warning "Failed to reload GPG agent" - fi -fi - -log_success "GPG configuration build completed" -finalize_module_logging "success" +# Call shared build script +"$DOT_HOME/shared/tools/gpg/build" diff --git a/lib/macos/constants.sh b/lib/macos/constants.sh new file mode 100644 index 00000000..da776ff6 --- /dev/null +++ b/lib/macos/constants.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +# Get the lib directory path +LIB_DIR="$(dirname "$(dirname "${BASH_SOURCE[0]}")")" + +# Source general constants first +source "$LIB_DIR/constants.sh" + +MACOS_VERSION=$(sw_vers -productVersion 2>/dev/null || echo "unknown") +MACOS_CODENAME=$(get_macos_codename 2>/dev/null || echo "unknown") diff --git a/lib/macos/include.sh b/lib/macos/include.sh new file mode 100644 index 00000000..c591a9d5 --- /dev/null +++ b/lib/macos/include.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +# Get the macos lib directory path +MACOS_LIB_DIR="$(dirname "${BASH_SOURCE[0]}")" +LIB_DIR="$(dirname "$MACOS_LIB_DIR")" + +source "$LIB_DIR/colors.sh" +source "$LIB_DIR/logging.sh" +source "$LIB_DIR/constants.sh" +source "$LIB_DIR/utils.sh" + +# May override some functions +source "$MACOS_LIB_DIR/utils.sh" +source "$MACOS_LIB_DIR/constants.sh" diff --git a/lib/macos/utils.sh b/lib/macos/utils.sh new file mode 100644 index 00000000..e03d1193 --- /dev/null +++ b/lib/macos/utils.sh @@ -0,0 +1,102 @@ +#!/bin/bash + +# macOS-specific utilities - extends the general utilities + +ensure_homebrew() { + if ! command_exists brew; then + log_warning "Homebrew not found. Installing Homebrew..." + /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" + + # Add Homebrew to PATH for Apple Silicon Macs + if [[ -f "/opt/homebrew/bin/brew" ]]; then + eval "$(/opt/homebrew/bin/brew shellenv)" + fi + fi +} + +brew_installed() { + local formula="$1" + brew list "$formula" &>/dev/null +} + +cask_installed() { + local cask="$1" + brew list --cask "$cask" &>/dev/null +} + +install_formula() { + local formulas=("$@") + + ensure_homebrew + log_info "Installing formulas with brew: ${formulas[*]}" + brew install "${formulas[@]}" +} + +install_cask() { + local casks=("$@") + + ensure_homebrew + log_info "Installing casks with brew: ${casks[*]}" + brew install --cask "${casks[@]}" +} + +remove_formula() { + local formulas=("$@") + + log_info "Removing formulas with brew: ${formulas[*]}" + brew uninstall "${formulas[@]}" +} + +update_homebrew() { + log_info "Updating Homebrew" + ensure_homebrew + brew update +} + +upgrade_formulas() { + log_info "Upgrading all formulas" + ensure_homebrew + brew upgrade +} + +cleanup_homebrew() { + log_info "Cleaning up Homebrew" + ensure_homebrew + brew cleanup +} + +get_macos_version() { + sw_vers -productVersion +} + +is_macos() { + [[ "$OSTYPE" == "darwin"* ]] +} + +get_macos_codename() { + local version=$(sw_vers -productVersion) + local major=$(echo "$version" | cut -d. -f1) + local minor=$(echo "$version" | cut -d. -f2) + + case "$major" in + 15) echo "Sequoia" ;; + 14) echo "Sonoma" ;; + 13) echo "Ventura" ;; + 12) echo "Monterey" ;; + 11) echo "Big Sur" ;; + 10) + case "$minor" in + 15) echo "Catalina" ;; + 14) echo "Mojave" ;; + 13) echo "High Sierra" ;; + *) echo "unknown" ;; + esac + ;; + *) echo "unknown" ;; + esac +} + +formula_available() { + local formula="$1" + brew info "$formula" &>/dev/null +} diff --git a/macos/build/01-00-mise b/macos/build/01-00-mise new file mode 100755 index 00000000..67a5b51c --- /dev/null +++ b/macos/build/01-00-mise @@ -0,0 +1,17 @@ +#!/bin/bash + +set -euo pipefail + +source "$DOT_HOME/lib/macos/include.sh" + +if command_exists mise; then + log_step "Creating mise.toml" + mkdir -p "$HOME/.config/mise/" + cp "$SHARED_DIR/tools/mise/config/mise.toml" "$HOME/.config/mise/config.toml" + log_success "Deployed mise config to ~/.config/mise/config.toml" + log_step "Installing tools" + mise install +else + log_error "mise build failed - mise binary not found" + exit 0 +fi diff --git a/macos/build/02-00-emacs b/macos/build/02-00-emacs new file mode 100755 index 00000000..069abc8f --- /dev/null +++ b/macos/build/02-00-emacs @@ -0,0 +1,28 @@ +#!/bin/bash + +set -euo pipefail + +source "$DOT_HOME/lib/macos/include.sh" + +log_step "Deploying Emacs configuration" + +EMACS_CONFIG_DIR="$HOME/.emacs.d" +SHARED_CONFIG_DIR="$SHARED_DIR/tools/emacs/config" +mkdir -p "$EMACS_CONFIG_DIR" + +if [[ -f "$SHARED_CONFIG_DIR/early-init.el" ]]; then + cp "$SHARED_CONFIG_DIR/early-init.el" "$EMACS_CONFIG_DIR/early-init.el" + log_info "Deployed early-init.el" +fi + +if [[ -f "$SHARED_CONFIG_DIR/init.el" ]]; then + cp "$SHARED_CONFIG_DIR/init.el" "$EMACS_CONFIG_DIR/init.el" + log_info "Deployed init.el" +fi + +if [[ -f "$SHARED_CONFIG_DIR/config.org" ]]; then + cp "$SHARED_CONFIG_DIR/config.org" "$EMACS_CONFIG_DIR/config.org" + log_info "Deployed config.org" +fi + +log_success "Emacs configuration completed" diff --git a/macos/build/03-00-git b/macos/build/03-00-git new file mode 100755 index 00000000..95592b16 --- /dev/null +++ b/macos/build/03-00-git @@ -0,0 +1,10 @@ +#!/bin/bash + +set -euo pipefail + +"$SHARED_DIR/tools/git/build" + +if [[ -f "$SYSTEM_DIR/config/git/gitconfig.os" ]]; then + cp "$SYSTEM_DIR/config/git/gitconfig.os" "$HOME/.gitconfig.os" + echo "[macOS] OS-specific git configuration installed" +fi diff --git a/macos/build/04-00-amethyst b/macos/build/04-00-amethyst new file mode 100755 index 00000000..9a636483 --- /dev/null +++ b/macos/build/04-00-amethyst @@ -0,0 +1,24 @@ +#!/bin/bash + +set -euo pipefail + +source "$DOT_HOME/lib/macos/include.sh" + +if ! command -v open >/dev/null || [[ ! -d "/Applications/Amethyst.app" ]]; then + log_warning "Amethyst not installed, skipping configuration deployment" + log_info "Run 'dot install amethyst' to install Amethyst first" + exit 0 +fi + +log_step "Deploying Amethyst configuration" +SOURCE_CONFIG="$SYSTEM_DIR/config/amethyst/.amethyst.yml" +DEST_CONFIG="$HOME/.amethyst.yml" + +if [[ ! -f "$SOURCE_CONFIG" ]]; then + log_error "Config file not found: $SOURCE_CONFIG" + exit 1 +fi + +cp "$SOURCE_CONFIG" "$DEST_CONFIG" +log_success "Amethyst configuration deployed to $DEST_CONFIG" +log_info "Restart Amethyst for changes to take effect" diff --git a/macos/build/04-00-gpg b/macos/build/04-00-gpg new file mode 100755 index 00000000..304ca0aa --- /dev/null +++ b/macos/build/04-00-gpg @@ -0,0 +1,5 @@ +#!/bin/bash + +set -euo pipefail + +"$SHARED_DIR/tools/gpg/build" diff --git a/macos/build/05-00-kanata b/macos/build/05-00-kanata new file mode 100755 index 00000000..3ce5de5f --- /dev/null +++ b/macos/build/05-00-kanata @@ -0,0 +1,60 @@ +#!/bin/bash + +set -euo pipefail + +source "$DOT_HOME/lib/macos/include.sh" + +if ! command_exists kanata; then + log_warning "kanata not installed, skipping configuration deployment" + log_info "Run 'dot install kanata' to install kanata first" + exit 0 +fi + +log_step "Validating kanata configuration" +NEW_CONFIG="$SYSTEM_DIR/config/kanata/iso-us-international.kbd" + +# Basic validation: check if file exists and is not empty +if [[ ! -f "$NEW_CONFIG" ]]; then + log_error "Config file not found: $NEW_CONFIG" + exit 1 +fi + +if [[ ! -s "$NEW_CONFIG" ]]; then + log_error "Config file is empty: $NEW_CONFIG" + exit 1 +fi + +log_info "Config file validation passed" + +log_step "Deploying kanata configuration" +CONFIG_DIR="$HOME/.config/kanata" +mkdir -p "$CONFIG_DIR" + +cp "$NEW_CONFIG" "$CONFIG_DIR/config.kbd" +log_success "Configuration deployed to $CONFIG_DIR/config.kbd" + +KANATA_PLIST="/Library/LaunchDaemons/com.kanata.plist" +if [[ -f "$KANATA_PLIST" ]]; then + log_step "Restarting kanata service" + + # Bootout (unload) - will fail silently if not loaded + sudo launchctl bootout system "$KANATA_PLIST" 2>/dev/null || true + sleep 0.5 + + # Bootstrap (load and start) + if sudo launchctl bootstrap system "$KANATA_PLIST" 2>/dev/null; then + log_success "kanata service restarted (passwordless sudo)" + else + # Try kickstart if already loaded + if sudo launchctl kickstart -k system/com.kanata 2>/dev/null; then + log_success "kanata service restarted via kickstart" + else + log_warning "Could not restart service - may need manual intervention" + fi + fi +else + log_warning "kanata LaunchDaemon not found" + log_info "Run 'dot install kanata' to set up the launch service" +fi + +log_success "kanata build completed" diff --git a/macos/build/06-00-shell b/macos/build/06-00-shell new file mode 100755 index 00000000..d860b194 --- /dev/null +++ b/macos/build/06-00-shell @@ -0,0 +1,5 @@ +#!/bin/bash + +set -euo pipefail + +"$SHARED_DIR/shell/build" diff --git a/macos/build/07-00-ghostty b/macos/build/07-00-ghostty new file mode 100755 index 00000000..5f5091ea --- /dev/null +++ b/macos/build/07-00-ghostty @@ -0,0 +1,20 @@ +#!/bin/bash + +set -euo pipefail + +source "$DOT_HOME/lib/macos/include.sh" + +log_step "Creating Ghostty config directory" +mkdir -p "$HOME/.config/ghostty" + +log_step "Deploying Ghostty configuration" +SHARED_CONFIG="$SHARED_DIR/ghostty/config/config" +if [[ -f "$SHARED_CONFIG" ]]; then + cp "$SHARED_CONFIG" "$HOME/.config/ghostty/config" + log_info "Deployed Ghostty config to ~/.config/ghostty/config" +else + log_error "Ghostty config file not found at $SHARED_CONFIG" + exit 1 +fi + +log_success "Ghostty configuration completed" diff --git a/macos/config/amethyst/.amethyst.yml b/macos/config/amethyst/.amethyst.yml new file mode 100644 index 00000000..fe65afbb --- /dev/null +++ b/macos/config/amethyst/.amethyst.yml @@ -0,0 +1,119 @@ +# Amethyst Configuration + +# Modifier keys (mod1 and mod2 can be customized) +mod1: + - option + - control + - command + +mod2: + - option + - control + - command + - shift + +# Layouts +layouts: + - tall + - fullscreen + - 3column-left + - floating + +# Window settings +window-margins: true +window-margin-size: 8 +window-resize-step: 5 + +# Focus behavior +mouse-follows-focus: false +focus-follows-mouse: false + +# Floating applications (bundle identifiers) +floating: + - com.apple.systempreferences + - com.apple.ActivityMonitor + +# Keyboard shortcuts +cycle-layout: + mod: mod1 + key: t + +shrink-main: + mod: mod1 + key: '=' + +expand-main: + mod: mod1 + key: '-' + +increase-main: + mod: mod1 + key: '.' + +decrease-main: + mod: mod1 + key: ',' + +focus-ccw: + mod: mod1 + key: i + +focus-cw: + mod: mod1 + key: o + +swap-cw: + mod: mod1 + key: n + +swap-main: + mod: mod1 + key: enter + +focus-screen-1: + mod: mod1 + key: m + +focus-screen-2: + mod: mod1 + key: l + +select-fullscreen-layout: + mod: mod1 + key: f + +select-wide-layout: + mod: mod2 + key: s + +throw-space-1: + mod: mod2 + key: '1' + +throw-space-2: + mod: mod2 + key: '2' + +throw-space-3: + mod: mod2 + key: '3' + +throw-space-4: + mod: mod2 + key: '4' + +throw-space-5: + mod: mod2 + key: '5' + +throw-space-6: + mod: mod2 + key: '6' + +throw-space-7: + mod: mod2 + key: '7' + +throw-space-8: + mod: mod2 + key: '8' diff --git a/macos/config/git/gitconfig.os b/macos/config/git/gitconfig.os new file mode 100644 index 00000000..767ac9be --- /dev/null +++ b/macos/config/git/gitconfig.os @@ -0,0 +1,5 @@ +# macOS-specific git configuration +[credential "https://github.com"] + helper = !/opt/homebrew/bin/gh auth git-credential +[credential "https://gist.github.com"] + helper = !/opt/homebrew/bin/gh auth git-credential diff --git a/macos/config/kanata/iso-us-international.kbd b/macos/config/kanata/iso-us-international.kbd new file mode 100644 index 00000000..ab7fe4cb --- /dev/null +++ b/macos/config/kanata/iso-us-international.kbd @@ -0,0 +1,64 @@ +;; Kanata keyboard configuration +;; Converted from kmonad config + +(defcfg + process-unmapped-keys yes + ;; Allow command execution (use with caution) + danger-enable-cmd yes +) + +(defalias + ;; Custom Hyper key (Cmd+Ctrl+Alt all together) + hyp (multi lctl lalt lmet) + + ;; Tap-hold aliases + ;; kanata uses: (tap-hold tap-timeout hold-timeout tap-action hold-action) + mta (tap-hold 150 150 tab @hyp) + rta (tap-hold 150 150 \ rmet) + qta (tap-hold 150 150 ' lalt) + ces (tap-hold 150 150 esc lctl) + laa (tap-hold 300 300 a lalt) + lac (tap-hold 300 300 ; rctl) + lsb (tap-hold 170 170 [ lsft) + rsb (tap-hold 170 170 ] rsft) + sid (tap-hold 300 300 spc (layer-toggle side)) + 1cm (tap-hold 300 300 1 lmet) + + ;; Browser history navigation + hfo (multi lalt rght) + hba (multi lalt left) + + ;; Browser tab navigation + tba (multi lctl (multi lsft tab)) + tfo (multi lctl tab) +) + +(defsrc + esc f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11 f12 + nubs 1 2 3 4 5 6 7 8 9 0 - = bspc + tab q w e r t y u i o p [ ] + caps a s d f g h j k l ; ' \ ret + lsft grv z x c v b n m , . / rsft + lctl lmet lalt spc ralt rctl pgup up pgdn + left down rght +) + +(deflayer main + esc brdn brup mctl sls dtn dnd prev pp next mute vold volu + = @1cm 2 3 4 5 6 7 8 9 0 - grv bspc + @mta q w e r t y u i o p @hyp \ + @ces @laa s d f g h j k l @lac @qta ret ret + lsft lsft z x c v b n m , . / @rsb + caps lalt lmet @sid ralt rctl pgup up pgdn + left down rght +) + +(deflayer side + _ _ _ _ _ _ _ _ _ _ _ _ _ + _ _ _ _ _ _ _ _ _ _ _ _ _ _ + _ @hba @hfo @tba @tfo _ _ _ _ _ up _ _ + _ _ _ bspc rght ret _ _ _ _ _ _ _ _ + _ _ _ _ _ _ left down _ _ _ _ _ + _ _ _ _ _ _ _ _ _ + _ _ _ +) diff --git a/macos/install/01-10-mise-deps-ruby b/macos/install/01-10-mise-deps-ruby new file mode 100755 index 00000000..006b59ee --- /dev/null +++ b/macos/install/01-10-mise-deps-ruby @@ -0,0 +1,16 @@ +#!/bin/bash + +set -euo pipefail + +source "$DOT_HOME/lib/macos/include.sh" + +log_step "Installing libyaml" + +if brew_installed libyaml; then + log_info "libyaml already installed" +else + install_formula libyaml +fi + +log_success "Ruby dependencies installed" +log_info "You can now install Ruby versions with: mise install ruby@3.4.5" diff --git a/macos/install/01-50-mise b/macos/install/01-50-mise new file mode 100755 index 00000000..2a78c4fc --- /dev/null +++ b/macos/install/01-50-mise @@ -0,0 +1,44 @@ +#!/bin/bash + +set -euo pipefail + +source "$DOT_HOME/lib/macos/include.sh" + +# Check if mise is already installed +if command_exists mise; then + log_info "mise is already installed, skipping" +else + log_step "Installing mise via official installer" + + # Download and run the mise installer + log_info "Downloading and running mise installer" + curl https://mise.run | sh + + # Verify installation + if [[ -f "$HOME/.local/bin/mise" ]]; then + log_success "mise installed successfully to $HOME/.local/bin/mise" + else + log_error "mise installation failed - binary not found" + exit 1 + fi +fi + +# Add mise activation to shell config if not already present +log_step "Configuring shell integration" + +BASHRC="$HOME/.bashrc" +MISE_INIT='eval "$(~/.local/bin/mise activate bash)"' + +if [[ -f "$BASHRC" ]]; then + if ! grep -q "mise activate bash" "$BASHRC"; then + log_info "Adding mise activation to .bashrc" + echo "" >> "$BASHRC" + echo "# mise version manager" >> "$BASHRC" + echo "$MISE_INIT" >> "$BASHRC" + else + log_info "mise activation already in .bashrc" + fi +fi + +log_success "mise installation completed" +log_info "Run 'source ~/.bashrc' or start a new shell to activate mise" diff --git a/macos/install/02-10-emacs-deps-vterm b/macos/install/02-10-emacs-deps-vterm new file mode 100755 index 00000000..494324dd --- /dev/null +++ b/macos/install/02-10-emacs-deps-vterm @@ -0,0 +1,19 @@ +#!/bin/bash + +set -euo pipefail + +source "$DOT_HOME/lib/macos/include.sh" + +log_step "Installing Emacs dependencies (cmake, libtool)" + +FORMULAS=("cmake" "libtool") + +for formula in "${FORMULAS[@]}"; do + if brew_installed "$formula"; then + log_info "$formula already installed" + else + install_formula "$formula" + fi +done + +log_success "Emacs dependencies installed" diff --git a/macos/install/02-20-fonts b/macos/install/02-20-fonts new file mode 100755 index 00000000..646585ac --- /dev/null +++ b/macos/install/02-20-fonts @@ -0,0 +1,24 @@ +#!/bin/bash + +set -euo pipefail + +source "$DOT_HOME/lib/macos/include.sh" + +log_step "Installing fonts via Homebrew" + +# Iosevka font variants +CASKS=( + "font-iosevka" + "font-iosevka-nerd-font" +) + +for cask in "${CASKS[@]}"; do + if brew list --cask "$cask" &>/dev/null; then + log_info "$cask already installed" + else + install_cask "$cask" + fi +done + +log_success "Fonts installation completed" +log_info "Restart applications to use the new fonts" diff --git a/macos/install/02-50-emacs b/macos/install/02-50-emacs new file mode 100755 index 00000000..a8f9655b --- /dev/null +++ b/macos/install/02-50-emacs @@ -0,0 +1,11 @@ +#!/bin/bash + +set -euo pipefail + +source "$DOT_HOME/lib/macos/include.sh" + +log_step "Installing emacs via Homebrew" +install_cask "emacs" + +log_success "Emacs installation completed" +log_info "Run 'dot build emacs' to configure emacs" diff --git a/macos/install/03-10-git b/macos/install/03-10-git new file mode 100755 index 00000000..3a3dbe14 --- /dev/null +++ b/macos/install/03-10-git @@ -0,0 +1,12 @@ +#!/bin/bash + +set -euo pipefail + +source "$DOT_HOME/lib/macos/include.sh" + +log_step "Installing git packages via Homebrew" +FORMULAS=("git" "git-delta" "gh") +install_formula "${FORMULAS[@]}" + +log_success "Git installation completed" +log_info "Run 'dot build git' to configure git" diff --git a/macos/install/04-10-amethyst b/macos/install/04-10-amethyst new file mode 100755 index 00000000..a8fc3b6f --- /dev/null +++ b/macos/install/04-10-amethyst @@ -0,0 +1,16 @@ +#!/bin/bash + +set -euo pipefail + +source "$DOT_HOME/lib/macos/include.sh" + +log_step "Installing Amethyst via Homebrew" +CASKS=("amethyst") +install_cask "${CASKS[@]}" + +log_success "Amethyst installation completed" +log_info "Run 'dot build amethyst' to configure Amethyst" +log_info "" +log_warning "IMPORTANT: Grant Accessibility permissions to Amethyst" +log_info "Go to: System Settings > Privacy & Security > Accessibility" +log_info "Enable Amethyst to allow window management" diff --git a/macos/install/05-10-kanata b/macos/install/05-10-kanata new file mode 100755 index 00000000..c59226af --- /dev/null +++ b/macos/install/05-10-kanata @@ -0,0 +1,237 @@ +#!/bin/bash + +set -euo pipefail + +source "$DOT_HOME/lib/macos/include.sh" + +# Kanata and Karabiner versions +KANATA_VERSION="1.10.1" +KARABINER_VERSION="6.7.0" + +# Check if everything is already set up +KARABINER_DAEMON_PLIST="/Library/LaunchDaemons/org.pqrs.karabiner.virtualhiddevice.daemon.plist" +KANATA_PLIST="/Library/LaunchDaemons/com.kanata.plist" + +if command_exists kanata && [[ -f "$KARABINER_DAEMON_PLIST" ]] && [[ -f "$KANATA_PLIST" ]]; then + INSTALLED_VERSION=$(kanata --version 2>&1 | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -1 || echo "unknown") + log_success "kanata is already fully installed and configured (version: $INSTALLED_VERSION)" + exit 0 +fi + +# Install Karabiner DriverKit VirtualHIDDevice v6.7.0 +log_step "Installing Karabiner DriverKit VirtualHIDDevice v${KARABINER_VERSION}" + +KARABINER_PKG="Karabiner-DriverKit-VirtualHIDDevice-${KARABINER_VERSION}.pkg" +KARABINER_URL="https://github.com/pqrs-org/Karabiner-DriverKit-VirtualHIDDevice/releases/download/v${KARABINER_VERSION}/${KARABINER_PKG}" +TEMP_DIR=$(mktemp -d) + +# Check if Karabiner is already installed and what version +if [[ -d "/Applications/.Karabiner-VirtualHIDDevice-Manager.app" ]]; then + log_info "Karabiner driver is installed, checking version..." + + # Try to get version from the app bundle + CURRENT_VERSION=$(defaults read "/Applications/.Karabiner-VirtualHIDDevice-Manager.app/Contents/Info.plist" CFBundleShortVersionString 2>/dev/null || echo "unknown") + + if [[ "$CURRENT_VERSION" == "$KARABINER_VERSION" ]]; then + log_info "Karabiner v${KARABINER_VERSION} already installed" + else + log_warning "Karabiner v${CURRENT_VERSION} is installed, upgrading to v${KARABINER_VERSION}" + + # Uninstall old version + log_info "Deactivating old Karabiner driver" + bash '/Library/Application Support/org.pqrs/Karabiner-DriverKit-VirtualHIDDevice/scripts/uninstall/deactivate_driver.sh' || true + + log_info "Removing old Karabiner files (requires sudo)" + ensure_sudo + sudo bash '/Library/Application Support/org.pqrs/Karabiner-DriverKit-VirtualHIDDevice/scripts/uninstall/remove_files.sh' || true + + # Download and install new version + log_info "Downloading Karabiner v${KARABINER_VERSION}" + if download_file "$KARABINER_URL" "$TEMP_DIR/$KARABINER_PKG"; then + log_info "Installing Karabiner driver (requires sudo)" + ensure_sudo + sudo installer -pkg "$TEMP_DIR/$KARABINER_PKG" -target / + log_success "Karabiner v${KARABINER_VERSION} installed" + else + log_error "Failed to download Karabiner driver" + exit 1 + fi + fi +else + # Fresh install + log_info "Downloading Karabiner DriverKit VirtualHIDDevice v${KARABINER_VERSION}" + if download_file "$KARABINER_URL" "$TEMP_DIR/$KARABINER_PKG"; then + log_info "Installing Karabiner driver (requires sudo)" + ensure_sudo + sudo installer -pkg "$TEMP_DIR/$KARABINER_PKG" -target / + log_success "Karabiner driver installed" + else + log_error "Failed to download Karabiner driver" + exit 1 + fi +fi + +# Activate Karabiner driver (run in background with timeout workaround) +log_step "Activating Karabiner driver" +# macOS doesn't have timeout command, use perl-based alternative +perl -e 'alarm 60; exec @ARGV' /Applications/.Karabiner-VirtualHIDDevice-Manager.app/Contents/MacOS/Karabiner-VirtualHIDDevice-Manager activate || true +log_info "Driver activation completed (may require approval in System Settings)" + +# Set up LaunchDaemon for Karabiner VirtualHIDDevice daemon +log_step "Setting up Karabiner daemon to start on boot" +DAEMON_PLIST="/Library/LaunchDaemons/org.pqrs.karabiner.virtualhiddevice.daemon.plist" + +if [[ -f "$DAEMON_PLIST" ]]; then + log_info "LaunchDaemon already configured" +else + log_info "Creating LaunchDaemon plist (requires sudo)" + ensure_sudo + + sudo tee "$DAEMON_PLIST" > /dev/null << 'EOF' + + + + + Label + org.pqrs.karabiner.virtualhiddevice.daemon + ProgramArguments + + /Library/Application Support/org.pqrs/Karabiner-DriverKit-VirtualHIDDevice/Applications/Karabiner-VirtualHIDDevice-Daemon.app/Contents/MacOS/Karabiner-VirtualHIDDevice-Daemon + + ProcessType + Interactive + RunAtLoad + + KeepAlive + + StandardOutPath + /var/log/karabiner-daemon.log + StandardErrorPath + /var/log/karabiner-daemon.log + + +EOF + + # Set correct permissions + sudo chmod 644 "$DAEMON_PLIST" + sudo chown root:wheel "$DAEMON_PLIST" + + # Load the daemon + log_info "Loading Karabiner daemon" + sudo launchctl load "$DAEMON_PLIST" || true + + log_success "Karabiner daemon configured to start on boot" +fi + +# Clean up temp directory +rm -rf "$TEMP_DIR" + +# Download and install kanata binary +log_step "Installing kanata v${KANATA_VERSION}" + +KANATA_ZIP="kanata-macos-binaries-arm64-v${KANATA_VERSION}.zip" +KANATA_URL="https://github.com/jtroo/kanata/releases/download/v${KANATA_VERSION}/${KANATA_ZIP}" +INSTALL_DIR="$HOME/.local/bin" +KANATA_PATH="$INSTALL_DIR/kanata" +TEMP_KANATA=$(mktemp -d) + +ensure_dir "$INSTALL_DIR" + +log_info "Downloading kanata v${KANATA_VERSION} for ARM64" +if download_file "$KANATA_URL" "$TEMP_KANATA/$KANATA_ZIP"; then + log_info "Extracting kanata binary" + cd "$TEMP_KANATA" + unzip -q "$KANATA_ZIP" + + # Find the binary (might be kanata_macos_arm64 or similar) + BINARY=$(find . -name "kanata*" -type f | head -1) + + if [[ -n "$BINARY" ]]; then + mv "$BINARY" "$KANATA_PATH" + chmod +x "$KANATA_PATH" + log_success "kanata installed to $KANATA_PATH" + else + log_error "Could not find kanata binary in zip" + exit 1 + fi + + rm -rf "$TEMP_KANATA" +else + log_error "Failed to download kanata" + exit 1 +fi + +# Verify installation +if command_exists kanata; then + VERSION=$(kanata --version 2>&1 | head -1) + log_success "kanata installation completed: $VERSION" +else + log_warning "kanata installed but not in PATH. Add $INSTALL_DIR to your PATH" +fi + +# Set up LaunchDaemon to run kanata on boot +log_step "Setting up kanata to start on boot" +KANATA_PLIST="/Library/LaunchDaemons/com.kanata.plist" +KANATA_CONFIG="$HOME/.config/kanata/config.kbd" + +log_info "Creating kanata LaunchDaemon (requires sudo)" +ensure_sudo + +sudo tee "$KANATA_PLIST" > /dev/null << EOF + + + + + Label + com.kanata + ProgramArguments + + $KANATA_PATH + --cfg + $KANATA_CONFIG + + RunAtLoad + + KeepAlive + + StandardErrorPath + /var/log/kanata.err + StandardOutPath + /var/log/kanata.out + + +EOF + +sudo chmod 644 "$KANATA_PLIST" +sudo chown root:wheel "$KANATA_PLIST" + +log_success "kanata LaunchDaemon created" + +# Set up passwordless sudo for kanata service management +log_step "Setting up passwordless sudo for kanata management" +SUDOERS_FILE="/etc/sudoers.d/kanata" + +sudo tee "$SUDOERS_FILE" > /dev/null << 'SUDOEOF' +# Allow passwordless sudo for kanata service management +%admin ALL=(root) NOPASSWD: /bin/launchctl bootout system /Library/LaunchDaemons/com.kanata.plist +%admin ALL=(root) NOPASSWD: /bin/launchctl bootstrap system /Library/LaunchDaemons/com.kanata.plist +%admin ALL=(root) NOPASSWD: /bin/launchctl kickstart -k system/com.kanata +SUDOEOF + +sudo chmod 440 "$SUDOERS_FILE" +log_success "Sudoers configured for passwordless kanata management" +log_info "kanata will start automatically after 'dot build kanata' deploys the config" + +echo "" +log_warning "IMPORTANT: Kanata requires system permissions" +log_info "1. Approve the Karabiner extension in System Settings > Privacy & Security if needed" +log_info "2. Restart your Mac if prompted" +log_info "3. Grant Input Monitoring permissions to: $KANATA_PATH" +log_info " Go to: System Settings > Privacy & Security > Input Monitoring" +log_info "4. Run 'dot build kanata' to deploy configuration and start kanata" +log_info "" +log_info "Manage kanata service without password:" +log_info " sudo launchctl bootout system /Library/LaunchDaemons/com.kanata.plist" +log_info " sudo launchctl bootstrap system /Library/LaunchDaemons/com.kanata.plist" +echo "" + diff --git a/shared/ghostty/build b/shared/ghostty/build new file mode 100755 index 00000000..aae786f0 --- /dev/null +++ b/shared/ghostty/build @@ -0,0 +1,36 @@ +#!/bin/bash + +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +DOT_HOME="$(dirname "$(dirname "$SCRIPT_DIR")")" + +# Detect OS and source appropriate include file +if [[ "$OSTYPE" == "darwin"* ]]; then + source "$DOT_HOME/lib/macos/include.sh" +else + source "$DOT_HOME/lib/debian/include.sh" +fi + +MODULE="ghostty" +init_module_logging "$MODULE" + +log_header "Building Ghostty Configuration" + +# Create Ghostty config directory +log_step "Creating Ghostty config directory" +mkdir -p "$HOME/.config/ghostty" + +# Deploy Ghostty configuration +log_step "Deploying Ghostty configuration" +if [[ -f "$SCRIPT_DIR/config/config" ]]; then + cp "$SCRIPT_DIR/config/config" "$HOME/.config/ghostty/config" + log_info "Deployed Ghostty config to ~/.config/ghostty/config" +else + log_error "Ghostty config file not found" + finalize_module_logging "failed" + exit 1 +fi + +log_success "Ghostty configuration completed" +finalize_module_logging "success" \ No newline at end of file diff --git a/debian/tools/01-ghostty/config/config b/shared/ghostty/config/config similarity index 66% rename from debian/tools/01-ghostty/config/config rename to shared/ghostty/config/config index a005ce39..7f6f4b5b 100644 --- a/debian/tools/01-ghostty/config/config +++ b/shared/ghostty/config/config @@ -1,5 +1,9 @@ # Ghostty terminal configuration +# macOS: Make left Option/Alt act as Meta key for terminal shortcuts (Alt+f, Alt+b, etc.) +# Right Option/Alt will still produce special characters (ń, ƒ, etc.) +macos-option-as-alt = left + # Cursor cursor-style = block cursor-style-blink = false diff --git a/shared/ghostty/install b/shared/ghostty/install new file mode 100755 index 00000000..994211ad --- /dev/null +++ b/shared/ghostty/install @@ -0,0 +1,71 @@ +#!/bin/bash + +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +DOT_HOME="$(dirname "$(dirname "$(dirname "$SCRIPT_DIR")")")" + +source "$DOT_HOME/lib/debian/include.sh" + +MODULE="ghostty" +init_module_logging "$MODULE" + +log_header "Installing Ghostty Terminal" + +# Install dependencies +log_step "Installing build dependencies" +PACKAGES=( + "libgtk-4-dev" + "libadwaita-1-dev" + "git" + "blueprint-compiler" + "gettext" + "libxml2-utils" + "libgtk4-layer-shell-dev" +) + +install_packages "${PACKAGES[@]}" + +if ! command_exists mise; then + log_error "mise not found. Please install mise first" + log_info "Run: dot install tools/00-mise" + exit 0 +fi + +# Clone or update Ghostty repository +log_step "Setting up Ghostty repository" +GHOSTTY_DIR="$HOME/Repositories/ghostty" +GHOSTTY_VERSION="v1.2.2" +GHOSTTY_ZIG_VERSION="0.14" + +if [[ ! -d "$GHOSTTY_DIR" ]]; then + log_info "Cloning Ghostty repository" + git clone https://github.com/ghostty-org/ghostty "$GHOSTTY_DIR" +else + log_info "Updating existing Ghostty repository" + cd "$GHOSTTY_DIR" + git fetch +fi + +# Checkout specific version +log_step "Checking out Ghostty version $GHOSTTY_VERSION" +cd "$GHOSTTY_DIR" +git checkout "$GHOSTTY_VERSION" + +# Build Ghostty +log_step "Building Ghostty" +log_info "Running zig build with mise (this may take a while)" +pushd "$GHOSTTY_DIR" +mise exec zig@$GHOSTTY_ZIG_VERSION -- zig build -p "$HOME/.local" -Doptimize=ReleaseFast +popd + +# Verify installation +if [[ -f "$HOME/.local/bin/ghostty" ]]; then + log_success "Ghostty installed successfully to $HOME/.local/bin/ghostty" +else + log_error "Ghostty installation failed - binary not found" + exit 1 +fi + +log_success "Ghostty installation completed" +finalize_module_logging "success" diff --git a/shared/shell/build b/shared/shell/build new file mode 100755 index 00000000..f16126e9 --- /dev/null +++ b/shared/shell/build @@ -0,0 +1,89 @@ +#!/bin/bash + +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +DOT_HOME="$(dirname "$(dirname "$SCRIPT_DIR")")" + +# Source universal libraries (OS-agnostic) +source "$DOT_HOME/lib/colors.sh" +source "$DOT_HOME/lib/logging.sh" + +MODULE="shell" +init_module_logging "$MODULE" + +log_header "Building Shell Configuration" + +# Deploy shell configuration files from existing plans +log_step "Deploying shell configuration" + +# Bash configuration +log_step "Installing bash configuration" + +# Copy bash configuration files +if [[ -f "$SCRIPT_DIR/config/.bashrc" ]]; then + cp "$SCRIPT_DIR/config/.bashrc" "$HOME/.bashrc" + log_info "Deployed .bashrc" +fi + +if [[ -f "$SCRIPT_DIR/config/.profile" ]]; then + cp "$SCRIPT_DIR/config/.profile" "$HOME/.profile" + log_info "Deployed .profile" +fi + +if [[ -f "$SCRIPT_DIR/config/.bash_profile" ]]; then + cp "$SCRIPT_DIR/config/.bash_profile" "$HOME/.bash_profile" + log_info "Deployed .bash_profile" +fi + +# Pry configuration +if [[ -f "$SCRIPT_DIR/config/.pryrc" ]]; then + cp "$SCRIPT_DIR/config/.pryrc" "$HOME/.pryrc" + log_info "Deployed .pryrc" +fi + +# IRB configuration +if [[ -f "$SCRIPT_DIR/config/.irbrc" ]]; then + cp "$SCRIPT_DIR/config/.irbrc" "$HOME/.irbrc" + log_info "Deployed .irbrc" +fi + +# Readline configuration +if [[ -f "$SCRIPT_DIR/config/.inputrc" ]]; then + cp "$SCRIPT_DIR/config/.inputrc" "$HOME/.inputrc" + log_info "Deployed .inputrc" +fi + +# Shared aliases +if [[ -f "$SCRIPT_DIR/config/.aliases" ]]; then + cp "$SCRIPT_DIR/config/.aliases" "$HOME/.aliases" + log_info "Deployed .aliases" +fi + +# Zsh configuration +if [[ -f "$SCRIPT_DIR/config/.zshrc" ]]; then + cp "$SCRIPT_DIR/config/.zshrc" "$HOME/.zshrc" + log_info "Deployed .zshrc" +fi + +# Deploy .profile.local example if it doesn't exist +if [[ ! -f "$HOME/.profile.local" ]] && [[ -f "$SCRIPT_DIR/config/.profile.local.example" ]]; then + cp "$SCRIPT_DIR/config/.profile.local.example" "$HOME/.profile.local" + log_info "Deployed .profile.local from example (customize as needed)" +fi + +# Bash completions +log_step "Installing bash completions" +mkdir -p "$HOME/.bashrc.d" + +# Source dot completions from top-level +if [[ -f "$DOT_HOME/completions/dot.bash" ]]; then + cp "$DOT_HOME/completions/dot.bash" "$HOME/.bashrc.d/dot-completion.bash" + log_info "Deployed dot bash completions" +fi + +# Zsh completions +# TODO: Add proper zsh completions (bash completions don't work in zsh) + +log_success "Shell configuration completed" +finalize_module_logging "success" diff --git a/shared/shell/config/.aliases b/shared/shell/config/.aliases new file mode 100644 index 00000000..a7b680df --- /dev/null +++ b/shared/shell/config/.aliases @@ -0,0 +1,4 @@ +# ~/.aliases +# Shared aliases for bash and zsh + +alias ll='ls -alF' diff --git a/debian/shell/config/.bash_profile b/shared/shell/config/.bash_profile similarity index 100% rename from debian/shell/config/.bash_profile rename to shared/shell/config/.bash_profile diff --git a/debian/shell/config/.bashrc b/shared/shell/config/.bashrc similarity index 83% rename from debian/shell/config/.bashrc rename to shared/shell/config/.bashrc index 5b932a9b..8a09a8fa 100644 --- a/debian/shell/config/.bashrc +++ b/shared/shell/config/.bashrc @@ -10,11 +10,6 @@ if ! [[ "$PATH" =~ "$HOME/.local/bin:" ]]; then PATH="$HOME/.local/bin:$PATH" fi -# Add dotfiles bin to PATH -if ! [[ "$PATH" =~ "$HOME/Repositories/dotfiles/bin:" ]]; then - PATH="$HOME/Repositories/dotfiles/bin:$PATH" -fi - export PATH # User specific aliases and functions @@ -26,20 +21,10 @@ if [ -d ~/.bashrc.d ]; then done fi -# Aliases -alias ll='ls -alF' -alias la='ls -A' -alias l='ls -CF' -alias grep='grep --color=auto' -alias fgrep='fgrep --color=auto' -alias egrep='egrep --color=auto' - -# Git aliases -alias gs='git status' -alias ga='git add' -alias gc='git commit' -alias gp='git push' -alias gl='git pull' +# Source shared aliases +if [ -f "$HOME/.aliases" ]; then + . "$HOME/.aliases" +fi # History settings HISTSIZE=10000 diff --git a/debian/shell/config/.inputrc b/shared/shell/config/.inputrc similarity index 100% rename from debian/shell/config/.inputrc rename to shared/shell/config/.inputrc diff --git a/debian/shell/config/.irbrc b/shared/shell/config/.irbrc similarity index 100% rename from debian/shell/config/.irbrc rename to shared/shell/config/.irbrc diff --git a/debian/shell/config/.profile b/shared/shell/config/.profile similarity index 64% rename from debian/shell/config/.profile rename to shared/shell/config/.profile index 0dac4ac4..904f9d11 100644 --- a/debian/shell/config/.profile +++ b/shared/shell/config/.profile @@ -1,9 +1,16 @@ # ~/.profile +# Add user's local bin to PATH if [ -d "$HOME/.local/bin" ] ; then PATH="$HOME/.local/bin:$PATH" fi +# Add dotfiles bin to PATH +DOTFILES_BIN="$HOME/Repositories/dotfiles/bin" +if [ -d "$DOTFILES_BIN" ] && ! echo "$PATH" | grep -q "$DOTFILES_BIN" ; then + PATH="$DOTFILES_BIN:$PATH" +fi + # Set default editor export EDITOR=emacs export VISUAL=emacs diff --git a/debian/shell/config/.profile.local.example b/shared/shell/config/.profile.local.example similarity index 100% rename from debian/shell/config/.profile.local.example rename to shared/shell/config/.profile.local.example diff --git a/debian/shell/config/.pryrc b/shared/shell/config/.pryrc similarity index 100% rename from debian/shell/config/.pryrc rename to shared/shell/config/.pryrc diff --git a/shared/shell/config/.zshrc b/shared/shell/config/.zshrc new file mode 100644 index 00000000..cdff382a --- /dev/null +++ b/shared/shell/config/.zshrc @@ -0,0 +1,44 @@ +# ~/.zshrc + +# Source common profile (PATH, EDITOR, etc.) +if [ -f "$HOME/.profile" ]; then + source "$HOME/.profile" +fi + +# Source shared aliases +if [ -f "$HOME/.aliases" ]; then + source "$HOME/.aliases" +fi + +# History settings +HISTSIZE=10000 +SAVEHIST=20000 +HISTFILE=~/.zsh_history +setopt SHARE_HISTORY +setopt HIST_IGNORE_DUPS +setopt HIST_IGNORE_SPACE + +# Zsh completions +autoload -Uz compinit +compinit + +# Note: Bash completions don't work in zsh +# TODO: Add proper zsh completions later + +# Git prompt (using vcs_info) +autoload -Uz vcs_info +precmd_vcs_info() { vcs_info } +precmd_functions+=( precmd_vcs_info ) +setopt prompt_subst +zstyle ':vcs_info:git:*' formats '[%b%u%c] ' +zstyle ':vcs_info:*' check-for-changes true +zstyle ':vcs_info:*' unstagedstr '!' +zstyle ':vcs_info:*' stagedstr '+' + +# Colorful prompt with git info +PROMPT='%F{yellow}%n%f%F{cyan}@%f%F{magenta}%m%f: %F{green}%~%f %F{magenta}${vcs_info_msg_0_}%f%F{cyan}%#%f ' + +# Tool version manager +if [ -f ~/.local/bin/mise ]; then + eval "$(~/.local/bin/mise activate zsh)" +fi diff --git a/debian/tools/emacs/config/config.org b/shared/tools/emacs/config/config.org similarity index 98% rename from debian/tools/emacs/config/config.org rename to shared/tools/emacs/config/config.org index c0a5ec88..bb5df376 100644 --- a/debian/tools/emacs/config/config.org +++ b/shared/tools/emacs/config/config.org @@ -138,12 +138,14 @@ Different machines get different values. #+begin_src emacs-lisp (defvar vik/big-font-size (cond + ((eq system-type 'darwin) 180) ;; macOS needs larger due to scaling ((string= (getenv "DESKTOP") "1") 180) ((string= (getenv "LAPTOP") "2") 170) (t 170))) (defvar vik/default-font-size (cond + ((eq system-type 'darwin) 180) ;; macOS needs larger due to scaling ((string= (getenv "DESKTOP") "1") 110) ((string= (getenv "LAPTOP") "2") 150) (t 110))) @@ -753,11 +755,22 @@ Use =C-h .= to look up documentation of thing at point. (setq eldoc-echo-area-prefer-doc-buffer t) #+end_src ** Mise +Shared mise configuration: #+begin_src elisp (use-package mise :ensure t :hook (after-init . global-mise-mode)) #+end_src + +macOS-specific PATH and mise executable: +#+begin_src elisp :tangle (if (eq system-type 'darwin) "yes" "no") +(use-package exec-path-from-shell + :ensure t + :config + (exec-path-from-shell-initialize)) + +(setq mise-executable (expand-file-name "~/.local/bin/mise")) +#+end_src ** Eglot Attaches eglot to every programming language buffer: #+begin_src emacs-lisp @@ -985,6 +998,10 @@ Attaches eglot to every programming language buffer: (with-eval-after-load 'dired (define-key dired-mode-map (kbd "e") 'eshell)) +;; Use GNU ls from coreutils on macOS +(when (eq system-type 'darwin) + (setq insert-directory-program "/opt/homebrew/bin/gls")) + (setq dired-listing-switches "-lah --group-directories-first") #+end_src diff --git a/debian/tools/emacs/config/early-init.el b/shared/tools/emacs/config/early-init.el similarity index 100% rename from debian/tools/emacs/config/early-init.el rename to shared/tools/emacs/config/early-init.el diff --git a/debian/tools/emacs/config/init.el b/shared/tools/emacs/config/init.el similarity index 100% rename from debian/tools/emacs/config/init.el rename to shared/tools/emacs/config/init.el diff --git a/shared/tools/git/build b/shared/tools/git/build new file mode 100755 index 00000000..e0d0ef25 --- /dev/null +++ b/shared/tools/git/build @@ -0,0 +1,54 @@ +#!/bin/bash + +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +DOT_HOME="$(dirname "$(dirname "$(dirname "$SCRIPT_DIR")")")" + +# Source universal libraries (OS-agnostic) +source "$DOT_HOME/lib/colors.sh" +source "$DOT_HOME/lib/logging.sh" + +MODULE="git" +init_module_logging "$MODULE" + +log_header "Building Git Configuration" + +log_step "Installing Git configuration" + +# Copy .gitconfig file +if [[ -f "$SCRIPT_DIR/config/.gitconfig" ]]; then + cp "$SCRIPT_DIR/config/.gitconfig" "$HOME/.gitconfig" + log_success "Git configuration installed" +else + log_warning "Git configuration file not found" +fi + +# Copy global gitignore file +if [[ -f "$SCRIPT_DIR/config/ignore" ]]; then + mkdir -p "$HOME/.config/git" + cp "$SCRIPT_DIR/config/ignore" "$HOME/.config/git/ignore" + log_success "Global gitignore installed" +else + log_warning "Global gitignore file not found" +fi + +log_step "Installing git scripts" + +# Create scripts directory +mkdir -p "$HOME/.local/bin" + +# Copy git utility scripts +if [[ -d "$SCRIPT_DIR/scripts" ]]; then + for script in "$SCRIPT_DIR/scripts"/*; do + if [[ -f "$script" ]]; then + script_name=$(basename "$script") + cp "$script" "$HOME/.local/bin/$script_name" + chmod +x "$HOME/.local/bin/$script_name" + log_info "Installed script: $script_name" + fi + done +fi + +log_success "Git configuration build completed" +finalize_module_logging "success" diff --git a/debian/tools/git/config/.gitconfig b/shared/tools/git/config/.gitconfig similarity index 81% rename from debian/tools/git/config/.gitconfig rename to shared/tools/git/config/.gitconfig index dbb0d23c..9c859cb4 100644 --- a/debian/tools/git/config/.gitconfig +++ b/shared/tools/git/config/.gitconfig @@ -2,10 +2,8 @@ email = vikdotdev@gmail.com name = Viktor Habchak signingkey = 7392D21113383CBB -[credential "https://github.com"] - helper = !/usr/bin/gh auth git-credential -[credential "https://gist.github.com"] - helper = !/usr/bin/gh auth git-credential +[include] + path = ~/.gitconfig.os [alias] ci = commit st = status diff --git a/debian/tools/git/config/ignore b/shared/tools/git/config/ignore similarity index 100% rename from debian/tools/git/config/ignore rename to shared/tools/git/config/ignore diff --git a/debian/tools/git/scripts/git-branch-files-changed b/shared/tools/git/scripts/git-branch-files-changed similarity index 100% rename from debian/tools/git/scripts/git-branch-files-changed rename to shared/tools/git/scripts/git-branch-files-changed diff --git a/debian/tools/git/scripts/git-default-branch b/shared/tools/git/scripts/git-default-branch similarity index 100% rename from debian/tools/git/scripts/git-default-branch rename to shared/tools/git/scripts/git-default-branch diff --git a/debian/tools/git/scripts/git-deploy b/shared/tools/git/scripts/git-deploy similarity index 100% rename from debian/tools/git/scripts/git-deploy rename to shared/tools/git/scripts/git-deploy diff --git a/debian/tools/git/scripts/git-log-changed b/shared/tools/git/scripts/git-log-changed similarity index 100% rename from debian/tools/git/scripts/git-log-changed rename to shared/tools/git/scripts/git-log-changed diff --git a/debian/tools/git/scripts/git-nuke b/shared/tools/git/scripts/git-nuke similarity index 100% rename from debian/tools/git/scripts/git-nuke rename to shared/tools/git/scripts/git-nuke diff --git a/debian/tools/git/scripts/git-summary b/shared/tools/git/scripts/git-summary similarity index 100% rename from debian/tools/git/scripts/git-summary rename to shared/tools/git/scripts/git-summary diff --git a/shared/tools/gpg/build b/shared/tools/gpg/build new file mode 100755 index 00000000..0f53bead --- /dev/null +++ b/shared/tools/gpg/build @@ -0,0 +1,39 @@ +#!/bin/bash + +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +DOT_HOME="$(dirname "$(dirname "$(dirname "$SCRIPT_DIR")")")" + +# Source universal libraries (OS-agnostic) +source "$DOT_HOME/lib/colors.sh" +source "$DOT_HOME/lib/logging.sh" +source "$DOT_HOME/lib/utils.sh" + +MODULE="gpg" +init_module_logging "$MODULE" + +log_header "Building GPG Configuration" + +log_step "Installing GPG agent configuration" + +# Create GPG directory if it doesn't exist +mkdir -p "$HOME/.gnupg" + +# Set proper permissions for GPG directory +chmod 700 "$HOME/.gnupg" + +# Copy GPG agent configuration +if [[ -f "$SCRIPT_DIR/config/gpg-agent.conf" ]]; then + cp "$SCRIPT_DIR/config/gpg-agent.conf" "$HOME/.gnupg/gpg-agent.conf" + chmod 600 "$HOME/.gnupg/gpg-agent.conf" + + # Restart GPG agent to pick up new config + if command_exists gpgconf; then + log_info "Reloading GPG agent configuration" + gpgconf --reload gpg-agent || log_warning "Failed to reload GPG agent" + fi +fi + +log_success "GPG configuration build completed" +finalize_module_logging "success" diff --git a/debian/tools/gpg/config/gpg-agent.conf b/shared/tools/gpg/config/gpg-agent.conf similarity index 100% rename from debian/tools/gpg/config/gpg-agent.conf rename to shared/tools/gpg/config/gpg-agent.conf diff --git a/debian/tools/00-mise/config/mise.toml b/shared/tools/mise/config/mise.toml similarity index 100% rename from debian/tools/00-mise/config/mise.toml rename to shared/tools/mise/config/mise.toml