aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsrdusr <trevorgray@srdusr.com>2025-09-04 04:23:23 +0200
committersrdusr <trevorgray@srdusr.com>2025-09-04 04:23:23 +0200
commit36e2a2b3853c66540dfae57f82e88d27e8d112f2 (patch)
tree77004c6a2604c8bf3f9cb585bcbbb0d2ca027c3b
parent48ea035ccc7771ffc6e4414cd8a28930bbf4f7da (diff)
downloaddotfiles-36e2a2b3853c66540dfae57f82e88d27e8d112f2.tar.gz
dotfiles-36e2a2b3853c66540dfae57f82e88d27e8d112f2.zip
Testing
-rwxr-xr-xlinux/home/install.sh1512
1 files changed, 757 insertions, 755 deletions
diff --git a/linux/home/install.sh b/linux/home/install.sh
index 9ef80d0..1b52e27 100755
--- a/linux/home/install.sh
+++ b/linux/home/install.sh
@@ -1,925 +1,927 @@
#!/usr/bin/env bash
-# Execute the main function if script is run directly
-if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
- main "$@"
-fi
-
-# Enhanced Dotfiles Installation Script
-#======================================
-
-set -euo pipefail # Exit on error, undefined vars, pipe failures
-
#======================================
-# Variables & Configuration
+# Variables
#======================================
-# Color definitions for pretty UI
+# Color definitions
NOCOLOR='\033[0m'
-RED='\033[0;31m'
-GREEN='\033[0;32m'
-YELLOW='\033[0;33m'
-BLUE='\033[0;34m'
-MAGENTA='\033[0;35m'
-CYAN='\033[0;36m'
-WHITE='\033[0;37m'
-BOLD='\033[1m'
-
-# Dotfiles configuration
-DOTFILES_URL='https://github.com/srdusr/dotfiles.git'
-DOTFILES_DIR="$HOME/.cfg"
-LOG_FILE="$HOME/.local/share/dotfiles_install.log"
-TRASH_DIR="$HOME/.local/share/Trash"
+RED='\033[00;31m'
+GREEN='\033[00;32m'
-# Installation tracking
-INSTALL_SUMMARY=()
-FAILED_ITEMS=()
-SKIPPED_ITEMS=()
-
-#======================================
-# UI Functions
-#======================================
-
-# Print colorized output
-print_color() {
- local color="$1"
- local message="$2"
- echo -e "${color}${message}${NOCOLOR}"
-}
+# Dotfiles
+dotfiles_url='https://github.com/srdusr/dotfiles.git'
+dotfiles_dir="$HOME/.cfg"
-# Print header with decorative border
-print_header() {
- local title="$1"
- local border_char="="
- local border_length=60
+# Log file
+LOG_FILE="dotfiles.log"
+TRASH_DIR="$HOME/.local/share/Trash"
- echo
- print_color "$CYAN" "$(printf '%*s' $border_length '' | tr ' ' "$border_char")"
- print_color "$CYAN$BOLD" "$(printf '%*s' $(((border_length + ${#title}) / 2)) "$title")"
- print_color "$CYAN" "$(printf '%*s' $border_length '' | tr ' ' "$border_char")"
- echo
-}
+# Ensure Trash directory exists
+if [ ! -d "$TRASH_DIR" ]; then
+ mkdir -p "$TRASH_DIR"
+ if [ $? -ne 0 ]; then
+ echo "Failed to create Trash directory. Exiting..."
+ exit 1
+ fi
+fi
-# Print section header
-print_section() {
- local title="$1"
- echo
- print_color "$BLUE$BOLD" "▶ $title"
- print_color "$BLUE" "$(printf '%*s' $((${#title} + 2)) '' | tr ' ' '-')"
-}
+# Move log file to Trash directory
+mv -f "$LOG_FILE" "$TRASH_DIR/"
-# Print success message
-print_success() {
- local message="$1"
- print_color "$GREEN" "✓ $message"
- INSTALL_SUMMARY+=("✓ $message")
-}
+# Redirect stderr to both stderr and log file
+exec 2> >(tee -a "$LOG_FILE")
-# Print error message
-print_error() {
+# Function to log errors
+log_error() {
local message="$1"
- print_color "$RED" "✗ $message" >&2
- FAILED_ITEMS+=("✗ $message")
+ echo "[ERROR] $(date +'%Y-%m-%d %H:%M:%S') - $message" | tee -a "$LOG_FILE" >&2
}
-# Print warning message
-print_warning() {
+# Function to handle errors
+handle_error() {
local message="$1"
- print_color "$YELLOW" "⚠ $message"
+ log_error "$message"
+ exit 1
}
-# Print info message
-print_info() {
+# Function to log completion messages
+log_complete() {
local message="$1"
- print_color "$CYAN" "ℹ $message"
+ echo "[COMPLETE] $(date +'%Y-%m-%d %H:%M:%S') - $message" | tee -a "$LOG_FILE"
}
-# Print skip message
-print_skip() {
+# Function to handle completion
+handle_complete() {
local message="$1"
- print_color "$YELLOW" "⏭ $message"
- SKIPPED_ITEMS+=("⏭ $message")
+ log_complete "$message"
}
-#======================================
-# Logging Functions
-#======================================
-
-# Setup logging
-setup_logging() {
- local log_dir
- log_dir="$(dirname "$LOG_FILE")"
+# Function to prompt the user
+prompt_user() {
+ local prompt="$1 [Y/n] "
+ local default_response="${2:-Y}"
+ local response
- # Create log directory if it doesn't exist
- if [[ ! -d "$log_dir" ]]; then
- mkdir -p "$log_dir" || {
- print_error "Failed to create log directory: $log_dir"
- exit 1
- }
- fi
+ read -p "$prompt" -n 1 -r -e -i "$default_response" response
+ case "${response^^}" in
+ Y) return 0 ;;
+ N) return 1 ;;
+ *) handle_error "Invalid choice. Exiting.." && exit ;;
+ esac
+}
- # Create trash directory if it doesn't exist
- if [[ ! -d "$TRASH_DIR" ]]; then
- mkdir -p "$TRASH_DIR" || {
- print_error "Failed to create trash directory: $TRASH_DIR"
- exit 1
- }
+# Function to temporarily unset GIT_WORK_TREE
+function git_without_work_tree() {
+ # Check if the current directory is a Git repository
+ if [ -d "$PWD/.git" ]; then
+ # Check if the current directory is inside the work tree
+ if [ "$(git rev-parse --is-inside-work-tree 2>/dev/null)" = "true" ]; then
+ # If it's a Git repository and inside the work tree, proceed with unsetting GIT_WORK_TREE
+ GIT_WORK_TREE_OLD="$GIT_WORK_TREE"
+ unset GIT_WORK_TREE
+ "$@"
+ export GIT_WORK_TREE="$GIT_WORK_TREE_OLD"
+ else
+ # If it's a Git repository but not inside the work tree, call git command directly
+ git "$@"
+ fi
+ else
+ # If it's not a Git repository, call git command directly
+ git "$@"
fi
+}
- # Move old log file to trash if it exists
- [[ -f "$LOG_FILE" ]] && mv "$LOG_FILE" "$TRASH_DIR/"
-
- # Initialize log file
- {
- echo "======================================="
- echo "Dotfiles Installation Log"
- echo "Date: $(date)"
- echo "User: $USER"
- echo "Host: $HOSTNAME"
- echo "OS: $(uname -s)"
- echo "======================================="
- echo
- } > "$LOG_FILE"
+# Set alias conditionally
+alias git='git_without_work_tree'
- # Redirect stderr to log file while keeping it visible
- exec 2> >(tee -a "$LOG_FILE" >&2)
+# Check for privilege escalation tools
+#--------------------------------------
+check_privilege_tools() {
+ if [ -x "$(command -v sudo)" ]; then
+ PRIVILEGE_TOOL="sudo"
+ elif [ -x "$(command -v doas)" ]; then
+ PRIVILEGE_TOOL="doas"
+ elif [ -x "$(command -v pkexec)" ]; then
+ PRIVILEGE_TOOL="pkexec"
+ elif [ -x "$(command -v dzdo)" ]; then
+ PRIVILEGE_TOOL="dzdo"
+ elif [ "$(id -u)" -eq 0 ]; then
+ PRIVILEGE_TOOL="" # root
+ else
+ PRIVILEGE_TOOL="" # No privilege escalation mechanism found
+ printf "\n${RED}Error: No privilege escalation tool (sudo, doas, pkexec, dzdo, or root privileges) found. You may not have sufficient permissions to run this script.${NOCOLOR}\n"
+ printf "\nAttempt to continue Installation (might fail without a privilege escalation tool)? [yes/no] "
+ read continue_choice
+ case $continue_choice in
+ [Yy] | [Yy][Ee][Ss]) ;;
+ [Nn] | [Nn][Oo]) exit ;;
+ *) handle_error "Invalid choice. Exiting..." && exit ;;
+ esac
+ fi
}
-# Log function
-log_message() {
- local level="$1"
- local message="$2"
- echo "[$level] $(date +'%Y-%m-%d %H:%M:%S') - $message" | tee -a "$LOG_FILE"
+# Function to set locale to en_US.UTF-8
+set_locale() {
+ echo "Setting locale to en_US.UTF-8..."
+ if ! "$PRIVILEGE_TOOL" localectl set-locale LANG=en_US.UTF-8; then
+ handle_error "Failed to set locale to en_US.UTF-8"
+ fi
}
-#======================================
-# User Interaction Functions
-#======================================
-
-# Prompt function
-prompt_user() {
- local question="$1"
- local default="${2:-Y}"
- local response
-
- while true; do
- if [[ "$default" == "Y" ]]; then
- print_color "$YELLOW" "$question [Y/n]: "
+# Change shell to zsh
+change_shell() {
+ if prompt_user "Change shell to zsh?"; then
+ if command -v zsh &>/dev/null; then
+ chsh -s "$(which zsh)" && echo "Shell changed to zsh. Please log out and log back in to apply the changes."
+ #sudo chsh -s "$(which zsh)" "$(whoami)"
else
- print_color "$YELLOW" "$question [y/N]: "
- fi
-
- read -r response
-
- # Use default if no response
- if [[ -z "$response" ]]; then
- response="$default"
+ echo "Error: zsh is not installed."
fi
+ else
+ echo "Shell not changed."
+ fi
+}
- case "${response^^}" in
- Y|YES) return 0 ;;
- N|NO) return 1 ;;
- *) print_warning "Please answer Y/yes or N/no" ;;
- esac
- done
+# Initialize git submodules
+submodules() {
+ echo "Initializing submodule(s)"
+ git submodule update --init --recursive
}
-# Multi-choice prompt
-prompt_choice() {
- local question="$1"
- shift
- local choices=("$@")
- local choice
+# Install Zsh plugins
+install_zsh_plugins() {
+ local zsh_plugins_dir="$HOME/.config/zsh/plugins"
- echo
- print_color "$YELLOW$BOLD" "$question"
- for i in "${!choices[@]}"; do
- print_color "$CYAN" "$((i + 1)). ${choices[i]}"
- done
+ mkdir -p "$HOME/.config/zsh"
+ mkdir -p "$zsh_plugins_dir"
- while true; do
- print_color "$YELLOW" "Please enter your choice (1-${#choices[@]}): "
- read -r choice
+ if [ ! -d "$zsh_plugins_dir/zsh-you-should-use" ]; then
+ echo "Installing zsh-you-should-use..."
+ git clone https://github.com/MichaelAquilina/zsh-you-should-use.git "$zsh_plugins_dir/zsh-you-should-use"
+ else
+ echo "zsh-you-should-use is already installed."
+ fi
- if [[ "$choice" =~ ^[0-9]+$ ]] && ((choice >= 1 && choice <= ${#choices[@]})); then
- return $((choice - 1))
- else
- print_warning "Invalid choice. Please enter a number between 1 and ${#choices[@]}"
- fi
- done
+ if [ ! -d "$zsh_plugins_dir/zsh-syntax-highlighting" ]; then
+ echo "Installing zsh-syntax-highlighting..."
+ git clone https://github.com/zsh-users/zsh-syntax-highlighting.git "$zsh_plugins_dir/zsh-syntax-highlighting"
+ else
+ echo "zsh-syntax-highlighting is already installed."
+ fi
+
+ if [ ! -d "$zsh_plugins_dir/zsh-autosuggestions" ]; then
+ echo "Installing zsh-autosuggestions..."
+ git clone https://github.com/zsh-users/zsh-autosuggestions.git "$zsh_plugins_dir/zsh-autosuggestions"
+ else
+ echo "zsh-autosuggestions is already installed."
+ fi
}
+#==============================================================================
+
#======================================
-# System Detection Functions
+# Common Sources/Dependencies
#======================================
+echo "$dotfiles_dir" >>.gitignore
+echo "install.sh" >>.gitignore
-# Detect operating system
-detect_os() {
- case "$(uname -s)" in
- Linux) CFG_OS="linux" ;;
- Darwin) CFG_OS="macos" ;;
- MINGW*|MSYS*|CYGWIN*) CFG_OS="windows" ;;
- *) CFG_OS="unknown" ;;
- esac
-
- print_info "Detected OS: $CFG_OS"
- log_message "INFO" "Detected operating system: $CFG_OS"
+# Dotfiles
+function config {
+ git --git-dir="$dotfiles_dir"/ --work-tree="$HOME" "$@"
}
-# Detect privilege escalation tools
-detect_privilege_tools() {
- if command -v sudo &>/dev/null; then
- PRIVILEGE_TOOL="sudo"
- elif command -v doas &>/dev/null; then
- PRIVILEGE_TOOL="doas"
- elif command -v pkexec &>/dev/null; then
- PRIVILEGE_TOOL="pkexec"
- elif [[ "$(id -u)" -eq 0 ]]; then
- PRIVILEGE_TOOL="" # Running as root
+# Function to install dotfiles
+install_dotfiles() {
+ # Check if the $dotfiles_dir directory exists
+ if [ -d "$dotfiles_dir" ]; then
+ config pull >/dev/null 2>&1
+ update=true
else
- PRIVILEGE_TOOL=""
- print_warning "No privilege escalation tool found"
- if prompt_user "Continue without privilege escalation? (Installation may fail for some components)" "N"; then
- print_info "Continuing without privilege escalation..."
- else
- print_error "Privilege escalation required. Exiting."
- exit 1
- fi
+ git clone --bare "$dotfiles_url" "$dotfiles_dir" >/dev/null 2>&1
+ update=false
fi
+ std_err_output=$(config checkout 2>&1 >/dev/null) || true
- [[ -n "$PRIVILEGE_TOOL" ]] && print_success "Using privilege escalation tool: $PRIVILEGE_TOOL"
-}
-
-# Detect Linux distribution
-detect_linux_distro() {
- if [[ ! -f /etc/os-release ]]; then
- print_error "/etc/os-release not found"
- return 1
+ if [[ $std_err_output == *"following untracked working tree files would be overwritten"* ]]; then
+ if [ "$update" = false ]; then
+ config checkout -- /dev/null 2>&1
+ fi
fi
+ config config status.showUntrackedFiles no
- source /etc/os-release
-
- case "$ID" in
- arch|manjaro|endeavouros) DISTRO="PACMAN" ;;
- debian|ubuntu|mint|pop) DISTRO="APT" ;;
- fedora|rhel|centos|rocky) DISTRO="DNF" ;;
- opensuse*|sles) DISTRO="ZYPPER" ;;
- gentoo) DISTRO="PORTAGE" ;;
- *)
- print_warning "Unknown distribution: $ID"
- # Try to detect package managers
- for pm in pacman apt dnf zypper emerge; do
- if command -v "$pm" &>/dev/null; then
- case "$pm" in
- pacman) DISTRO="PACMAN" ;;
- apt) DISTRO="APT" ;;
- dnf) DISTRO="DNF" ;;
- zypper) DISTRO="ZYPPER" ;;
- emerge) DISTRO="PORTAGE" ;;
- esac
- break
- fi
- done
+ git config --global include.path "$HOME.gitconfig.aliases"
- if [[ -z "${DISTRO:-}" ]]; then
- print_error "Could not detect package manager"
- return 1
- fi
- ;;
- esac
+ # Prompt the user if they want to overwrite existing files
+ if prompt_user "Do you want to overwrite existing files and continue with the dotfiles setup?"; then
+ config fetch origin main:main
- print_success "Detected Linux distribution: $ID (Package manager: $DISTRO)"
- log_message "INFO" "Detected Linux distribution: $ID, Package manager: $DISTRO"
-}
+ config reset --hard main
-#======================================
-# Utility Functions
-#======================================
+ config checkout -f
+ if [ $? -eq 0 ]; then
+ echo "Successfully backed up conflicting dotfiles in $dotfiles_dir-backup/ and imported $dotfiles_dir."
+ else
+ handle_error "Mission failed."
+ fi
+ else
+ # User chose not to overwrite existing files
+ handle_error "Aborted by user. Exiting..."
+ fi
+}
-# Check if command exists
-command_exists() {
- command -v "$1" &>/dev/null
+# Check if necessary dependencies are installed
+#--------------------------------------
+# Download dependencies (wget/curl)
+check_download_dependencies() {
+ if [ -x "$(command -v wget)" ]; then
+ DOWNLOAD_COMMAND="wget"
+ elif [ -x "$(command -v curl)" ]; then
+ DOWNLOAD_COMMAND="curl"
+ else
+ handle_error "Neither wget nor curl found. Please install one of them to continue!"
+ fi
}
-# Download file with progress
+# Download a file using wget or curl
download_file() {
local url="$1"
local output="$2"
- if command_exists wget; then
- wget --progress=bar:force -O "$output" "$url" 2>&1 | \
- while IFS= read -r line; do
- if [[ "$line" =~ [0-9]+% ]]; then
- printf "\r%s" "$line"
- fi
- done
- echo
- elif command_exists curl; then
- curl --progress-bar -o "$output" "$url"
+ if [ "$DOWNLOAD_COMMAND" = "wget" ]; then
+ if ! wget -q --show-progress -O "$output" "$url"; then
+ handle_error "Download failed. Exiting..."
+ exit 1
+ fi
+ elif [ "$DOWNLOAD_COMMAND" = "curl" ]; then
+ if ! curl --progress-bar -# -o "$output" "$url"; then
+ handle_error "Download failed. Exiting..."
+ exit 1
+ fi
else
- print_error "Neither wget nor curl found"
- return 1
+ echo "Unsupported download command: $DOWNLOAD_COMMAND"
+ exit 1
fi
}
-# Create directory with proper permissions
-create_dir() {
- local dir="$1"
- local permissions="${2:-755}"
+# Install yq
+install_yq() {
+ if ! command -v yq &>/dev/null; then
+ echo "yq not found, installing..."
+ local bin_dir="$HOME/.local/bin"
+ local yq_url="https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64"
+ local yq_path="$bin_dir/yq"
+
+ echo "Installing yq..."
+
+ # Create bin directory if it doesn't exist
+ mkdir -p "$bin_dir" || {
+ echo "Error: Failed to create directory $bin_dir"
+ return 1
+ }
+
+ # Download yq
+ download_file "$yq_url" "$yq_path" || return 1
- if [[ ! -d "$dir" ]]; then
- mkdir -p "$dir" || {
- print_error "Failed to create directory: $dir"
+ # Make yq executable
+ chmod +x "$yq_path" || {
+ echo "Error: Failed to set executable permissions for $yq_path"
return 1
}
- chmod "$permissions" "$dir"
- print_success "Created directory: $dir"
+
+ echo "yq installed successfully to $bin_dir."
+
+ # Add bin directory to PATH if not already added
+ if [[ ":$PATH:" != *":$bin_dir:"* ]]; then
+ echo "Adding $bin_dir to PATH"
+ echo "export PATH=\"$bin_dir:\$PATH\"" >>"$HOME/.bashrc"
+ export PATH="$bin_dir:$PATH"
+ fi
else
- print_info "Directory already exists: $dir"
+ echo "yq is already installed."
fi
}
+#------------------------------------------------------------------------------
+
+#==============================================================================
+
#======================================
-# Git Configuration Functions
+# Check Operating System
#======================================
-
-# Git wrapper to avoid conflicts
-git_without_work_tree() {
- if [[ -d "$PWD/.git" ]] && [[ "$(git rev-parse --is-inside-work-tree 2>/dev/null)" == "true" ]]; then
- local old_work_tree="$GIT_WORK_TREE"
- unset GIT_WORK_TREE
- git "$@"
- export GIT_WORK_TREE="$old_work_tree"
+check_os() {
+ if [[ "$OSTYPE" == "linux-gnu"* ]]; then
+ echo "Linux OS detected."
+ # Implement Linux-specific checks
+ elif [[ "$OSTYPE" == "darwin"* ]]; then
+ echo "MacOS detected."
+ # Implement MacOS-specific checks
+ elif [[ "$OSTYPE" == "msys" || "$OSTYPE" == "cygwin" ]]; then
+ echo "Windows-like environment detected."
+ # Implement Windows-specific checks
else
- git "$@"
+ handle_error "Unsupported operating system."
fi
}
-# Core config command
-_config() {
- git --git-dir="$DOTFILES_DIR" --work-tree="$HOME" "$@"
-}
-
-# Path mapping functions
-_repo_path() {
- local f="$1"
+#==============================================================================
- case "$f" in
- linux/*|macos/*|windows/*|common/*|profile/*|.*) echo "$f"; return ;;
- esac
-
- [[ "$f" = "$HOME"* ]] && f="${f#$HOME/}"
- echo "$CFG_OS/home/$f"
-}
+#======================================
+# Linux
+#======================================
-_sys_path() {
- local repo_path="$1"
- case "$repo_path" in
- */home/*) echo "$HOME/${repo_path#*/home/}" ;;
- *) echo "/$repo_path" ;;
- esac
-}
+# Check Distro
+#--------------------------------------
-# Enhanced config wrapper with better path handling
-config() {
- local cmd="$1"
+# Detect package type from /etc/issue
+_found_arch() {
+ local _ostype="$1"
shift
-
- case "$cmd" in
- add)
- for file_path in "$@"; do
- local repo_path
- repo_path="$(_repo_path "$file_path")"
- local full_repo_path="$DOTFILES_DIR/$repo_path"
-
- create_dir "$(dirname "$full_repo_path")"
- cp -a "$file_path" "$full_repo_path" || {
- print_error "Failed to copy $file_path"
- continue
- }
-
- _config add "$repo_path" || {
- print_error "Failed to git add $repo_path"
- continue
- }
-
- print_success "Added: $file_path → $repo_path"
- done
+ grep -qis "$*" /etc/issue && _distro="$_ostype"
+}
+
+# Detect package type
+_distro_detect() {
+ # Check if /etc/os-release exists and extract information
+ if [ -f /etc/os-release ]; then
+ source /etc/os-release
+ case "$ID" in
+ "arch")
+ _distro="PACMAN"
+ return
;;
-
- status)
- # Auto-sync modified files
- local synced_files=()
- while IFS= read -r repo_file; do
- [[ -z "$repo_file" ]] && continue
- local sys_file full_repo_path
- sys_file="$(_sys_path "$repo_file")"
- full_repo_path="$DOTFILES_DIR/$repo_file"
-
- if [[ -e "$sys_file" && -e "$full_repo_path" ]]; then
- if ! diff -q "$full_repo_path" "$sys_file" >/dev/null 2>&1; then
- cp -f "$sys_file" "$full_repo_path"
- synced_files+=("$repo_file")
- fi
- fi
- done < <(_config ls-files 2>/dev/null)
-
- if [[ ${#synced_files[@]} -gt 0 ]]; then
- print_section "Auto-synced Files"
- for repo_file in "${synced_files[@]}"; do
- print_success "Synced: $(_sys_path "$repo_file") → $repo_file"
- done
- echo
- fi
-
- _config status
+ "debian")
+ _distro="DPKG"
+ return
;;
-
- deploy)
- local deployed=()
- while IFS= read -r repo_file; do
- [[ -z "$repo_file" ]] && continue
- local sys_file full_repo_path
- sys_file="$(_sys_path "$repo_file")"
- full_repo_path="$DOTFILES_DIR/$repo_file"
-
- if [[ -e "$full_repo_path" ]]; then
- create_dir "$(dirname "$sys_file")"
- cp -a "$full_repo_path" "$sys_file" || {
- print_error "Failed to deploy $repo_file"
- continue
- }
- deployed+=("$repo_file")
- fi
- done < <(_config ls-files 2>/dev/null)
-
- if [[ ${#deployed[@]} -gt 0 ]]; then
- print_success "Deployed ${#deployed[@]} files"
- else
- print_warning "No files to deploy"
- fi
+ "ubuntu")
+ _distro="DPKG"
+ return
;;
-
- *)
- _config "$cmd" "$@"
+ "centos")
+ _distro="YUM"
+ return
;;
- esac
-}
-
-
-#======================================
-# Installation Functions
-#======================================
-
-# Install dotfiles
-install_dotfiles() {
- print_section "Installing Dotfiles"
+ "fedora")
+ _distro="YUM"
+ return
+ ;;
+ "opensuse" | "suse")
+ _distro="ZYPPER"
+ return
+ ;;
+ "gentoo")
+ _distro="PORTAGE"
+ return
+ ;;
+ esac
+ fi
- local update=false
+ # Fallback method if /etc/os-release doesn't provide the information
+ if [ -f /etc/issue ]; then
+ _found_arch PACMAN "Arch Linux" && return
+ _found_arch DPKG "Debian GNU/Linux" && return
+ _found_arch DPKG "Ubuntu" && return
+ _found_arch YUM "CentOS" && return
+ _found_arch YUM "Red Hat" && return
+ _found_arch YUM "Fedora" && return
+ _found_arch ZYPPER "SUSE" && return
+ _found_arch PORTAGE "Gentoo" && return
+ fi
- if [[ -d "$DOTFILES_DIR" ]]; then
- if prompt_user "Dotfiles repository already exists. Update it?"; then
- print_info "Updating existing dotfiles..."
- config pull origin main || {
- print_error "Failed to pull updates"
- return 1
- }
- update=true
- else
- print_skip "Skipping dotfiles update"
- return 0
+ # Check for package managers and prompt the user if none found
+ local available_package_managers=("apt" "pacman" "portage" "yum" "zypper")
+ for manager in "${available_package_managers[@]}"; do
+ if command -v "$manager" &>/dev/null; then
+ _distro="$manager"
+ return
fi
+ done
+
+ # If none of the above methods work, prompt the user to specify the package manager
+ printf "Unable to detect the package manager. Please specify the package manager (e.g., apt, pacman, portage, yum, zypper): "
+ read -r user_package_manager
+ if [ -x "$(command -v "$user_package_manager")" ]; then
+ _distro="$user_package_manager"
+ return
else
- print_info "Cloning dotfiles repository..."
- git clone --bare "$DOTFILES_URL" "$DOTFILES_DIR" || {
- print_error "Failed to clone dotfiles repository"
- return 1
- }
+ _error "Specified package manager '$user_package_manager' not found. Exiting..."
+ exit 1
fi
+}
- # Check for conflicts
- local conflicts
- conflicts=$(config checkout 2>&1 | grep -E "^\s+" | awk '{print $1}' || true)
-
- if [[ -n "$conflicts" ]]; then
- print_warning "The following files will be overwritten:"
- echo "$conflicts"
-
- if prompt_user "Continue and overwrite these files?"; then
- # Backup conflicting files
- local backup_dir="$HOME/.dotfiles-backup-$(date +%Y%m%d-%H%M%S)"
- create_dir "$backup_dir"
+#------------------------------------------------------------------------------
- while IFS= read -r file; do
- [[ -z "$file" ]] && continue
- [[ -e "$HOME/$file" ]] && cp -r "$HOME/$file" "$backup_dir/"
- done <<< "$conflicts"
+# Define directories to create
+user_dirs() {
+ directories=('.cache' '.config' '.scripts')
- print_info "Backed up conflicting files to: $backup_dir"
+ # Prompt the user if they want to use user-dirs.dirs
+ if prompt_user "Do you want to use the directories specified in user-dirs.dirs?"; then
+ # Check if ~/.config/user-dirs.dirs exists
+ config_dirs_file="$HOME/.config/user-dirs.dirs"
+ if [ -f "$config_dirs_file" ]; then
+ echo "Config file $config_dirs_file exists. Proceeding..."
else
- print_error "Installation cancelled by user"
- return 1
+ echo "Error: Config file $config_dirs_file not found. Please check your configuration."
+ exit 1
fi
- fi
- # Checkout files
- config checkout -f || {
- print_error "Failed to checkout dotfiles"
- return 1
- }
-
- # Configure repository
- config config status.showUntrackedFiles no
-
- print_success "Dotfiles installed successfully"
-}
-
-# Create user directories
-setup_user_dirs() {
- print_section "Setting Up User Directories"
-
- local directories=('.cache' '.config' '.local/bin' '.local/share' '.scripts')
-
- for dir in "${directories[@]}"; do
- create_dir "$HOME/$dir"
- done
-
- # Handle XDG user directories
- if [[ -f "$HOME/.config/user-dirs.dirs" ]]; then
- if prompt_user "Configure XDG user directories?"; then
- source "$HOME/.config/user-dirs.dirs"
+ # Prompt the user if they want to change directory names
+ if prompt_user "Do you want to change the directory names to lowercase?"; then
+ # Function to change directory names from uppercase to lowercase
+ change_dir_names() {
+ local config_file="$HOME/.config/user-dirs.dirs"
+
+ # Check if the system is not macOS
+ if [[ ! "$OSTYPE" == "darwin"* ]]; then
+ # Check if the config file exists
+ if [ -f "$config_file" ]; then
+ echo "Changing directory names from uppercase to lowercase..."
+
+ # Read the lines from the config file and process them
+ while read -r line; do
+ # Extract variable name and path from each line
+ if [[ $line =~ ^[[:space:]]*([A-Z_]+)=\"(.+)\" ]]; then
+ var_name="${BASH_REMATCH[1]}"
+ var_path="${BASH_REMATCH[2]}"
+
+ # Convert the variable name to lowercase
+ var_name_lowercase="$(echo "$var_name" | tr '[:upper:]' '[:lower:]')"
+
+ # Check if the directory exists
+ if [ -d "$var_path" ]; then
+ # Rename the directory to lowercase
+ new_var_path="$HOME/${var_name_lowercase}"
+ mv "$var_path" "$new_var_path"
+ echo "Renamed $var_path to $new_var_path"
+ fi
+ fi
+ done <"$config_file"
+
+ echo "Directory names changed successfully."
+ else
+ echo "The config file $config_file does not exist. Skipping directory name changes."
+ fi
+ else
+ echo "macOS detected. Skipping directory name changes."
+ fi
+ }
- # Create XDG directories
- for var in XDG_DESKTOP_DIR XDG_DOWNLOAD_DIR XDG_TEMPLATES_DIR XDG_PUBLICSHARE_DIR \
- XDG_DOCUMENTS_DIR XDG_MUSIC_DIR XDG_PICTURES_DIR XDG_VIDEOS_DIR; do
- local dir_path="${!var:-}"
- [[ -n "$dir_path" ]] && create_dir "$dir_path"
- done
+ # Run the function to change directory names
+ change_dir_names
+ elif prompt_user "Do you want to change the directory names to uppercase?"; then
+ # Function to change directory names from lowercase to uppercase
+ change_dir_names() {
+ local config_file="$HOME/.config/user-dirs.dirs"
+
+ # Check if the system is not macOS
+ if [[ ! "$OSTYPE" == "darwin"* ]]; then
+ # Check if the config file exists
+ if [ -f "$config_file" ]; then
+ echo "Changing directory names from lowercase to uppercase..."
+
+ # Read the lines from the config file and process them
+ while read -r line; do
+ # Extract variable name and path from each line
+ if [[ $line =~ ^[[:space:]]*([A-Z_]+)=\"(.+)\" ]]; then
+ var_name="${BASH_REMATCH[1]}"
+ var_path="${BASH_REMATCH[2]}"
+
+ # Convert the variable name to uppercase
+ var_name_uppercase="$(echo "$var_name" | tr '[:lower:]' '[:upper:]')"
+
+ # Check if the directory exists
+ if [ -d "$var_path" ]; then
+ # Rename the directory to uppercase
+ new_var_path="$HOME/${var_name_uppercase}"
+ mv "$var_path" "$new_var_path"
+ echo "Renamed $var_path to $new_var_path"
+ fi
+ fi
+ done <"$config_file"
+
+ echo "Directory names changed successfully."
+ else
+ echo "The config file $config_file does not exist. Skipping directory name changes."
+ fi
+ else
+ echo "macOS detected. Skipping directory name changes."
+ fi
+ }
- print_success "XDG user directories configured"
+ # Run the function to change directory names
+ change_dir_names
+ #xdg-user-dirs-update
fi
fi
-}
-
-install_yq() {
- local bin_dir="$HOME/.local/bin"
- local yq_url="https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64"
- local yq_path="$bin_dir/yq"
-
- print_info "Installing yq..."
- create_dir "$bin_dir"
+ # Create needed dirs and set proper permissions
+ for d in "${directories[@]}"; do
+ full_path="$HOME/$d"
+ if [ ! -d "$full_path" ]; then
+ mkdir -p "$full_path"
+ # Assuming $USER is defined or replace it with the desired user
+ chown -R "$USER" "$full_path"
+ echo "Created $full_path"
+ fi
+ done
+}
- download_file "$yq_url" "$yq_path" || return 1
+#------------------------------------------------------------------------------
- chmod +x "$yq_path" || {
- print_error "Failed to set executable permissions for yq"
- return 1
+# Update system
+linux_update_system() {
+ # Prompt the user if they want to update the system
+ prompt_user "Do you want to update the system?" Y || {
+ echo "System update skipped."
+ return
}
- # Add to PATH if not already there
- if [[ ":$PATH:" != *":$bin_dir:"* ]]; then
- export PATH="$bin_dir:$PATH"
- echo "export PATH=\"$bin_dir:\$PATH\"" >> "$HOME/.bashrc"
- fi
-
- print_success "yq installed successfully"
+ # Continue with system update based on detected package manager
+ case "$_distro" in
+ "PACMAN")
+ "$PRIVILEGE_TOOL" pacman -Syyy && "$PRIVILEGE_TOOL" pacman -Syu --noconfirm
+ ;;
+ "DPKG")
+ "$PRIVILEGE_TOOL" apt-get update && "$PRIVILEGE_TOOL" apt-get upgrade -y
+ ;;
+ "YUM")
+ "$PRIVILEGE_TOOL" yum update -y
+ ;;
+ "ZYPPER")
+ "$PRIVILEGE_TOOL" zypper --non-interactive update
+ ;;
+ "PORTAGE")
+ "$PRIVILEGE_TOOL" emerge --sync && "$PRIVILEGE_TOOL" emerge --ask --update --deep --newuse @world
+ ;;
+ *)
+ echo "Package manager not supported."
+ return 1
+ ;;
+ esac
}
-# Install packages based on OS and package manager
-install_packages() {
- print_section "Installing Packages"
+#------------------------------------------------------------------------------
+linux_install_packages() {
+ local failed_packages=()
+ local any_failures=false
local packages_file="packages.yml"
- # Check if yq is available for YAML parsing
- if ! command_exists yq; then
- if prompt_user "yq (YAML parser) is required. Install it?"; then
- install_yq || {
- print_error "Failed to install yq"
- return 1
- }
- else
- print_skip "Package installation (requires yq)"
- return 0
- fi
- fi
-
- if [[ ! -f "$packages_file" ]]; then
- print_warning "packages.yml not found, skipping package installation"
- return 0
+ # Check if yq is available
+ if ! command -v yq &>/dev/null; then
+ echo "Error: yq (YAML parser) is not installed or not found."
+ return 1
fi
- case "$CFG_OS" in
- linux)
- install_linux_packages "$packages_file"
- ;;
- macos)
- install_macos_packages "$packages_file"
- ;;
- windows)
- install_windows_packages "$packages_file"
- ;;
- *)
- print_warning "Package installation not supported for $CFG_OS"
- ;;
- esac
-}
-
-# Install Linux packages
-install_linux_packages() {
- local packages_file="$1"
- local failed_packages=()
- local installed_packages=()
-
- # Get package list
+ # Read package names from packages.yml under PackageManager for most distributions
local packages=()
- mapfile -t packages < <(yq e '.PackageManager[]' "$packages_file" 2>/dev/null)
-
- # Add distro-specific packages
- case "$DISTRO" in
- PACMAN)
- mapfile -t -O ${#packages[@]} packages < <(yq e '.linux.arch[]' "$packages_file" 2>/dev/null)
- ;;
- APT)
- mapfile -t -O ${#packages[@]} packages < <(yq e '.linux.debian[]' "$packages_file" 2>/dev/null)
- ;;
- DNF)
- mapfile -t -O ${#packages[@]} packages < <(yq e '.linux.rhel[]' "$packages_file" 2>/dev/null)
- ;;
- esac
-
- if [[ ${#packages[@]} -eq 0 ]]; then
- print_warning "No packages found in configuration"
- return 0
- fi
-
- print_info "Found ${#packages[@]} packages to install"
-
- # Update package database first
- if prompt_user "Update package database before installing?"; then
- case "$DISTRO" in
- PACMAN) $PRIVILEGE_TOOL pacman -Sy ;;
- APT) $PRIVILEGE_TOOL apt update ;;
- DNF) $PRIVILEGE_TOOL dnf check-update || true ;;
- ZYPPER) $PRIVILEGE_TOOL zypper refresh ;;
- PORTAGE) $PRIVILEGE_TOOL emerge --sync ;;
- esac
+ if [[ -f "$packages_file" ]]; then
+ while IFS= read -r package; do
+ packages+=("$package")
+ done < <(yq e '.PackageManager[]' "$packages_file" 2>/dev/null)
+ else
+ echo "Error: packages.yml not found."
+ return 1
fi
- # Install packages
- for package in "${packages[@]}"; do
- [[ -z "$package" ]] && continue
-
- print_info "Installing $package..."
+ # Read the package manager type detected by _distro_detect()
+ case "$_distro" in
+ "PACMAN")
+ # Read additional package names from arch section if present
+ if [[ -f "$packages_file" ]]; then
+ while IFS= read -r package; do
+ packages+=("$package")
+ done < <(yq e '.arch[]' "$packages_file" 2>/dev/null)
+ fi
- case "$DISTRO" in
- PACMAN)
- if pacman -Q "$package" &>/dev/null; then
- print_info "$package already installed"
- continue
- fi
- if $PRIVILEGE_TOOL pacman -S --noconfirm "$package"; then
- installed_packages+=("$package")
- else
+ # Installation using Pacman
+ for package in "${packages[@]}"; do
+ if ! pacman -Q "$package" &>/dev/null; then
+ if ! "$PRIVILEGE_TOOL" pacman -S --noconfirm "$package"; then
failed_packages+=("$package")
+ any_failures=true
fi
- ;;
- APT)
- if dpkg -l "$package" 2>/dev/null | grep -q "^ii"; then
- print_info "$package already installed"
- continue
- fi
- if $PRIVILEGE_TOOL apt install -y "$package"; then
- installed_packages+=("$package")
- else
+ fi
+ done
+ ;;
+ "DPKG")
+ # Try installing packages with dpkg
+ for package in "${packages[@]}"; do
+ if ! dpkg-query -W "$package" &>/dev/null; then
+ if ! "$PRIVILEGE_TOOL" apt-get install -y "$package"; then
failed_packages+=("$package")
+ any_failures=true
fi
- ;;
- DNF)
- if rpm -q "$package" &>/dev/null; then
- print_info "$package already installed"
- continue
+ fi
+ done
+ ;;
+ "YUM")
+ # Try installing packages with yum
+ for package in "${packages[@]}"; do
+ if ! rpm -q "$package" &>/dev/null; then
+ if ! "$PRIVILEGE_TOOL" yum install -y "$package"; then
+ failed_packages+=("$package")
+ any_failures=true
fi
- if $PRIVILEGE_TOOL dnf install -y "$package"; then
- installed_packages+=("$package")
- else
+ fi
+ done
+ ;;
+ "ZYPPER")
+ # Try installing packages with zypper
+ for package in "${packages[@]}"; do
+ if ! rpm -q "$package" &>/dev/null; then
+ if ! "$PRIVILEGE_TOOL" zypper --non-interactive install "$package"; then
failed_packages+=("$package")
+ any_failures=true
fi
- ;;
- esac
- done
+ fi
+ done
+ ;;
+ "PORTAGE")
+ # Try installing packages with emerge for Gentoo
+ if [[ -f "$packages_file" ]]; then
+ # Read package names from packages.yml under gentoo
+ gentoo_packages=()
+ while IFS= read -r package; do
+ gentoo_packages+=("$package")
+ done < <(yq e '.gentoo[]' "$packages_file" 2>/dev/null)
+ else
+ echo "Error: packages.yml not found."
+ return 1
+ fi
- # Report results
- if [[ ${#installed_packages[@]} -gt 0 ]]; then
- print_success "Successfully installed ${#installed_packages[@]} packages"
- fi
+ for package in "${gentoo_packages[@]}"; do
+ if [ "$package" != "" ]; then
+ if ! equery list "$package" &>/dev/null; then
+ if ! "$PRIVILEGE_TOOL" emerge "$package"; then
+ failed_packages+=("$package")
+ any_failures=true
+ fi
+ fi
+ fi
+ done
+ ;;
+ *)
+ echo "Package manager not supported."
+ return 1
+ ;;
+ esac
- if [[ ${#failed_packages[@]} -gt 0 ]]; then
- print_error "Failed to install ${#failed_packages[@]} packages: ${failed_packages[*]}"
+ # Check if any packages failed to install
+ if "$any_failures"; then
+ echo "Failed to install the following packages:"
+ printf '%s\n' "${failed_packages[@]}"
+ return 1
+ else
+ echo "All packages installed successfully."
+ return 0
fi
}
-# Install shell and plugins
-setup_shell() {
- print_section "Setting Up Shell Environment"
+# Install Rust using rustup and install Rust packages from packages.yml
+install_rust() {
+ if command -v "rustup" &>/dev/null; then
+ echo "Installing Rust using rustup..."
+ CARGO_HOME=${XDG_DATA_HOME:-$HOME/.local/share}/cargo RUSTUP_HOME=${XDG_DATA_HOME:-$HOME/.local/share}/rustup bash -c 'curl https://sh.rustup.rs -sSf | sh -s -- -y'
+ else
+ echo "Rust is already installed."
+ fi
- # Install Zsh if requested
- if prompt_user "Install and configure Zsh?"; then
- if ! command_exists zsh; then
- print_info "Installing Zsh..."
- case "$DISTRO" in
- PACMAN) $PRIVILEGE_TOOL pacman -S --noconfirm zsh ;;
- APT) $PRIVILEGE_TOOL apt install -y zsh ;;
- DNF) $PRIVILEGE_TOOL dnf install -y zsh ;;
- esac
- fi
+ # Read Rust-specific packages from packages.yml under the 'rust' section
+ local rust_packages=()
+ if [[ -f "$packages_file" ]]; then
+ rust_packages=("$(yq '.rust[]' "$packages_file" 2>/dev/null)")
+ #rust_packages=("$(grep 'rust:' -A 1 "$packages_file" | grep -v 'rust:' | grep -vE '^\s*$' | sed 's/^\s*-\s*//')")
+ else
+ echo "Error: packages.yml not found."
+ return 1
+ fi
- if command_exists zsh; then
- if prompt_user "Change default shell to Zsh?"; then
- local zsh_path
- zsh_path="$(which zsh)"
- if chsh -s "$zsh_path"; then
- print_success "Default shell changed to Zsh"
- print_warning "Please log out and log back in to apply changes"
- else
- print_error "Failed to change default shell"
- fi
+ # Install Rust packages using cargo if rust is installed
+ if command -v "cargo" &>/dev/null; then
+ for package in "${rust_packages[@]}"; do
+ if ! cargo install "$package"; then
+ echo "Failed to install Rust package: $package"
+ return 1
fi
-
- # Install Zsh plugins
- install_zsh_plugins
- else
- print_error "Zsh installation failed"
- fi
+ done
else
- print_skip "Zsh setup"
+ echo "Cargo not found. Rust packages installation skipped."
fi
}
-# Install Zsh plugins
-install_zsh_plugins() {
- local plugins_dir="$HOME/.config/zsh/plugins"
- local plugins=(
- "zsh-you-should-use:https://github.com/MichaelAquilina/zsh-you-should-use.git"
- "zsh-syntax-highlighting:https://github.com/zsh-users/zsh-syntax-highlighting.git"
- "zsh-autosuggestions:https://github.com/zsh-users/zsh-autosuggestions.git"
- )
-
- create_dir "$plugins_dir"
-
- for plugin_info in "${plugins[@]}"; do
- local plugin_name="${plugin_info%%:*}"
- local plugin_url="${plugin_info##*:}"
- local plugin_path="$plugins_dir/$plugin_name"
-
- if [[ -d "$plugin_path" ]]; then
- print_info "$plugin_name already installed"
- if prompt_user "Update $plugin_name?"; then
- (cd "$plugin_path" && git pull) && print_success "Updated $plugin_name"
- fi
- else
- print_info "Installing $plugin_name..."
- if git clone "$plugin_url" "$plugin_path"; then
- print_success "Installed $plugin_name"
- else
- print_error "Failed to install $plugin_name"
- fi
- fi
- done
+# Function to install Node Version Manager (NVM)
+install_nvm() {
+ # Set NVM_DIR environment variable
+ export NVM_DIR="$HOME/.config/nvm"
+ if [ ! -d "$NVM_DIR" ]; then
+ mkdir -p "$NVM_DIR"
+ fi
+ # Download and install or update NVM script
+ if command -v nvm &>/dev/null; then
+ echo "Updating Node Version Manager (NVM)..."
+ curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/master/install.sh | bash
+ else
+ echo "Installing Node Version Manager (NVM)..."
+ curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/master/install.sh | bash
+ fi
+ # Source NVM script to enable it in the current shell
+ if [ -s "$NVM_DIR/nvm.sh" ]; then
+ echo "Sourcing NVM script..."
+ . "$NVM_DIR/nvm.sh"
+ else
+ echo "NVM script not found. Make sure installation was successful."
+ return 1
+ fi
+
+ # Verify installation
+ if command -v nvm &>/dev/null; then
+ echo "NVM installation completed successfully."
+ export NVM_DIR="$HOME/.config/nvm"
+ [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
+ [ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" # This loads nvm bash_completion
+ else
+ echo "NVM installation failed."
+ return 1
+ fi
}
-# Setup SSH
-setup_ssh() {
- print_section "Setting Up SSH"
+install_node() {
+ # Check if Node.js is already installed
+ if ! command -v node &>/dev/null; then
+ echo "Node.js is already installed."
+ return
+ fi
- local ssh_dir="$HOME/.ssh"
+ echo "Installing Node.js..."
+ # Set up environment variables for Node.js installation
+ export NVM_NODEJS_ORG_MIRROR=https://npm.taobao.org/mirrors/node/
+ export NODEJS_ORG_MIRROR=https://npm.taobao.org/mirrors/node/
- if [[ ! -f "$ssh_dir/id_rsa" ]]; then
- if prompt_user "Generate SSH key pair?"; then
- create_dir "$ssh_dir" 700
+ # Install the latest stable version of Node.js using NVM
+ nvm
+ nvm install node
+ nvm use node
+ nvm install --lts
+ nvm alias default lts/* # Set LTS version as default
- local email
- print_color "$YELLOW" "Enter email for SSH key (or press Enter for $USER@$HOSTNAME): "
- read -r email
- email="${email:-$USER@$HOSTNAME}"
+ echo "Node.js installation completed successfully."
+}
- ssh-keygen -t rsa -b 4096 -f "$ssh_dir/id_rsa" -N '' -C "$email" && {
- print_success "SSH key pair generated"
- cat "$ssh_dir/id_rsa.pub" >> "$ssh_dir/authorized_keys"
- chmod 600 "$ssh_dir/authorized_keys"
- print_info "Public key added to authorized_keys"
- }
- fi
- else
- print_info "SSH key already exists"
+install_yarn() {
+ # Check if Yarn is already installed
+ if command -v yarn &>/dev/null; then
+ echo "Yarn is already installed."
+ return
fi
-}
-#======================================
-# Summary and Cleanup
-#======================================
+ # Check if the .yarn directory exists
+ if [ -d "$HOME/.yarn" ]; then
+ echo "Removing existing .yarn directory..."
+ rm -rf "$HOME/.yarn"
+ fi
+
+ echo "Installing Yarn..."
+ # Install Yarn using npm
+ curl -o- -L https://yarnpkg.com/install.sh | bash
+ echo "Yarn installation completed successfully."
+}
-# Print installation summary
-print_installation_summary() {
- print_header "Installation Summary"
+setup_tmux_plugins() {
+ local tpm_dir="$HOME/.config/tmux/plugins/tpm"
+ local plugins_dir="$HOME/.config/tmux/plugins"
- if [[ ${#INSTALL_SUMMARY[@]} -gt 0 ]]; then
- print_section "Successful Operations"
- printf '%s\n' "${INSTALL_SUMMARY[@]}"
+ # Ensure the plugins directory exists
+ if [ ! -d "$plugins_dir" ]; then
+ mkdir -p "$plugins_dir"
fi
- if [[ ${#SKIPPED_ITEMS[@]} -gt 0 ]]; then
- print_section "Skipped Items"
- printf '%s\n' "${SKIPPED_ITEMS[@]}"
+ # Ensure the TPM directory exists
+ if [ ! -d "$tpm_dir" ]; then
+ mkdir -p "$tpm_dir"
fi
- if [[ ${#FAILED_ITEMS[@]} -gt 0 ]]; then
- print_section "Failed Operations"
- printf '%s\n' "${FAILED_ITEMS[@]}"
- echo
- print_warning "Some operations failed. Check the log file: $LOG_FILE"
+ if [ "$(ls -A "$tpm_dir")" ]; then
+ # TPM is already installed and directory is not empty, so we skip installation.
+ echo "TPM has been installed...skipping"
+ else
+ # If TPM directory doesn't exist or is empty, we proceed with installation.
+ if [ -d "$tpm_dir" ]; then
+ rm -rf "$tpm_dir" # Remove existing directory if it exists
+ fi
+ echo "Installing TPM..."
+ git clone https://github.com/tmux-plugins/tpm "$tpm_dir"
fi
+}
- echo
- print_color "$GREEN$BOLD" "Installation completed!"
- print_info "Log file: $LOG_FILE"
+install_tailscale() {
+ if ! command -v tailscale &>/dev/null; then
+ curl -fsSL https://tailscale.com/install.sh | bash
+ fi
+}
- if [[ ${#FAILED_ITEMS[@]} -eq 0 ]]; then
- print_color "$GREEN" "🎉 All operations completed successfully!"
- else
- print_color "$YELLOW" "⚠️ Installation completed with ${#FAILED_ITEMS[@]} issues"
+setup_ssh() {
+ SSH_DIR="$HOME/.ssh"
+ if ! [[ -f "$SSH_DIR/authorized_keys" ]]; then
+ echo "Generating SSH keys"
+ mkdir -p "$SSH_DIR"
+ chmod 700 "$SSH_DIR"
+ ssh-keygen -b 4096 -t rsa -f "$SSH_DIR"/id_rsa -N '' -C "$USER@$HOSTNAME"
+ cat "$SSH_DIR"/id_rsa.pub >>"$SSH_DIR"/authorized_keys
fi
+}
- echo
- print_info "Next steps:"
- print_color "$CYAN" " • Restart your shell or run: exec \$SHELL"
- print_color "$CYAN" " • Review configuration files in: $DOTFILES_DIR"
- print_color "$CYAN" " • Use 'config status' to manage dotfiles"
- echo
+linux_specific_steps() {
+ install_dotfiles
+ user_dirs
+ _distro_detect
+ check_privilege_tools
+ #set_locale
+ submodules
+ change_dir_names
+ #linux_update_system
+ install_yq
+ #install_rust
+ #install_nvm
+ #install_node
+ #install_yarn
+ install_tailscale
+ linux_install_packages
+ install_zsh_plugins
+ setup_tmux_plugins
+ setup_ssh
+ change_shell
}
+#------------------------------------------------------------------------------
+
+#------------------------------------------------------------------------------
+
+#==============================================================================
+
#======================================
-# Main Installation Flow
+# MacOS
#======================================
-# Main installation function
-main() {
- # Initialize
- setup_logging
-
- print_header "Enhanced Dotfiles Installation"
- print_info "Starting installation for user: $USER"
- print_info "Log file: $LOG_FILE"
-
- # Pre-flight checks
- detect_os
- detect_privilege_tools
-
- if [[ "$CFG_OS" == "linux" ]]; then
- detect_linux_distro || exit 1
- fi
-
- # Installation steps
- local steps=(
- "install_dotfiles:Install dotfiles repository"
- "setup_user_dirs:Setup user directories"
- "install_packages:Install system packages"
- "setup_shell:Setup shell environment"
- "setup_ssh:Setup SSH configuration"
- )
-
- echo
- print_color "$YELLOW$BOLD" "The following steps will be performed:"
- for i in "${!steps[@]}"; do
- local step_desc="${steps[i]#*:}"
- print_color "$CYAN" "$((i + 1)). $step_desc"
- done
+macos_specific_steps() {
+ set_locale
+ macos_install_packages
+ git_install_macos
- echo
- if ! prompt_user "Continue with installation?"; then
- print_info "Installation cancelled by user"
- exit 0
- fi
+}
- # Execute installation steps
- for step_info in "${steps[@]}"; do
- local step_func="${step_info%%:*}"
- local step_desc="${step_info#*:}"
+#==============================================================================
- echo
- print_section "$step_desc"
+#======================================
+# Windows
+#======================================
- if "$step_func"; then
- print_success "$step_desc completed"
- else
- print_error "$step_desc failed"
- fi
- done
+windows_specific_steps() {
+ check_git_installed_windows
+ install_dependencies_windows
+ windows_install_packages
+ git_install_windows
+ symlink_configuration_files_windows
+}
+#------------------------------------------------------------------------------
+
+#==============================================================================
+
+#======================================
+# Main Installation
+#======================================
- # Show summary
- print_installation_summary
+# Main Installation
+main_installation() {
+ echo "Starting main installation..."
+
+ case "$OSTYPE" in
+ linux-gnu*)
+ linux_specific_steps
+ ;;
+ darwin*)
+ macos_specific_steps
+ ;;
+ msys* | cygwin*)
+ windows_specific_steps
+ ;;
+ *)
+ handle_error "Unsupported operating system."
+ ;;
+ esac
- log_message "INFO" "Installation process completed"
+ sleep 1
+}
+
+# Script entry point
+main() {
+ echo "Log File for Dotfiles Installation" >"$LOG_FILE"
+ check_download_dependencies
+ check_os
+ main_installation
+ handle_complete "Installation completed successfully."
}
+main "$@"