0% found this document useful (0 votes)
53 views16 pages

Rice Installer

This document is a Bash script for installing custom dotfiles and necessary dependencies for a user environment. It includes error handling, checks for root user and internet connection, and manages repositories for package installations. The script provides a welcome message and outlines the installation process, ensuring that the user's system configurations remain unmodified.

Uploaded by

Adrian Eka
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
53 views16 pages

Rice Installer

This document is a Bash script for installing custom dotfiles and necessary dependencies for a user environment. It includes error handling, checks for root user and internet connection, and manages repositories for package installations. The script provides a welcome message and outlines the installation process, ensuring that the user's system configurations remain unmodified.

Uploaded by

Adrian Eka
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd

#!

/usr/bin/env bash
# ██████╗ ██╗ ██████╗███████╗ ██╗███╗ ██╗███████╗████████╗ █████╗ ██╗ ██╗
███████╗██████╗
# ██╔══██╗██║██╔════╝██╔════╝ ██║████╗ ██║██╔════╝╚══██╔══╝██╔══██╗██║ ██║
██╔════╝██╔══██╗
# ██████╔╝██║██║ █████╗ ██║██╔██╗ ██║███████╗ ██║ ███████║██║ ██║
█████╗ ██████╔╝
# ██╔══██╗██║██║ ██╔══╝ ██║██║╚██╗██║╚════██║ ██║ ██╔══██║██║ ██║
██╔══╝ ██╔══██╗
# ██║ ██║██║╚██████╗███████╗ ██║██║ ╚████║███████║ ██║ ██║
██║███████╗███████╗███████╗██║ ██║
# ╚═╝ ╚═╝╚═╝ ╚═════╝╚══════╝ ╚═╝╚═╝ ╚═══╝╚══════╝ ╚═╝ ╚═╝
╚═╝╚══════╝╚══════╝╚══════╝╚═╝ ╚═╝
#
# Author - gh0stzk
# Repo - [Link]
# Last updated - 24.03.2025 [Link]
#
# RiceInstaller - Script to install my dotfiles
#
# Copyright (C) 2021-2025 gh0stzk <[Link]@[Link]>
# Licensed under GPL-3.0 license

# Colors
CRE=$(tput setaf 1) # Red
CYE=$(tput setaf 3) # Yellow
CGR=$(tput setaf 2) # Green
CBL=$(tput setaf 4) # Blue
BLD=$(tput bold) # Bold
CNC=$(tput sgr0) # Reset colors

# Global vars
backup_folder=~/.RiceBackup
ERROR_LOG="$HOME/[Link]"

