#!/usr/bin/env bash set -o errexit set -o pipefail set -o nounset __dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" backup_dir="$HOME/.local/backups/dotfiles" # Colors for output. So fancy. COLOR_SUCCESS='\033[0;32m' COLOR_ERROR='\033[0;31m' COLOR_NOTIFY='\033[1;33m' NC='\033[0m' # No Color # Default settings for this script: # - Do not create backups automatically. # - Install everything. auto_backup=false config_selection="all" # Dotfile locations. Note that these locations should be identical between the # home directory and the dotfile directory. zshrc=".zshrc" zshrc_name="zshrc" zshrc_source="${__dir}/${zshrc}" zshrc_target="${HOME}/${zshrc}" zshrc_backup="${backup_dir}/${zshrc_name}" profile=".profile" profile_name="profile" profile_source="${__dir}/${profile}" profile_target="${HOME}/${profile}" profile_backup="${backup_dir}/${profile_name}" i3=".config/i3/config" i3_name="i3" i3_source="${__dir}/${i3}" i3_target="${HOME}/${i3}" i3_backup="${backup_dir}/${i3_name}" i3status=".config/i3status/config" i3status_name="i3status" i3status_source="${__dir}/${i3status}" i3status_target="${HOME}/${i3status}" i3status_backup="${backup_dir}/${i3status_name}" xresources=".Xresources" xresources_name="xresources" xresources_source="${__dir}/${xresources}" xresources_target="${HOME}/${xresources}" xresources_backup="${backup_dir}/${xresources_name}" gitconfig=".gitconfig" gitconfig_name="gitconfig" gitconfig_source="${__dir}/${gitconfig}" gitconfig_target="${HOME}/${gitconfig}" gitconfig_backup="${backup_dir}/${gitconfig_name}" gitignore=".gitignore" gitignore_name="gitignore" gitignore_source="${__dir}/${gitignore}" gitignore_target="${HOME}/${gitignore}" gitignore_backup="${backup_dir}/${gitignore_name}" alacritty=".config/alacritty/alacritty.toml" alacritty_name="alacritty" alacritty_source="${__dir}/${alacritty}" alacritty_target="${HOME}/${alacritty}" alacritty_backup="${backup_dir}/${alacritty_name}" fontconfig=".config/fontconfig/fonts.conf" fontconfig_name="fontconfig" fontconfig_source="${__dir}/${fontconfig}" fontconfig_target="${HOME}/${fontconfig}" fontconfig_backup="${backup_dir}/${fontconfig_name}" function display_configs { echo 'Supported config targets: all, zshrc, profile, i3, i3status, xresources, gitconfig, gitignore, alacritty, fontconfig, nvim' } function display_usage { echo 'Usage: install.sh [-c|--config ] [-a|--auto-backup]' echo ' [-h|--help]' echo '' echo 'Install configurations.' echo '' echo ' -c|--config Describes what to install: Default=all' echo ' -l|--list List available configs.' echo ' -a|--auto-backup Automatically backup existing configs.' echo ' -h|--help Display this usage text.' echo '' echo 'Examples:' echo '' echo "./install.sh --config=all --auto-backup" } # Install some singular configuration file by creating a symbolic link. Handles # automatic backups if the file already exists. function install_config { # Used for diagnostic purposes only - describes the configuration. local config_name="$1" # The location of the configuration to install. local config_source="$2" # The destination where the symbolic link should be created. local config_target="$3" # The backup file for this piece of configuration. local config_backup="$4" if [ "$config_selection" = "all" ] || [ "${config_selection}" = "${config_name}" ]; then echo -n -e "${COLOR_SUCCESS}[+]${NC} Installing '${config_name}' to '${config_target}'... " if [ -f "${config_target}" ]; then if $auto_backup; then # The file exists, so create a backup and remove the file. echo -e "\n\t${COLOR_NOTIFY}[Note]${NC} creating a backup of '${config_target}'" cp "${config_target}" "${config_backup}" rm "${config_target}" ln -s "${config_source}" "${config_target}" echo -e "\t${COLOR_SUCCESS}[Success]${NC}" else # The caller does not want backups/deletions, so we must abort. echo -e "\n\t${COLOR_ERROR}[Error]${NC} Could not install configuration '${config_name}'. File '${config_target}' already exists. Please manually remove it or set --auto-backup" fi else # The file doesn't exist, we can safely create a symlink. ln -s "${config_source}" "${config_target}" echo -e "${COLOR_SUCCESS}[Success]${NC}" fi fi } function install_neovim { # Used for diagnostic purposes only - describes the configuration. local config_name="nvim" # The location of the configuration to install. local config_source=".config/nvim/init.lua" local lua_source=".config/nvim/lua" # The destination where the symbolic link should be created. local config_target="${HOME}/.config/nvim/init.lua" local lua_target="${HOME}/.config/nvim/lua" # The backup file for this piece of configuration. local config_backup="${backup_dir}/${config_name}" local lua_backup="${backup_dir}/nvim-lua" if [ "$config_selection" = "all" ] || [ "${config_selection}" = "${config_name}" ]; then echo -n -e "${COLOR_SUCCESS}[+]${NC} Installing '${config_name}' to '${config_target}'... " if [ -f "${config_target}" ]; then if $auto_backup; then # The file exists, so create a backup and remove the file. echo -e "\n\t${COLOR_NOTIFY}[Note]${NC} creating a backup of '${config_target}' and '${lua_target}'" cp "${config_target}" "${config_backup}" cp -r "${lua_target}" "${lua_backup}" rm "${config_target}" rm -r "${lua_target}" ln -s "${__dir}/${config_source}" "${config_target}" ln -s "${__dir}/${lua_source}" "${lua_target}" echo -e "\t${COLOR_SUCCESS}[Success]${NC}" else # The caller does not want backups/deletions, so we must abort. echo -e "\n\t${COLOR_ERROR}[Error]${NC} Could not install configuration '${config_name}'. This configuration already exists. Please manually remove it or set --auto-backup" fi else # The file doesn't exist, we can safely create a symlink. ln -s "${__dir}/${config_source}" "${config_target}" ln -s "${__dir}/${lua_source}" "${lua_target}" echo -e "${COLOR_SUCCESS}[Success]${NC}" fi fi } while [[ $# -gt 0 ]] do key="$1" case $key in -c|--config) config_selection="$2" shift shift ;; -a|--auto-backup) auto_backup=true shift ;; -l|--list) display_configs exit 0 ;; -h|--help) display_usage exit 0 ;; *) echo "Unrecognized option: $1" display_usage exit 1 ;; esac done # Ensure the backup directory exists (if backups are requested). if $auto_backup; then if [ ! -d "$backup_dir" ]; then if eval mkdir "$backup_dir"; then echo -e "${COLOR_NOTIFY}[Note]${NC} created '$backup_dir' to store dotfile backups." else echo -e "${COLOR_ERROR}[Error]${NC} Failed to create backup directory '$backup_dir'." fi fi fi # Install all requested configurations. install_config "${zshrc_name}" "${zshrc_source}" "${zshrc_target}" "${zshrc_backup}" install_config "${profile_name}" "${profile_source}" "${profile_target}" "${profile_backup}" install_config "${i3_name}" "${i3_source}" "${i3_target}" "${i3_backup}" install_config "${i3status_name}" "${i3status_source}" "${i3status_target}" "${i3status_backup}" install_config "${gitconfig_name}" "${gitconfig_source}" "${gitconfig_target}" "${gitconfig_backup}" install_config "${gitignore_name}" "${gitignore_source}" "${gitignore_target}" "${gitignore_backup}" install_config "${xresources_name}" "${xresources_source}" "${xresources_target}" "${xresources_backup}" install_config "${alacritty_name}" "${alacritty_source}" "${alacritty_target}" "${alacritty_backup}" install_config "${fontconfig_name}" "${fontconfig_source}" "${fontconfig_target}" "${fontconfig_backup}" # Note that all of these configurations are Neovim-related: install_neovim