# Logo
logo() {
local text="${1:?}"
echo -en "
%%%
%%%%%//%%%%%
%%************%%%
(%%//############*****%%
%%%%**###&&&&&&&&&###**//
%%(**##&&&#########&&&##**
%%(**##*****#####*****##**%%%
%%(**## ***** ##**
//## @@** @@ ##//
## **### ##
####### #####//
###**&&&&&**###
&&& &&&
&&&//// &&
&&//@@@**
..***

${BLD}${CRE}[ ${CYE}${text} ${CRE}]${CNC}\n\n"


}
# Handle errors
log_error() {
local error_msg="$1"
local timestamp=$(date +"%Y-%m-%d %H:%M:%S")

# Escribir en el log con timestamp


echo "[${timestamp}] ERROR: ${error_msg}" >> "$ERROR_LOG"

# Mostrar error en colores


printf "%s%sERROR:%s %s\n" "${CRE}" "${BLD}" "${CNC}" "${error_msg}" >&2
}

# Verificaciones iniciales
initial_checks() {
# Verificar usuario root
if [ "$(id -u)" = 0 ]; then
log_error "This script MUST NOT be run as root user."
exit 1
fi

# Verificar directorio HOME


if [ "$PWD" != "$HOME" ]; then
log_error "The script must be executed from HOME directory."
exit 1
fi

# Verificar conexión a internet


if ! ping -q -c 1 -W 1 [Link] &>/dev/null; then
log_error "No internet connection detected."
exit 1
fi
}

# Internal verification function


is_installed() {
pacman -Qq "$1" >/dev/null 2>&1
}

welcome() {
clear
logo "Welcome $USER"
echo -en "${BLD}${CGR}This script will install my dotfiles and this is what
it will do:${CNC}

${BLD}${CGR}[${CYE}i${CGR}]${CNC} 2 repositories will be installed. $


{CBL}gh0stzk-dotfiles${CNC} and ${CBL}Chaotic-Aur${CNC}
${BLD}${CGR}[${CYE}i${CGR}]${CNC} Check necessary dependencies and install them
${BLD}${CGR}[${CYE}i${CGR}]${CNC} Download my dotfiles in ${HOME}/dotfiles
${BLD}${CGR}[${CYE}i${CGR}]${CNC} Backup of possible existing configurations
(bspwm, polybar, etc...)
${BLD}${CGR}[${CYE}i${CGR}]${CNC} Install my configuration
${BLD}${CGR}[${CYE}i${CGR}]${CNC} Enabling MPD service (Music player daemon)
${BLD}${CGR}[${CYE}i${CGR}]${CNC} Change your shell to zsh shell

${BLD}${CGR}[${CRE}!${CGR}]${CNC} ${BLD}${CRE}My dotfiles DO NOT modify any of your


system configurations${CNC}
${BLD}${CGR}[${CRE}!${CGR}]${CNC} ${BLD}${CRE}This script does NOT have the
potential power to break your system${CNC}
"
local yn
while true; do
read -rp " ${BLD}${CGR}Do you wish to continue?${CNC} [y/N]: " yn
case "${yn,,}" in
y|yes)
return 0
;;
n|no|"")
echo -e "\n${BLD}${CYE}Operation cancelled${CNC}"
exit 0
;;
*)
echo -e "\n${BLD}${CRE}Error:${CNC} Just write '${BLD}${CYE}y$
{CNC}' or '${BLD}${CYE}n${CNC}'\n"
;;
esac
done
}

add_gh0stzk_repo() {
clear
logo "Add gh0stzk custom repo"
local repo_name="gh0stzk-dotfiles"
sleep 2

# Check if the repository already exists


echo -e "${BLD}${CYE}Installing ${CBL}${repo_name} ${CYE}repository...${CNC}"
if ! grep -q "\[${repo_name}\]" /etc/[Link]; then
if echo -e "\n[${repo_name}]\nSigLevel = Optional TrustAll\nServer =
[Link] | \
sudo tee -a /etc/[Link] >/dev/null 2>> "$ERROR_LOG"
then
echo -e "\n${BLD}${CYE}${repo_name} ${CGR}repository added
succesfully!${CNC}"

# Update databases
if ! sudo pacman -Syy >> "$ERROR_LOG" 2>&1; then
log_error "Database update failed"
return 1
fi
else
log_error "Error adding repository - check permissions"
return 1
fi
else
echo -e "\n${BLD}${CYE}The repository already exists and is configured$
{CNC}"
sleep 3
return 0
fi
}

add_chaotic_repo() {
clear
logo "Add chaotic-aur repository"
local repo_name="chaotic-aur"
local key_id="3056513887B78AEB"
sleep 2

# Check if repository already exists


echo -e "${BLD}${CYE}Configuring ${CBL}${repo_name} ${CYE}repository...${CNC}"
if grep -q "\[${repo_name}\]" /etc/[Link]; then
echo -e "\n${BLD}${CYE}Repository already exists in [Link]${CNC}"
sleep 3
return 0
fi

# Key management
if ! pacman-key -l | grep -q "$key_id"; then
echo -e "${BLD}${CYE}Adding GPG key...${CNC}"
if ! sudo pacman-key --recv-key "$key_id" --keyserver [Link]
>> "$ERROR_LOG" 2>&1; then
log_error "Failed to receive GPG key"
return 1
fi

echo -e "${BLD}${CYE}Signing key locally...${CNC}"


if ! sudo pacman-key --lsign-key "$key_id" >> "$ERROR_LOG" 2>&1; then
log_error "Failed to sign GPG key"
return 1
fi
else
echo -e "${BLD}${CYE}GPG key already exists in keyring${CNC}"
fi

# Install required packages if missing


local chaotic_pkgs=("chaotic-keyring" "chaotic-mirrorlist")
for pkg in "${chaotic_pkgs[@]}"; do
if ! pacman -Qq "$pkg" >/dev/null 2>&1; then
echo -e "${BLD}${CYE}Installing ${CBL}${pkg}${CNC}"
if ! sudo pacman -U --noconfirm "[Link]
aur/${pkg}.[Link]" >> "$ERROR_LOG" 2>&1; then
log_error "Failed to install ${pkg}"
return 1
fi
else
echo -e "${BLD}${CYE}${pkg} is already installed${CNC}"
fi
done

# Add repository configuration


echo -e "${BLD}${CYE}Adding repository to [Link]...${CNC}"
if ! echo -e "\n[${repo_name}]\nInclude = /etc/pacman.d/chaotic-mirrorlist" | \
sudo tee -a /etc/[Link] >/dev/null 2>> "$ERROR_LOG"; then
log_error "Failed to add repository configuration"
return 1
fi

# Update package databases


echo -e "${BLD}${CYE}Updating package databases...${CNC}"
if ! sudo pacman -Syy >> "$ERROR_LOG" 2>&1; then
log_error "Failed to update package databases"
return 1
fi

echo -e "\n${BLD}${CGR}${repo_name} repository configured successfully!${CNC}"


sleep 3
}

install_dependencies() {
clear
logo "Installing needed packages from official repositories..."
sleep 2

# List of dependencies
local dependencies=(
alacritty base-devel bat brightnessctl bspwm clipcat dunst eza feh fzf
thunar
tumbler gvfs-mtp firefox geany git imagemagick jq jgmenu kitty libwebp maim
mpc mpd mpv neovim ncmpcpp npm pamixer pacman-contrib papirus-icon-theme
picom playerctl polybar polkit-gnome python-gobject redshift rofi rustup
sxhkd tmux xclip xdg-user-dirs xdo xdotool xsettingsd xorg-xdpyinfo
xorg-xkill xorg-xprop xorg-xrandr xorg-xsetroot xorg-xwininfo yazi zsh
zsh-autosuggestions zsh-history-substring-search zsh-syntax-highlighting
ttf-inconsolata ttf-jetbrains-mono ttf-jetbrains-mono-nerd ttf-terminus-
nerd
ttf-ubuntu-mono-nerd webp-pixbuf-loader
)

echo -e "\n${BLD}${CBL}Checking for required packages...${CNC}\n"


sleep 2

# Detect missing packages


local missing_pkgs=()
for pkg in "${dependencies[@]}"; do
if ! is_installed "$pkg"; then
missing_pkgs+=("$pkg")
echo -e " ${BLD}${CYE}${pkg} ${CRE}not installed${CNC}"
else
echo -e "${BLD}${CGR}${pkg} ${CBL}already installed${CNC}"
fi
done

# Batch installation
if ((${#missing_pkgs[@]} > 0)); then
echo -e "\n${BLD}${CYE}Installing ${#missing_pkgs[@]} packages...${CNC}\n"

if sudo pacman -S --noconfirm --needed "${missing_pkgs[@]}" >> "$ERROR_LOG"


2>&1; then
# Verify complete installation
local failed_pkgs=()
for pkg in "${missing_pkgs[@]}"; do
if ! is_installed "$pkg"; then
failed_pkgs+=("$pkg")
log_error "Failed to install: $pkg"
fi
done

# Show final results


if ((${#failed_pkgs[@]} == 0)); then
echo -e "${BLD}${CGR}All packages installed successfully!${CNC}\n\
n"
else
echo -e "${BLD}${CRE}Failed to install ${#failed_pkgs[@]} packages:
${CNC}\n"
echo -e " ${BLD}${CYE}${failed_pkgs[*]}${CNC}\n\n"
fi
else
log_error "Critical error during batch installation"
echo -e "${BLD}${CRE}Installation failed! Check log for details${CNC}\
n"
return 1
fi
else
echo -e "\n${BLD}${CGR}All dependencies are already installed!${CNC}"
fi

sleep 3
}

install_gh0stzk_dependencies() {
clear
logo "Installing needed packages from gh0stzk repository..."
sleep 2

# List of dependencies
local gh0stzk_dependencies=(
gh0stzk-gtk-themes gh0stzk-cursor-qogirr gh0stzk-icons-beautyline
gh0stzk-icons-candy gh0stzk-icons-catppuccin-mocha gh0stzk-icons-dracula
gh0stzk-icons-glassy gh0stzk-icons-gruvbox-plus-dark gh0stzk-icons-hack
gh0stzk-icons-luv gh0stzk-icons-sweet-rainbow gh0stzk-icons-tokyo-night
gh0stzk-icons-vimix-white gh0stzk-icons-zafiro gh0stzk-icons-zafiro-purple
)

echo -e "\n${BLD}${CBL}Checking for required packages...${CNC}\n"


sleep 2

# Detect missing packages


local missing_gh0stzk_pkgs=()
for pkg in "${gh0stzk_dependencies[@]}"; do
if ! is_installed "$pkg"; then
missing_gh0stzk_pkgs+=("$pkg")
echo -e " ${BLD}${CYE}${pkg} ${CRE}not installed${CNC}"
else
echo -e "${BLD}${CGR}${pkg} ${CBL}already installed${CNC}"
fi
done

# Batch installation
if ((${#missing_gh0stzk_pkgs[@]} > 0)); then
echo -e "\n${BLD}${CYE}Installing ${#missing_gh0stzk_pkgs[@]} packages...$
{CNC}\n"

if sudo pacman -S --noconfirm --needed "${missing_gh0stzk_pkgs[@]}" >>


"$ERROR_LOG" 2>&1; then
# Verify complete installation
local failed_gh0stzk_pkgs=()
for pkg in "${missing_gh0stzk_pkgs[@]}"; do
if ! is_installed "$pkg"; then
failed_gh0stzk_pkgs+=("$pkg")
log_error "Failed to install: $pkg"
fi
done
# Show final results
if ((${#failed_gh0stzk_pkgs[@]} == 0)); then
echo -e "${BLD}${CGR}All packages installed successfully!${CNC}\n\
n"
else
echo -e "${BLD}${CRE}Failed to install ${#failed_gh0stzk_pkgs[@]}
packages:${CNC}\n"
echo -e " ${BLD}${CYE}${failed_gh0stzk_pkgs[*]}${CNC}\n\n"
fi
else
log_error "Critical error during batch installation"
echo -e "${BLD}${CRE}Installation failed! Check log for details${CNC}\
n"
return 1
fi
else
echo -e "\n${BLD}${CGR}All dependencies are already installed!${CNC}"
fi

sleep 3
}

install_chaotic_dependencies() {
clear
logo "Installing needed packages from chaotic repository..."
sleep 2

# List of dependencies
local chaotic_dependencies=(
paru eww-git i3lock-color simple-mtpfs fzf-tab-git
)

echo -e "\n${BLD}${CBL}Checking for required packages...${CNC}\n"


sleep 2

# Detect missing packages


local missing_chaotic_pkgs=()
for pkg in "${chaotic_dependencies[@]}"; do
if ! is_installed "$pkg"; then
missing_chaotic_pkgs+=("$pkg")
echo -e " ${BLD}${CYE}${pkg} ${CRE}not installed${CNC}"
else
echo -e "${BLD}${CGR}${pkg} ${CBL}already installed${CNC}"
fi
done

# Batch installation
if ((${#missing_chaotic_pkgs[@]} > 0)); then
echo -e "\n${BLD}${CYE}Installing ${#missing_chaotic_pkgs[@]} packages...$
{CNC}\n"

if sudo pacman -S --noconfirm --needed "${missing_chaotic_pkgs[@]}" >>


"$ERROR_LOG" 2>&1; then
# Verify complete installation
local failed_chaotic_pkgs=()
for pkg in "${missing_chaotic_pkgs[@]}"; do
if ! is_installed "$pkg"; then
failed_chaotic_pkgs+=("$pkg")
log_error "Failed to install: $pkg"
fi
done

# Show final results


if ((${#failed_chaotic_pkgs[@]} == 0)); then
echo -e "${BLD}${CGR}All packages installed successfully!${CNC}\n\
n"
else
echo -e "${BLD}${CRE}Failed to install ${#failed_chaotic_pkgs[@]}
packages:${CNC}\n"
echo -e " ${BLD}${CYE}${failed_chaotic_pkgs[*]}${CNC}\n\n"
fi
else
log_error "Critical error during batch installation"
echo -e "${BLD}${CRE}Installation failed! Check log for details${CNC}\
n"
return 1
fi
else
echo -e "\n${BLD}${CGR}All dependencies are already installed!${CNC}"
fi

sleep 3
}

install_aur_dependencies() {
clear
logo "Installing AUR dependencies..."
sleep 2

# AUR Package List


local aur_apps=(xqp xwinwrap-0.9-bin)

echo -e "${BLD}${CBL}Checking for required AUR packages...${CNC}\n"


sleep 2

# Detect missing AUR packages


local missing_aur=()
for pkg in "${aur_apps[@]}"; do
if ! is_installed "$pkg"; then
missing_aur+=("$pkg")
echo -en " ${BLD}${CYE}${pkg} ${CRE}not installed${CNC}\n"
else
echo -en "${BLD}${CGR}${pkg} ${CBL}already installed${CNC}\n"
fi
done

# Batch AUR installation


if ((${#missing_aur[@]} > 0)); then
echo -en "\n\n${BLD}${CYE}Installing ${#missing_aur[@]} AUR packages...$
{CNC}\n"

local aur_failed=()
for pkg in "${missing_aur[@]}"; do
echo -en "${BLD}${CBL}Processing: ${pkg}${CNC}\n"

if paru -S --skipreview --noconfirm "$pkg" >> "$ERROR_LOG" 2>&1; then


echo -en " ${BLD}${CGR}Successfully installed!${CNC}\n"
else
log_error "AUR package installation failed: $pkg"
aur_failed+=("$pkg")
echo -en " ${BLD}${CRE}Installation failed!${CNC}\n"
fi
sleep 0.5
done

# Show final summary


if ((${#aur_failed[@]} > 0)); then
echo -en "\n${BLD}${CRE}Failed ${#aur_failed[@]}/${#missing_aur[@]} AUR
packages:${CNC}\n"
echo -en "${BLD}${CYE}${aur_failed[*]}${CNC}\n\n"
else
echo -en "\n${BLD}${CGR}All AUR packages installed successfully!${CNC}\
n\n"
fi
else
echo -en "\n${BLD}${CGR}All AUR dependencies are already installed!${CNC}\
n\n"
fi

sleep 3
}

clone_dotfiles() {
clear
logo "Downloading dotfiles"
local repo_url="[Link]
local repo_dir="$HOME/dotfiles"
local timestamp=$(date +%Y%m%d-%H%M%S)
sleep 3

# Handle existing repository


if [[ -d "$repo_dir" ]]; then
local backup_dir="${repo_dir}_${timestamp}"
echo -en "${BLD}${CYE}Existing repository found - renaming to: ${CBL}$
{backup_dir}${CNC}\n"

if ! mv -v "$repo_dir" "$backup_dir" >> "$ERROR_LOG" 2>&1; then


log_error "Failed to rename existing repository"
echo -en "${BLD}${CRE}Renaming failed! Check${CYE}[Link]${CNC}\
n"
return 1
fi
echo -en "${BLD}${CGR}Repository successfully renamed for backup${CNC}\n\n"
fi

# Clone new repository


echo -en "${BLD}${CYE}Cloning dotfiles from: ${CBL}${repo_url}${CNC}\n"
if git clone --depth=1 "$repo_url" "$repo_dir" >> "$ERROR_LOG" 2>&1; then
echo -en "${BLD}${CGR}Dotfiles cloned successfully!${CNC}\n\n"
else
log_error "Repository clone failed"
echo -en "${BLD}${CRE}Clone failed! Check ${CYE}[Link]${CNC}\n"
return 1
fi

sleep 3
}
backup_existing_config() {
clear
logo "Backup files"
local date=$(date +%Y%m%d-%H%M%S)
sleep 2

# User questions
declare -g try_nvim try_firefox
while true; do
read -rp "${BLD}${CYE}Do you want to use my Neovim setup?${CNC} [y/N]: "
try_nvim
case "${try_nvim,,}" in
y|n) break ;;
*) echo " ${BLD}${CRE}Error:${CNC} write 'y' or 'n'" ;;
esac
done

while true; do
read -rp "${BLD}${CYE}Do you want to use my Firefox theme?${CNC} [y/N]: "
try_firefox
case "${try_firefox,,}" in
y|n) break ;;
*) echo " ${BLD}${CRE}Error:${CNC} write 'y' or 'n'" ;;
esac
done

# Create backup directory


mkdir -p "$backup_folder" 2>> "$ERROR_LOG"
echo -en "\n${BLD}${CYE}Backup directory: ${CBL}${backup_folder}${CNC}\n\n"
sleep 2

# Generic backup function


backup_item() {
local type=$1 path=$2 target=$3
local base_name=$(basename "$path")

if [ -$type "$path" ]; then


if mv "$path" "$backup_folder/${target}_${date}" 2>> "$ERROR_LOG"; then
echo -en "${BLD}${CGR}${base_name} ${CBL}backup successful${CNC}\n"
else
log_error "Error backup: $base_name"
echo -en "${BLD}${CRE}${base_name} ${CYE}backup failed${CNC}\n"
fi
sleep 0.5
else
echo -en "${BLD}${CYE}${base_name} ${CBL}not found${CNC}\n"
sleep 0.3
fi
}

# Backup of main configurations


local config_folders=(bspwm alacritty clipcat picom rofi eww sxhkd dunst kitty
polybar geany gtk-3.0 ncmpcpp yazi tmux zsh mpd paru)
for folder in "${config_folders[@]}"; do
backup_item d "$HOME/.config/$folder" "$folder"
done

# Neovim Conditional Backup


if [[ "${try_nvim,,}" == "y" ]]; then
backup_item d "$HOME/.config/nvim" "nvim"
fi

# Firefox management
if [[ "${try_firefox,,}" == "y" ]]; then
if [ ! -d "$HOME/.mozilla" ]; then
echo -en "${BLD}${CYE}Creating Firefox profile...${CNC}\n"
timeout 1s firefox --headless --display=0 >/dev/null 2>&1
sleep 1
fi

# Backup of Firefox components


local firefox_profile=$(find "$HOME/.mozilla/firefox" -maxdepth 1 -type d -
name '*.default-release' 2>/dev/null | head -1)

if [ -n "$firefox_profile" ]; then
backup_item d "${firefox_profile}/chrome" "chrome"
backup_item f "${firefox_profile}/[Link]" "[Link]"
fi
fi

# Backup of individual files


local single_files=("$HOME/.zshrc" "$HOME/.gtkrc-2.0" "$HOME/.icons")
for item in "${single_files[@]}"; do
if [[ "$item" == *".icons" ]]; then
backup_item d "$item" ".icons"
else
backup_item f "$item" "$(basename "$item")"
fi
done

echo -en "\n${BLD}${CGR}Backup completed!${CNC}\n\n"


sleep 3
}

install_dotfiles() {
clear
logo "Installing dotfiles.."
echo -en "${BLD}${CBL} Copying files to respective directories...${CNC}\n\n"
sleep 2

# Create required directories


local required_dirs=("$HOME/.config" "$HOME/.local/bin" "$HOME/.local/share")
for dir in "${required_dirs[@]}"; do
if [ ! -d "$dir" ]; then
mkdir -p "$dir" 2>> "$ERROR_LOG" && \
echo -en "${BLD}${CGR}Created directory: ${CBL}${dir}${CNC}\n"
fi
done

# Generic function to copy files


copy_files() {
local source="$1"
local target="$2"
local item_name=$(basename "$source")

if cp -R "$source" "$target" 2>> "$ERROR_LOG"; then


echo -en "${BLD}${CYE}${item_name} ${CGR}copied successfully!${CNC}\n"
return 0
else
log_error "Failed to copy: $item_name"
echo -en "${BLD}${CYE}${item_name} ${CRE}copy failed!${CNC}\n"
return 1
fi
}

# Copy main settings


local config_source="$HOME/dotfiles/config"
for config_dir in "$config_source"/*; do
local dir_name=$(basename "$config_dir")

# Skip neovim if the user doesn't want it


[[ "$dir_name" == "nvim" && "$try_nvim" != "y" ]] && continue

copy_files "$config_dir" "$HOME/.config/"


sleep 0.3
done

# Copy miscellaneous components


local misc_items=("applications" "asciiart" "fonts" "startup-page" "bin")
for item in "${misc_items[@]}"; do
local source_path="$HOME/dotfiles/misc/$item"
local target_path="$HOME/.local/share/"

[[ "$item" == "bin" ]] && target_path="$HOME/.local/"

copy_files "$source_path" "$target_path"


sleep 0.3
done

# Handle Firefox theme


if [[ "$try_firefox" == "y" ]]; then
local firefox_profile=$(find "$HOME/.mozilla/firefox" -maxdepth 1 -type d -name
'*.default-release' 2>/dev/null | head -n1)

if [ -n "$firefox_profile" ]; then
# Create necessary directories
mkdir -p "$firefox_profile/chrome" 2>> "$ERROR_LOG"

# Copy content from firefox/


for item in "$HOME/dotfiles/misc/firefox/"*; do
if [ -e "$item" ]; then
local item_name=$(basename "$item")
local target="$firefox_profile"

if [[ "$item_name" == "chrome" ]]; then


for chrome_item in "$item"/*; do
copy_files "$chrome_item" "$firefox_profile/chrome/"
done
else
copy_files "$item" "$target/"
fi
fi
done

# Update settings
local user_js="$firefox_profile/[Link]"
local startup_cfg="$HOME/.local/share/startup-page/[Link]"

if [ -f "$user_js" ]; then
sed -i "s|/home/z0mbi3|/home/$USER|g" "$user_js" 2>>
"$ERROR_LOG" && \
echo -en "${BLD}${CGR}Firefox config updated!${CNC}\n"
fi

if [ -f "$startup_cfg" ]; then
sed -i "s/name: 'gh0stzk'/name: '$USER'/" "$startup_cfg"
2>> "$ERROR_LOG" && \
echo -en "${BLD}${CGR}Startup page updated!${CNC}\n"
fi
else
log_error "Firefox profile not found"
echo -en "${BLD}${CRE}Firefox profile not found!${CNC}\n"
fi
fi

# Copy remaining files


local home_files=("$HOME/dotfiles/home/.zshrc" "$HOME/dotfiles/home/.gtkrc-2.0"
"$HOME/dotfiles/home/.icons")
for file in "${home_files[@]}"; do
copy_files "$file" "$HOME/"
done

# Update font cache


if fc-cache -rv >/dev/null 2>&1; then
echo -en "\n${BLD}${CGR}Font cache updated successfully!${CNC}\n"
else
log_error "Failed to update font cache"
fi

# Generate xdg dirs


if [[ ! -e "$HOME/.config/[Link]" ]]; then
if xdg-user-dirs-update >/dev/null 2>&1; then
echo -en "${BLD}${CGR}Xdg dirs generated successfully!${CNC}\n"
else
log_error "Failed to generate xdg dirs"
fi
fi

# Copying [Link]
if [[ ! -d /etc/pacman.d/hooks ]]; then
sudo mkdir -p /etc/pacman.d/hooks
fi

if sudo cp "$HOME/dotfiles/misc/[Link]" /etc/pacman.d/hooks; then


echo -en "${BLD}${CGR}Pacman hook copied successfully!${CNC}\n"
else
log_error "Failed to copy pacman hook :("
fi

echo -en "\n${BLD}${CGR}Dotfiles installed successfully!${CNC}\n"


sleep 3
}

configure_services() {
clear
logo "Configuring Services"
local picom_config="$HOME/.config/bspwm/src/config/[Link]"
sleep 2

# MPD Service Management


if systemctl is-enabled --quiet [Link]; then
printf "%s%sDisabling global MPD service...%s\n" "${BLD}" "${CYE}" "${CNC}"
if sudo systemctl disable --now [Link] >> "$ERROR_LOG" 2>&1; then
echo -en "${BLD}${CGR}Global MPD service disabled successfully${CNC}"
else
log_error "Failed to disable global MPD service"
echo -en "${BLD}${CRE}Failed to disable global MPD service${CNC}\n\n"
fi
fi

# User-level MPD Service


echo -en "${BLD}${CYE}Enabling user MPD service...${CNC}\n"
if systemctl --user enable --now [Link] >> "$ERROR_LOG" 2>&1; then
echo -en "${BLD}${CGR}User MPD service activated successfully${CNC}\n\n"
else
log_error "Failed to enable user MPD service"
echo -en "${BLD}${CRE}Failed to activate user MPD service${CNC}\n\n"
fi

# User-level ArchUpdates
echo -en "${BLD}${CYE}Enabling user ArchUpdates service...${CNC}\n"
if systemctl --user enable --now [Link] >> "$ERROR_LOG" 2>&1; then
echo -en "${BLD}${CGR}User ArchUpdates service activated successfully$
{CNC}\n\n"
else
log_error "Failed to enable user ArchUpdates service"
echo -en "${BLD}${CRE}Failed to activate user ArchUpdates service${CNC}\n\
n"
fi

# Virtual Machine Detection


is_virtual_machine() {
systemd-detect-virt --quiet && return 0 || return 1
}

# Picom Configuration for VMs


if is_virtual_machine; then
echo -en "${BLD}${CYE}Virtual machine detected${CNC}\n"
echo -en "${BLD}${CYE}Adjusting Picom configuration...${CNC}\n"

if [ -f "$picom_config" ]; then
if sed -i 's/backend = "glx"/backend = "xrender"/' "$picom_config" >>
"$ERROR_LOG" 2>&1; then
echo -en "${BLD}{CGR}Picom backend changed to xrender${CNC}\n\n"
else
log_error "Failed to modify Picom configuration"
echo -en "${BLD}${CRE}Failed to adjust Picom settings${CNC}\n\n"
fi
else
log_error "Picom configuration file not found"
echo -en "${BLD}${CRE}Picom config file missing: ${CYE}${picom_config}$
{CNC}\n\n"
fi
if [ -f "$picom_config" ]; then
if sed -i 's/vsync = true/vsync = false/' "$picom_config" >>
"$ERROR_LOG" 2>&1; then
echo -en "${BLD}{CGR}Picom vSync disabled${CNC}\n\n"
else
log_error "Failed to modify Picom configuration"
echo -en "${BLD}${CRE}Failed to adjust Picom settings${CNC}\n\n"
fi
else
log_error "Picom configuration file not found"
echo -en "${BLD}${CRE}Picom config file missing: ${CYE}${picom_config}$
{CNC}\n\n"
fi
fi

sleep 3
}

change_default_shell() {
clear
logo "Changing default shell to zsh"
local zsh_path=$(which zsh)
sleep 3

if [[ -z "$zsh_path" ]]; then


log_error "Zsh binary not found"
echo -en "${BLD}${CRE}Zsh is not installed! Cannot change shell${CNC}\
n\n"
return 1
fi

if [[ "$SHELL" != "$zsh_path" ]]; then


echo -en "${BLD}${CYE}Changing your shell to Zsh...${CNC}\n"

if chsh -s "$zsh_path" 2> >(tee -a "$ERROR_LOG"); then


echo -en "\n${BLD}${CGR}Shell changed successfully!${CNC}\n"
else
log_error "Failed to change shell to Zsh"
echo -en "\n${BLD}${CRE}Error changing shell! ${CYE}Check
[Link]${CNC}\n\n"
fi
else
echo -en "${BLD}${CGR}Zsh is already your default shell!${CNC}\n\n"
fi

sleep 3
}

final_prompt() {
clear
logo "Installation Complete"
sleep 2

echo -en "${BLD}${CGR}Installation completed successfully!${CNC}\n"


echo -en "${BLD}${CRE}You ${CBL}MUST ${CRE}restart your system to apply
changes${CNC}\n\n"

while true; do
read -rp " ${BLD}${CYE}Reboot now?${CNC} [y/N]: " yn
case "${yn,,}" in
y|yes)
echo -en "\n${BLD}${CGR}Initiating reboot...${CNC}\n"
sleep 2
if ! sudo reboot >> "$ERROR_LOG" 2>&1; then
log_error "Failed to trigger reboot"
echo -en "${BLD}${CRE}Reboot failed! Execute manually${CNC}\n"
fi
exit 0
;;
n|no|"")
echo -en "\n${BLD}${CYE}You really need to reboot bro!!${CNC}\n\n"
exit 0
;;
*)
echo -en "\n${BLD}${CRE}Invalid choice - use '${CYE}y${CRE}' or '$
{CYE}n${CRE}'${CNC}\n\n"
sleep 1
;;
esac
done
}

# --- Main run --- #


initial_checks
welcome
add_gh0stzk_repo
add_chaotic_repo

install_dependencies
install_gh0stzk_dependencies
install_chaotic_dependencies
install_aur_dependencies
clone_dotfiles

backup_existing_config
install_dotfiles
configure_services
change_default_shell
final_prompt

You might also like