1225 lines
47 KiB
Bash
Executable File
1225 lines
47 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
# =================================================================================================
|
|
#
|
|
# This program provides helpful tools for initializing a new system based on my personal dotfiles.
|
|
# It aims to provide a core set of common configs across a number of tools I use, while remaining
|
|
# flexible to a variety of deployment scenarios with different requirements.
|
|
#
|
|
# To support flexibility, this installer reads from a set of package lists. These are stored in the
|
|
# `packages` directory, in `[arch,aur,apt].[global,local]` files, corresponding to the repository
|
|
# and scope of the package.
|
|
#
|
|
# To add an Arch User Repository (AUR) package to your local config, `touch ./packages/aur.local`
|
|
# and add the package name, one per line. These will be included when installing packages from their
|
|
# respective installer commands.
|
|
#
|
|
#
|
|
# =================================================================================================
|
|
|
|
# TODO: sed -i -e s/AddKeysToAgent.*$/AddKeysToAgent yes/g' .ssh/config
|
|
# Create the file if doesn't exist
|
|
# Add the line if it's not present
|
|
#
|
|
# TODO: Setup fingerprint reader
|
|
# fprintd-enroll brad -f right-index-finger
|
|
# Copy /etc/pam.d/ configs
|
|
# auth sufficient pam_fprintd.so
|
|
# /etc/pam.d/[kde, kde-fingerprint, login, sddm, sudo, i3lock, etc?]
|
|
#
|
|
# TODO: Setup touchpad gestures
|
|
# yay -S libinput-gestures
|
|
# sudo gpasswd -a "$USER" input
|
|
# libinput-gestures-setup autostart
|
|
# Need to logout here or otherwise reload groups
|
|
# libinput-gestures-setup start
|
|
# Config in .config/libinput-gestures.conf
|
|
|
|
# TODO: Install gruvbox themes
|
|
# cd dotfiles && git submodule update --init
|
|
# mkdir ~/dotfiles/config/themes ~/dotfiles/config/icons
|
|
# cp -r ~/dotfiles/dependencies/Gruvbox-GTK-Theme/themes/* ~/dotfiles/config/themes
|
|
# cp -r ~/dotfiles/dependencies/Gruvbox-GTK-Theme/icons/* ~/dotfiles/config/icons
|
|
# cp -r ~/dotfiles/config/claude/themes/* ~/.claude/themes/
|
|
|
|
# TODO: Customize lightdm
|
|
# Move some wallpaper assets into this repo
|
|
# cp ~/dotfiles/assets/lightdm-background.png /usr/share/endeavouros/backgrounds/custom-wallpaper.png
|
|
# sudo sed --in-place=.backup 's/background=/usr/share/endeavouros/backgrounds/endeavouros-wallpaper.png/background=/usr/share/endeavouros/backgrounds/custom-wallpaper.png/g' /etc/lightdm/slick-greeter.conf
|
|
|
|
# TODO: Setup github credentials
|
|
# gh auth login
|
|
# Possibly set up a credential store
|
|
|
|
# TODO: Separate out themes and make gruvbox optional
|
|
|
|
# TODO: Restart needed needs to be implemented
|
|
|
|
# TODO: non-interactive should be used throughout the codebase
|
|
|
|
# TODO: Support different install types (user, server, hardened, IoT, devbox)
|
|
|
|
# TODO: If on mac, install brew
|
|
# /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
|
|
|
|
# TODO: If on mac, install powerline-status
|
|
# pipx install --index-url https://pypi.org/simple powerline-status
|
|
|
|
# TODO: If on mac, install powerline-fonts
|
|
# git clone https://github.com/powerline/fonts.git --depth=1 && cd fonts && ./install.sh && cd - && rm -rf ./fonts
|
|
# Or just add powerline-fonts as a dependency submodule
|
|
# Then go into iTerm2 settings and set Source Code Pro for Powerline as the font
|
|
|
|
dir="$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" # dotfiles repository directory
|
|
if [ -f "$HOME/.dotfiles-dir" ]; then
|
|
# Migrate legacy config
|
|
echo "Migrating .dotfiles-dir to .dotfiles-config"
|
|
mv "$HOME/.dotfiles-dir" "$HOME/.dotfiles-config"
|
|
fi
|
|
if [ ! -f "$HOME/.dotfiles-config" ]; then
|
|
if [ ! -f "$dir/install.sh" ] || [ ! -f "$dir/dotfiles-local.sh" ]; then
|
|
echo "Please run this script initially from within the dotfiles directory"
|
|
exit 1
|
|
fi
|
|
echo "Writing 'export DOTFILES_DIR=$dir' to $HOME/.dotfiles-config"
|
|
echo "export DOTFILES_DIR=$dir" > "$HOME/.dotfiles-config"
|
|
else
|
|
echo "Loading existing $HOME/.dotfiles-config"
|
|
fi
|
|
source "$HOME/.dotfiles-config"
|
|
unset dir
|
|
source "$DOTFILES_DIR"/functions.sh
|
|
config_dir="$DOTFILES_DIR"/config
|
|
packages_dir="$DOTFILES_DIR"/packages
|
|
platform=$(uname)
|
|
pacman_args="--noconfirm --needed"
|
|
|
|
restart_needed=0
|
|
interactive=0
|
|
|
|
if [ ! -L $DOTFILES_DIR/bin/dotfiles-install ]; then
|
|
echo "Adding this script to PATH. 'dotfiles-install' to run in the future"
|
|
ln -s "$DOTFILES_DIR/install.sh" "$DOTFILES_DIR/bin/dotfiles-install"
|
|
fi
|
|
|
|
# Files and directories to link to home directory
|
|
home_files="
|
|
zshrc
|
|
zsh_functions
|
|
profile
|
|
bash_aliases
|
|
bash_profile
|
|
bashrc
|
|
bash_functions
|
|
tmux.conf
|
|
tmux
|
|
gtkrc-2.0.mine
|
|
themes
|
|
icons
|
|
ideavimrc
|
|
"
|
|
# Files and directories under ~/.config
|
|
configs="
|
|
nvim
|
|
i3
|
|
alacritty
|
|
dunst
|
|
conky
|
|
rofi
|
|
gtk-3.0
|
|
qt5ct
|
|
powerline
|
|
VSCodium
|
|
xfce4
|
|
picom.conf
|
|
picom-extended.conf
|
|
libinput-gestures.conf
|
|
dejima
|
|
"
|
|
# Files and directories under ~/.claude
|
|
# Whole-item symlinks for anything directly under claude/ that isn't itself
|
|
# a shared directory another tool also drops files into (hooks/ is handled
|
|
# separately below, per-file, since a standalone dejima install
|
|
# also symlinks into ~/.claude/hooks).
|
|
claude_configs="
|
|
statusline.sh
|
|
"
|
|
local_home_templates="
|
|
zshrc_local
|
|
profile.local
|
|
"
|
|
user_systemd_services="
|
|
"
|
|
system_systemd_services="
|
|
archlinux-keyring-wkd-sync.service
|
|
archlinux-keyring-wkd-sync.timer
|
|
"
|
|
xsessions="
|
|
plasma-i3.desktop
|
|
"
|
|
wayland_sessions="
|
|
plasma-sway.desktop
|
|
"
|
|
arch=""
|
|
apt=""
|
|
brew=""
|
|
aur=""
|
|
flatpak=""
|
|
gem=""
|
|
pipx=""
|
|
|
|
function load_package_lists() {
|
|
if [[ -f "$packages_dir"/arch.global ]]; then
|
|
arch="$(<"$packages_dir"/arch.global)"
|
|
fi
|
|
if [[ -f "$packages_dir"/aur.global ]]; then
|
|
aur="$(<"$packages_dir"/aur.global)"
|
|
fi
|
|
if [[ -f "$packages_dir"/apt.global ]]; then
|
|
apt="$(<"$packages_dir"/apt.global)"
|
|
fi
|
|
if [[ -f "$packages_dir"/flatpak.global ]]; then
|
|
flatpak="$(<"$packages_dir"/flatpak.global)"
|
|
fi
|
|
if [[ -f "$packages_dir"/gem.global ]]; then
|
|
gem="$(<"$packages_dir"/gem.global)"
|
|
fi
|
|
if [[ -f "$packages_dir"/pipx.global ]]; then
|
|
pipx="$(<"$packages_dir"/pipx.global)"
|
|
fi
|
|
if [[ -f "$packages_dir"/brew.global ]]; then
|
|
brew="$(<"$packages_dir"/brew.global)"
|
|
fi
|
|
if [[ -f "$packages_dir"/arch.local ]]; then
|
|
arch_overrides="$(<"$packages_dir"/arch.local)"
|
|
printf -v arch "${arch}\n${arch_overrides}"
|
|
fi
|
|
if [[ -f "$packages_dir"/aur.local ]]; then
|
|
aur_overrides="$(<"$packages_dir"/aur.local)"
|
|
printf -v aur "${aur}\n${aur_overrides}"
|
|
fi
|
|
if [[ -f "$packages_dir"/apt.local ]]; then
|
|
apt_overrides="$(<"$packages_dir"/apt.local)"
|
|
printf -v apt "${apt}\n${apt_overrides}"
|
|
fi
|
|
if [[ -f "$packages_dir"/flatpak.local ]]; then
|
|
flatpak_overrides="$(<"$packages_dir"/flatpak.local)"
|
|
printf -v flatpak "${flatpak}\n${flatpak_overrides}"
|
|
fi
|
|
if [[ -f "$packages_dir"/gem.local ]]; then
|
|
gem_overrides="$(<"$packages_dir"/gem.local)"
|
|
printf -v gem "${gem}\n${gem_overrides}"
|
|
fi
|
|
if [[ -f "$packages_dir"/pipx.local ]]; then
|
|
pipx_overrides="$(<"$packages_dir"/pipx.local)"
|
|
printf -v pipx "${pipx}\n${pipx_overrides}"
|
|
fi
|
|
if [[ -f "$packages_dir"/brew.local ]]; then
|
|
brew_overrides="$(<"$packages_dir"/brew.local)"
|
|
printf -v brew "${brew}\n${brew_overrides}"
|
|
fi
|
|
}
|
|
|
|
function link_dotfiles {
|
|
# change to the dotfiles directory
|
|
cd $config_dir
|
|
echo ""
|
|
|
|
# Check if existing file in homedir and warn if so, otherwise create symlinks from the
|
|
# files in the dotfiles directory specified in $files to the homedir
|
|
for file in $home_files; do
|
|
if [[ -f $file || -d $file ]]; then
|
|
if [[ -L $HOME/.$file ]]; then
|
|
echo "Skipping: $file because ~/.$file already linked"
|
|
else
|
|
if [[ -f "$HOME/.$file" || -d "$HOME/.$file" ]]; then
|
|
echo "Moving: existing ~/.$file to ~/.dotfiles-backup/$file"
|
|
if [ ! -d $HOME/.dotfiles-backup ]; then
|
|
mkdir -p $HOME/.dotfiles-backup
|
|
fi
|
|
mv "$HOME/.$file" "$HOME/.dotfiles-backup/$file"
|
|
fi
|
|
echo "Linking: $file ($config_dir/$file -> ~/.$file)"
|
|
ln -s $config_dir/$file $HOME/.$file
|
|
fi
|
|
fi
|
|
done
|
|
for file in $configs; do
|
|
if [[ -f $file || -d $file ]]; then
|
|
if [[ -L "$HOME/.config/$file" ]]; then
|
|
echo "Skipping: $file because ~/.config/$file already linked"
|
|
else
|
|
if [[ -f "$HOME/.config/$file" || -d "$HOME/.config/$file" ]]; then
|
|
echo "Moving: existing ~/.config/$file to ~/.dotfiles-backup/config/$file"
|
|
if [ ! -d $HOME/.dotfiles-backup/config ]; then
|
|
mkdir -p $HOME/.dotfiles-backup/config
|
|
fi
|
|
mv "$HOME/.config/$file" "$HOME/.dotfiles-backup/config/$file"
|
|
fi
|
|
echo "Linking: $file ($config_dir/$file -> ~/.config/$file)"
|
|
ln -s $config_dir/$file $HOME/.config/$file
|
|
fi
|
|
fi
|
|
done
|
|
echo -n "Would you like to link the Claude Code dotfiles (~/.claude/[CLAUDE.md, hooks, themes, etc])? (y/N) "
|
|
read response
|
|
if [[ "$response" == 'y' ]] || [[ "$response" == 'Y' ]]; then
|
|
for file in $claude_configs; do
|
|
if [[ -f claude/$file || -d claude/$file ]]; then
|
|
if [[ -f "$HOME/.claude/.stignore" ]] && ! grep -qxF "$file" "$HOME/.claude/.stignore"; then
|
|
echo "Adding $file to ~/.claude/.stignore"
|
|
echo "$file" >> "$HOME/.claude/.stignore"
|
|
fi
|
|
if [[ -L "$HOME/.claude/$file" ]]; then
|
|
echo "Skipping: $file because ~/.claude/$file already linked"
|
|
else
|
|
if [[ -f "$HOME/.claude/$file" || -d "$HOME/.claude/$file" ]]; then
|
|
echo "Moving: existing ~/.claude/$file to ~/.dotfiles-backup/claude/$file"
|
|
if [ ! -d $HOME/.dotfiles-backup/claude ]; then
|
|
mkdir -p $HOME/.dotfiles-backup/claude
|
|
fi
|
|
mv "$HOME/.claude/$file" "$HOME/.dotfiles-backup/claude/$file"
|
|
fi
|
|
echo "Linking: $file ($config_dir/claude/$file -> ~/.claude/$file)"
|
|
mkdir -p $HOME/.claude
|
|
ln -s $config_dir/claude/$file $HOME/.claude/$file
|
|
fi
|
|
fi
|
|
done
|
|
# CLAUDE.md is user-authored content, not a shared config: if one
|
|
# already exists it's left alone (no backup-and-replace) since it's
|
|
# likely the user's own instructions, not a leftover to overwrite.
|
|
if [[ -L "$HOME/.claude/CLAUDE.md" ]]; then
|
|
echo "Skipping: CLAUDE.md because ~/.claude/CLAUDE.md already linked"
|
|
elif [[ -f "$HOME/.claude/CLAUDE.md" ]]; then
|
|
echo "Skipping: CLAUDE.md because ~/.claude/CLAUDE.md already exists"
|
|
else
|
|
echo "Linking: CLAUDE.md ($config_dir/claude/CLAUDE.md -> ~/.claude/CLAUDE.md)"
|
|
mkdir -p $HOME/.claude
|
|
ln -s $config_dir/claude/CLAUDE.md $HOME/.claude/CLAUDE.md
|
|
fi
|
|
# ~/.claude/hooks is a real directory, not a single symlink: other
|
|
# installs (e.g. a standalone dejima checkout) also drop
|
|
# their own hook files in there, so dotfiles only ever links its own
|
|
# individual files into it, never claims the whole directory.
|
|
mkdir -p "$HOME/.claude/hooks"
|
|
for hook_file in claude/hooks/*; do
|
|
hook_name=$(basename "$hook_file")
|
|
if [[ -L "$HOME/.claude/hooks/$hook_name" ]]; then
|
|
echo "Skipping: hooks/$hook_name because ~/.claude/hooks/$hook_name already linked"
|
|
else
|
|
if [[ -f "$HOME/.claude/hooks/$hook_name" ]]; then
|
|
echo "Moving: existing ~/.claude/hooks/$hook_name to ~/.dotfiles-backup/claude/hooks/$hook_name"
|
|
mkdir -p "$HOME/.dotfiles-backup/claude/hooks"
|
|
mv "$HOME/.claude/hooks/$hook_name" "$HOME/.dotfiles-backup/claude/hooks/$hook_name"
|
|
fi
|
|
echo "Linking: hooks/$hook_name ($config_dir/claude/hooks/$hook_name -> ~/.claude/hooks/$hook_name)"
|
|
ln -s "$config_dir/claude/hooks/$hook_name" "$HOME/.claude/hooks/$hook_name"
|
|
fi
|
|
done
|
|
if [[ -f "$HOME/.claude/settings.json" ]] && program_installed jq; then
|
|
if ! jq -e '[.hooks.PreToolUse[]?.hooks[]?.command // empty] | any(test("deny-dangerous-bash.sh"))' "$HOME/.claude/settings.json" >/dev/null 2>&1; then
|
|
echo "Adding deny-dangerous-bash.sh PreToolUse hook to ~/.claude/settings.json"
|
|
tmp_settings=$(mktemp)
|
|
jq '.hooks.PreToolUse = ((.hooks.PreToolUse // []) + [{"matcher": "Bash", "hooks": [{"type": "command", "command": "$HOME/.claude/hooks/deny-dangerous-bash.sh"}]}])' \
|
|
"$HOME/.claude/settings.json" > "$tmp_settings" && mv "$tmp_settings" "$HOME/.claude/settings.json"
|
|
fi
|
|
if ! jq -e '.statusLine' "$HOME/.claude/settings.json" >/dev/null 2>&1; then
|
|
echo "Adding statusline.sh statusLine to ~/.claude/settings.json"
|
|
tmp_settings=$(mktemp)
|
|
jq '.statusLine = {"type": "command", "command": "$HOME/.claude/statusline.sh"}' \
|
|
"$HOME/.claude/settings.json" > "$tmp_settings" && mv "$tmp_settings" "$HOME/.claude/settings.json"
|
|
fi
|
|
fi
|
|
fi
|
|
# TODO: These are getting in the way of dotfiles-local install so disabling
|
|
# Refactor this
|
|
# for file in $local_home_templates; do
|
|
# if [[ -f ./local-templates/$file || -d ./local-templates/$file ]]; then
|
|
# if [[ -f $HOME/.$file || -d $HOME/.$file ]]; then
|
|
# echo "Skipping: $file because ~/.$file already exists"
|
|
# else
|
|
# echo "Copying: $file ($config_dir/local-templates/$file -> ~/.$file)"
|
|
# cp $config_dir/local-templates/$file $HOME/.$file
|
|
# fi
|
|
# fi
|
|
# done
|
|
for file in $user_systemd_services; do
|
|
if [[ -f systemd/user/$file || -d systemd/user/$file ]]; then
|
|
if [[ -L "$HOME/.config/systemd/user/$file" ]]; then
|
|
echo "Skipping: $file because ~/.config/systemd/user/$file already linked"
|
|
elif [[ -f $HOME/.config/systemd/user/$file || -d $HOME/.config/systemd/user/$file ]]; then
|
|
echo "Skipping: $file because ~/.config/systemd/user/$file already exists"
|
|
else
|
|
echo "Linking: $file ($config_dir/systemd/user/$file -> ~/.config/systemd/user/$file)"
|
|
ln -s $config_dir/systemd/user/$file $HOME/.config/systemd/user/$file
|
|
|
|
echo -n "Would you like to enable $file user service? (y/N) "
|
|
read response
|
|
if [[ "$response" == 'y' ]] || [[ "$response" == 'Y' ]]; then
|
|
systemctl --user enable --now $file
|
|
fi
|
|
fi
|
|
fi
|
|
done
|
|
if [ "$interactive" == 1 ]; then
|
|
echo -n "Would you like to install systemd system services? (y/N) "
|
|
read response
|
|
if [[ "$response" == 'y' ]] || [[ "$response" == 'Y' ]]; then
|
|
for file in $system_systemd_services; do
|
|
if [[ -f systemd/$file || -d systemd/system/$file ]]; then
|
|
if [[ -L "/etc/systemd/system/$file" ]]; then
|
|
echo "Skipping: $file because /etc/systemd/system/$file already linked"
|
|
elif [[ -f /etc/systemd/system/$file || -d /etc/systemd/system/$file ]]; then
|
|
echo "Skipping: $file because /etc/systemd/system/$file already exists"
|
|
else
|
|
echo "Linking: $file ($config_dir/systemd/$file -> /etc/systemd/system/$file)"
|
|
sudo ln -s $config_dir/systemd/$file /etc/systemd/system/$file
|
|
|
|
echo -n "Would you like to enable $file systemd service? (y/N) "
|
|
read response
|
|
if [[ "$response" == 'y' ]] || [[ "$response" == 'Y' ]]; then
|
|
sudo systemctl enable --now $file
|
|
fi
|
|
fi
|
|
fi
|
|
done
|
|
fi
|
|
fi
|
|
cd - > /dev/null
|
|
}
|
|
|
|
function link_dotfiles_local() {
|
|
if [ -d "$DOTFILES_DIR/dependencies/dotfiles-local" ]; then
|
|
cd "$DOTFILES_DIR/dependencies/dotfiles-local"
|
|
# Check if on main branch
|
|
current_branch=$(git rev-parse --abbrev-ref HEAD)
|
|
if [ "$current_branch" == "main" ]; then
|
|
if [ "$interactive" == 0 ]; then
|
|
echo "Local dotfiles repo on branch $current_branch and tool running non-interactively."
|
|
echo "Setting branch to $(hostname)"
|
|
current_branch=$(hostname)
|
|
# echo "Please set branch by running:"
|
|
# echo "> $DOTFILES_DIR/dotfiles-local.sh {machine-name}"
|
|
# return
|
|
fi
|
|
fi
|
|
cd -
|
|
else
|
|
echo "Local dotfiles repo not found. Cloning into dependencies"
|
|
if [ "$interactive" == 0 ]; then
|
|
echo "Tool running non-interactively. Setting branch to $(hostname)"
|
|
else
|
|
echo -n "What machine name would you like to use for this branch? [$(hostname)] "
|
|
read response
|
|
if [ -z "$response" ]; then
|
|
current_branch=$(hostname)
|
|
else
|
|
current_branch="$response"
|
|
fi
|
|
fi
|
|
fi
|
|
echo ""
|
|
"$DOTFILES_DIR"/dotfiles-local.sh "$current_branch"
|
|
}
|
|
|
|
function install_aur() {
|
|
# install AUR programs if on Arch
|
|
if program_installed yay; then
|
|
echo ""
|
|
echo "Installing and updating AUR packages"
|
|
yay -Syua $pacman_args
|
|
to_install=()
|
|
while IFS= read -r program || [[ -n $program ]]; do
|
|
# Check for comment or whitespace
|
|
if [[ "$program" == '#'* || -z "${program// }" ]]; then
|
|
continue
|
|
fi
|
|
if ! program_installed $program; then
|
|
to_install+=("$program")
|
|
fi
|
|
done < <(printf '%s' "$aur")
|
|
if [ "${#to_install[@]}" -gt 0 ]; then
|
|
yay -Sqa $pacman_args "${to_install[@]}"
|
|
fi
|
|
fi
|
|
}
|
|
|
|
function install_main() {
|
|
if program_installed pacman; then
|
|
echo ""
|
|
echo "Installing and updating pacman packages"
|
|
sudo pacman -Sy --needed archlinux-keyring
|
|
sudo pacman -Syu
|
|
while IFS= read -r program || [[ -n $program ]]; do
|
|
# Check for comment or whitespace
|
|
if [[ "$program" == '#'* || -z "${program// }" ]]; then
|
|
continue
|
|
fi
|
|
if ! program_installed $program; then
|
|
to_install+=("$program")
|
|
fi
|
|
done < <(printf '%s' "$arch")
|
|
if [ "${#to_install[@]}" -gt 0 ]; then
|
|
sudo pacman -Sq $pacman_args "${to_install[@]}"
|
|
fi
|
|
elif program_installed apt-get; then
|
|
echo ""
|
|
echo "Installing and updating apt packages"
|
|
sudo apt-get update
|
|
sudo apt-get upgrade
|
|
to_install=()
|
|
while IFS= read -r program || [[ -n $program ]]; do
|
|
# Check for comment or whitespace
|
|
if [[ "$program" == '#'* || -z "${program// }" ]]; then
|
|
continue
|
|
fi
|
|
if ! program_installed $program; then
|
|
to_install+=("$program")
|
|
fi
|
|
done < <(printf '%s' "$apt")
|
|
if [ "${#to_install[@]}" -gt 0 ]; then
|
|
sudo apt-get install -y "${to_install[@]}"
|
|
fi
|
|
elif program_installed brew; then
|
|
echo ""
|
|
echo "Installing and updating brew packages"
|
|
brew update
|
|
brew upgrade
|
|
to_install=()
|
|
while IFS= read -r program || [[ -n $program ]]; do
|
|
# Check for comment or whitespace
|
|
if [[ "$program" == '#'* || -z "${program// }" ]]; then
|
|
continue
|
|
fi
|
|
if ! program_installed $program; then
|
|
to_install+=("$program")
|
|
fi
|
|
done < <(printf '%s' "$brew")
|
|
if [ "${#to_install[@]}" -gt 0 ]; then
|
|
brew install "${to_install[@]}"
|
|
fi
|
|
else
|
|
echo "Cannot install programs, no compatible package manager."
|
|
fi
|
|
}
|
|
|
|
function install_flatpak() {
|
|
if program_installed flatpak; then
|
|
echo ""
|
|
echo "Installing and updating flatpak packages"
|
|
flatpak update --noninteractive --assumeyes
|
|
while IFS= read -r program || [[ -n $program ]]; do
|
|
# Check for comment or whitespace
|
|
if [[ "$program" == '#'* || -z "${program// }" ]]; then
|
|
continue
|
|
fi
|
|
program_array=($program)
|
|
remote=${program_array[0]}
|
|
app=${program_array[1]}
|
|
flatpak install --noninteractive --assumeyes $remote $app
|
|
done < <(printf '%s' "$flatpak")
|
|
fi
|
|
}
|
|
|
|
function install_gem() {
|
|
if program_installed gem; then
|
|
echo ""
|
|
echo "Installing and updating gem packages"
|
|
gem update
|
|
to_install=()
|
|
while IFS= read -r program || [[ -n $program ]]; do
|
|
# Check for comment or whitespace
|
|
if [[ "$program" == '#'* || -z "${program// }" ]]; then
|
|
continue
|
|
fi
|
|
to_install+=("$program")
|
|
done < <(printf '%s' "$gem")
|
|
if [ "${#to_install[@]}" -gt 0 ]; then
|
|
gem install "${to_install[@]}"
|
|
fi
|
|
fi
|
|
}
|
|
|
|
function install_pipx() {
|
|
if program_installed pipx; then
|
|
echo ""
|
|
echo "Installing and updating pipx packages"
|
|
pipx upgrade-all
|
|
to_install=()
|
|
while IFS= read -r program || [[ -n $program ]]; do
|
|
# Check for comment or whitespace
|
|
if [[ "$program" == '#'* || -z "${program// }" ]]; then
|
|
continue
|
|
fi
|
|
if ! program_installed $program; then
|
|
to_install+=("$program")
|
|
fi
|
|
done < <(printf '%s' "$pipx")
|
|
if [ "${#to_install[@]}" -gt 0 ]; then
|
|
pipx install "${to_install[@]}"
|
|
fi
|
|
fi
|
|
}
|
|
|
|
function install_gpu_monitoring() {
|
|
if program_installed nvidia-smi; then
|
|
if ! id "nvidia_gpu_exporter" >/dev/null 2>&1; then
|
|
echo 'Creating nvidia_gpu_exporter user'
|
|
sudo useradd --system --no-create-home --shell /usr/sbin/nologin nvidia_gpu_exporter
|
|
fi
|
|
if program_installed dpkg; then
|
|
echo "Installing nvidia-gpu-exporter using dpkg"
|
|
sudo dpkg -i nvidia-gpu-exporter_1.3.1_linux_amd64.deb
|
|
else
|
|
VERSION=1.3.1
|
|
echo "Installing nvidia-gpu-exporter from release binary [version $VERSION]"
|
|
wget -o /dev/null https://github.com/utkuozdemir/nvidia_gpu_exporter/releases/download/v${VERSION}/nvidia_gpu_exporter_${VERSION}_linux_x86_64.tar.gz
|
|
mkdir -p ./nvidia_gpu_exporter
|
|
tar -xvzf nvidia_gpu_exporter_${VERSION}_linux_x86_64.tar.gz -C ./nvidia_gpu_exporter >/dev/null
|
|
rm nvidia_gpu_exporter_${VERSION}_linux_x86_64.tar.gz
|
|
sudo mv nvidia_gpu_exporter/nvidia_gpu_exporter /usr/bin
|
|
rm -r ./nvidia_gpu_exporter
|
|
unset VERSION
|
|
fi
|
|
if program_installed systemctl; then
|
|
echo "Installing systemd service for nvidia-gpu-exporter and enabling"
|
|
sudo wget -o /dev/null -O /etc/systemd/system/nvidia_gpu_exporter.service https://raw.githubusercontent.com/utkuozdemir/nvidia_gpu_exporter/refs/heads/master/systemd/nvidia_gpu_exporter.service >/dev/null
|
|
sudo systemctl daemon-reload
|
|
sudo systemctl enable --now nvidia_gpu_exporter
|
|
fi
|
|
if program_installed firewall-cmd; then
|
|
# Open firewall port in firewalld
|
|
PORT=9835
|
|
# Check if the rule already exists
|
|
if sudo firewall-cmd --state | grep -q '^running'; then
|
|
# firewalld is running
|
|
if ! sudo firewall-cmd --permanent --add-port=$PORT/tcp 2>&1 | grep -q 'ALREADY_ENABLED'; then
|
|
echo "Opened firewalld port $PORT/tcp for nvidia-gpu-exporter."
|
|
# Reload firewall to apply changes
|
|
echo "Reloading firewalld"
|
|
sudo firewall-cmd --quiet --reload
|
|
else
|
|
echo "Port $PORT/tcp is already open."
|
|
fi
|
|
fi
|
|
unset PORT
|
|
fi
|
|
fi
|
|
}
|
|
|
|
function setup_zsh() {
|
|
# Only ask to setup if zsh installed and not the current shell
|
|
if program_installed zsh && [ "$SHELL" != "$(which zsh)" ]; then
|
|
echo
|
|
echo -n "Would you like to set zsh as your default shell? (y/N) "
|
|
read response
|
|
if [[ "$response" == 'y' ]] || [[ "$response" == 'Y' ]]; then
|
|
echo "Setting zsh as default shell"
|
|
chsh -s /usr/bin/zsh
|
|
fi
|
|
fi
|
|
}
|
|
|
|
function setup_system_configs() {
|
|
setup_zsh
|
|
if program_installed sshd && ! service_enabled sshd.service; then
|
|
echo
|
|
echo "Enabling SSH server"
|
|
sudo systemctl enable --now sshd.service
|
|
fi
|
|
if program_installed lightdm; then
|
|
echo
|
|
echo "Enabling numlock at startup"
|
|
original=`cat /etc/lightdm/lightdm.conf` >> /dev/null
|
|
sudo sed --in-place=.backup 's/#greeter-setup-script=/greeter-setup-script=\/usr\/bin\/numlockx on/g' /etc/lightdm/lightdm.conf
|
|
edited=`cat /etc/lightdm/lightdm.conf` >> /dev/null
|
|
diff=`diff <(echo "$original") <(echo "$edited")`
|
|
if [[ "$diff" != '' ]]; then
|
|
echo "$diff"
|
|
restart_needed=1
|
|
else
|
|
echo "No changes were made"
|
|
fi
|
|
fi
|
|
|
|
# Assume Steam is desired if xdg-desktop-portal is installed
|
|
if [ -f /usr/share/xdg-desktop-portal/portals/gtk.portal ] && program_installed i3; then
|
|
echo
|
|
echo "Enabling xdg-desktop-portal-gtk in i3 (needed for Steam)"
|
|
original=`cat /usr/share/xdg-desktop-portal/portals/gtk.portal` >> /dev/null
|
|
sudo sed --in-place=.backup 's/^UseIn=gnome$/UseIn=gnome;i3/g' /usr/share/xdg-desktop-portal/portals/gtk.portal
|
|
edited=`cat /usr/share/xdg-desktop-portal/portals/gtk.portal` >> /dev/null
|
|
diff=`diff <(echo "$original") <(echo "$edited")`
|
|
if [[ "$diff" != '' ]]; then
|
|
echo "$diff"
|
|
restart_needed=1
|
|
else
|
|
echo "No changes were made"
|
|
fi
|
|
fi
|
|
|
|
# If gnome-keyring is installed and i3, enable its XDG portal backend
|
|
if [ -f /usr/share/xdg-desktop-portal/portals/gnome-keyring.portal ] && program_installed i3; then
|
|
echo
|
|
echo "Enabling xdg-desktop-portal-gnome-keyring in i3"
|
|
original=`cat /usr/share/xdg-desktop-portal/portals/gnome-keyring.portal` >> /dev/null
|
|
sudo sed --in-place=.backup 's/^UseIn=gnome$/UseIn=gnome;i3/g' /usr/share/xdg-desktop-portal/portals/gnome-keyring.portal
|
|
edited=`cat /usr/share/xdg-desktop-portal/portals/gnome-keyring.portal` >> /dev/null
|
|
diff=`diff <(echo "$original") <(echo "$edited")`
|
|
if [[ "$diff" != '' ]]; then
|
|
echo "$diff"
|
|
restart_needed=1
|
|
else
|
|
echo "No changes were made"
|
|
fi
|
|
fi
|
|
|
|
if program_installed vim && program_installed nvim && [ ! -f /usr/bin/vim ]; then
|
|
echo
|
|
echo "Preventing missing vim issues"
|
|
sudo ln -s "$(which nvim)" /usr/bin/vim
|
|
fi
|
|
|
|
# TODO: Make sure bluetooth is installed
|
|
if ! service_enabled bluetooth.service; then
|
|
echo
|
|
echo "Enabling Bluetooth"
|
|
sudo systemctl enable --now bluetooth.service
|
|
fi
|
|
|
|
if program_installed syncthing && ! service_enabled syncthing.service; then
|
|
echo
|
|
echo "Enabling Syncthing"
|
|
systemctl enable --user --now syncthing.service
|
|
echo "Configure syncthing here:"
|
|
echo "http://localhost:8384"
|
|
fi
|
|
choose_desktop_environment
|
|
}
|
|
|
|
function setup_sessions() {
|
|
# Install plasma + i3 sessions
|
|
echo
|
|
echo -n "Would you like to install X11 / Wayland sessions? (y/N) "
|
|
read response
|
|
if [[ "$response" == 'y' ]] || [[ "$response" == 'Y' ]]; then
|
|
# Check if xsessions directory exists
|
|
if [[ -d /usr/share/xsessions ]]; then
|
|
for file in $xsessions; do
|
|
if [[ -f $config_dir/xsessions/$file ]]; then
|
|
if [[ -f /usr/share/xsessions/$file ]]; then
|
|
echo "Skipping: $file because /usr/share/xsessions/$file already exists"
|
|
else
|
|
echo "Copying: $file ($config_dir/xsessions/$file -> /usr/share/xsessions/$file)"
|
|
sudo cp $config_dir/xsessions/$file /usr/share/xsessions/$file
|
|
fi
|
|
fi
|
|
done
|
|
fi
|
|
# Check if wayland_sessions directory exists
|
|
if [[ -d /usr/share/wayland-sessions ]]; then
|
|
for file in $wayland_sessions; do
|
|
if [[ -f $config_dir/wayland-sessions/$file ]]; then
|
|
if [[ -f /usr/share/wayland-sessions/$file ]]; then
|
|
echo "Skipping: $file because /usr/share/wayland-sessions/$file already exists"
|
|
else
|
|
echo "Copying: $file ($config_dir/wayland-sessions/$file -> /usr/share/wayland-sessions/$file)"
|
|
sudo cp $config_dir/wayland-sessions/$file /usr/share/wayland-sessions/$file
|
|
fi
|
|
fi
|
|
done
|
|
fi
|
|
fi
|
|
}
|
|
|
|
function choose_desktop_environment() {
|
|
echo
|
|
echo "Choose a desktop environment"
|
|
echo "[plasma-i3] Plasma desktop environment with i3 as window manager"
|
|
echo "[i3] i3 window manager only"
|
|
echo "[plasma] Set up samba credentials only"
|
|
echo "[0] No change"
|
|
echo ""
|
|
echo "What would you like to do?"
|
|
read response
|
|
if [[ $response == "plasma-i3" ]]; then
|
|
setup_plasma_i3
|
|
elif [[ $response == "i3" ]]; then
|
|
setup_bare_i3
|
|
elif [[ $response == "plasma" ]]; then
|
|
setup_bare_plasma
|
|
else
|
|
echo "Making no changes to desktop environment"
|
|
fi
|
|
}
|
|
|
|
function setup_bare_i3() {
|
|
echo "Configuring i3"
|
|
if ! program_installed i3; then
|
|
echo "i3 not installed, please install and rerun"
|
|
return 1
|
|
fi
|
|
# TODO: Set display manager to lightdm?
|
|
if [[ ! -d ~/.config/i3/config.de ]]; then
|
|
mkdir ~/.config/i3/config.de
|
|
fi
|
|
if [[ -f ~/.config/i3/config.de/i3-keybindings.conf ]]; then
|
|
echo "Skipping: i3-keybindings.conf because ~/.config/i3/config.de/i3-keybindings.conf already exists"
|
|
else
|
|
echo "Linking: i3-keybindings.conf ($config_dir/bare-i3/i3-keybindings.conf -> ~/.config/i3/config.de/i3-keybindings.conf)"
|
|
ln -s $config_dir/bare-i3/i3-keybindings.conf ~/.config/i3/config.de/i3-keybindings.conf
|
|
fi
|
|
|
|
if [[ -f ~/.config/i3/config.de/i3-bar.conf ]]; then
|
|
echo "Skipping: i3-bar.conf because ~/.config/i3/config.de/i3-bar.conf already exists"
|
|
else
|
|
echo "Linking: i3-bar.conf ($config_dir/bare-i3/i3-bar.conf -> ~/.config/i3/config.de/i3-bar.conf)"
|
|
ln -s $config_dir/bare-i3/i3-bar.conf ~/.config/i3/config.de/i3-bar.conf
|
|
fi
|
|
|
|
if [[ -f ~/.config/i3/config.de/i3-autostart.conf ]]; then
|
|
echo "Skipping: i3-autostart.conf because ~/.config/i3/config.de/i3-autostart.conf already exists"
|
|
else
|
|
echo "Linking: i3-autostart.conf ($config_dir/bare-i3/i3-autostart.conf -> ~/.config/i3/config.de/i3-autostart.conf)"
|
|
ln -s $config_dir/bare-i3/i3-autostart.conf ~/.config/i3/config.de/i3-autostart.conf
|
|
fi
|
|
|
|
if [[ -f /etc/systemd/system/update-wallpapers.service ]]; then
|
|
echo "Skipping: update-wallpapers.service because /etc/systemd/system/update-wallpapers.service already exists"
|
|
else
|
|
echo "Linking: update-wallpapers.service ($config_dir/systemd/update-wallpapers.service -> /etc/systemd/system/update-wallpapers.service)"
|
|
sudo ln -s $config_dir/systemd/update-wallpapers.service /etc/systemd/system/update-wallpapers.service
|
|
fi
|
|
|
|
if [[ -f /etc/udev/rules.d/85-drm-hotplug.rules ]]; then
|
|
echo "Skipping: 85-drm-hotplug.rules because /etc/udev/rules.d/85-drm-hotplug.rules already exists"
|
|
else
|
|
echo "Linking: 85-drm-hotplug.rules ($config_dir/udev/85-drm-hotplug.rules -> /etc/udev/rules.d/85-drm-hotplug.rules)"
|
|
sudo ln -s $config_dir/udev/85-drm-hotplug.rules /etc/udev/rules.d/85-drm-hotplug.rules
|
|
fi
|
|
# Setup GTK themes
|
|
# TODO: It might be necessary to rerun `dotfiles-install dotfiles` after this
|
|
if [ ! -d "$config_dir/themes" ]; then
|
|
mkdir "$config_dir/themes"
|
|
fi
|
|
if [ ! -d "$config_dir/icons" ]; then
|
|
mkdir "$config_dir/icons"
|
|
fi
|
|
# TODO: Can I symlink these instead?
|
|
cp -r "$DOTFILES_DIR"/dependencies/Gruvbox-GTK-Theme/themes/* "$config_dir/themes"
|
|
cp -r "$DOTFILES_DIR"/dependencies/Gruvbox-GTK-Theme/icons/* "$config_dir/icons"
|
|
# TODO: Actually launch into i3 rather than plasma, need to set up DM configs
|
|
}
|
|
|
|
function setup_plasma_i3() {
|
|
if ! program_installed i3 && ! program_installed plasmashell; then
|
|
echo "Neither i3 nor plasma installed, please install and rerun"
|
|
return 1
|
|
fi
|
|
if ! program_installed i3; then
|
|
echo "i3 not installed, please install and rerun"
|
|
return 1
|
|
fi
|
|
if ! program_installed plasmashell; then
|
|
echo "Plasma not installed, please install and rerun"
|
|
# TODO: echo the command to install plasma
|
|
return 1
|
|
fi
|
|
|
|
echo "Copying: startplasma-sway-wayland ($config_dir/bin/startplasma-sway-wayland -> /usr/local/bin/)"
|
|
sudo cp $config_dir/scripts/startplasma-sway-wayland /usr/local/bin/
|
|
|
|
echo "Configuring i3"
|
|
if [[ -f ~/.config/i3/config.de/i3-keybindings.conf ]]; then
|
|
echo "Skipping: i3-keybindings.conf because ~/.config/i3/config.de/i3-keybindings.conf already exists"
|
|
else
|
|
echo "Linking: i3-keybindings.conf ($config_dir/plasma-i3/i3-keybindings.conf -> ~/.config/i3/config.de/i3-keybindings.conf)"
|
|
ln -s $config_dir/plasma-i3/i3-keybindings.conf ~/.config/i3/config.de/i3-keybindings.conf
|
|
fi
|
|
|
|
if [[ -f ~/.config/i3/config.de/i3-bar.conf ]]; then
|
|
echo "Skipping: i3-bar.conf because ~/.config/i3/config.de/i3-bar.conf already exists"
|
|
else
|
|
echo "Linking: i3-bar.conf ($config_dir/plasma-i3/i3-bar.conf -> ~/.config/i3/config.de/i3-bar.conf)"
|
|
ln -s $config_dir/plasma-i3/i3-bar.conf ~/.config/i3/config.de/i3-bar.conf
|
|
fi
|
|
|
|
if [[ -f /etc/systemd/system/update-wallpapers.service ]]; then
|
|
echo "Skipping: update-wallpapers.service because /etc/systemd/system/update-wallpapers.service already exists"
|
|
else
|
|
echo "Linking: update-wallpapers.service ($config_dir/systemd/update-wallpapers.service -> /etc/systemd/system/update-wallpapers.service)"
|
|
sudo ln -s $config_dir/systemd/update-wallpapers.service /etc/systemd/system/update-wallpapers.service
|
|
fi
|
|
|
|
if [[ -f /etc/udev/rules.d/85-drm-hotplug.rules ]]; then
|
|
echo "Skipping: 85-drm-hotplug.rules because /etc/udev/rules.d/85-drm-hotplug.rules already exists"
|
|
else
|
|
echo "Linking: 85-drm-hotplug.rules ($config_dir/udev/85-drm-hotplug.rules -> /etc/udev/rules.d/85-drm-hotplug.rules)"
|
|
sudo ln -s $config_dir/udev/85-drm-hotplug.rules /etc/udev/rules.d/85-drm-hotplug.rules
|
|
fi
|
|
|
|
echo "Disabling plasma systemd autostart"
|
|
if program_installed kwriteconfig5; then
|
|
kwriteconfig5 --file startkderc --group General --key systemdBoot false
|
|
fi
|
|
if program_installed kwriteconfig6; then
|
|
kwriteconfig6 --file startkderc --group General --key systemdBoot false
|
|
fi
|
|
|
|
setup_sessions
|
|
}
|
|
|
|
function setup_bare_plasma() {
|
|
if ! program_installed plasmashell; then
|
|
echo "Plasma not installed, please install and rerun"
|
|
return 1
|
|
fi
|
|
|
|
echo "Configuring plasma"
|
|
# TODO: Copy over plasma configs (or just do this by default with other configs)
|
|
# Mostly we just want to not do the things we do in the other DE functions here
|
|
# TODO: Undo the things the other window manager setups do
|
|
}
|
|
|
|
function setup_samba() {
|
|
echo
|
|
echo -n "Would you like to configure an SMB host? (y/N) "
|
|
read response
|
|
if [[ "$response" == 'y' ]] || [[ "$response" == 'Y' ]]; then
|
|
echo -n "What is the friendly name of the SMB host? "
|
|
read samba_host
|
|
echo -n "What is the IP address of the SMB host? "
|
|
read samba_ip
|
|
if [[ "$samba_host" != '' ]] && [[ "$samba_ip" != '' ]]; then
|
|
echo
|
|
echo -n "Would you like to configure SMB credentials for this host? (y/N) "
|
|
read response
|
|
if [[ "$response" == 'y' ]] || [[ "$response" == 'Y' ]]; then
|
|
[[ ! -d "/etc/samba" ]] && sudo mkdir /etc/samba
|
|
[[ ! -d "/etc/samba/credentials" ]] && sudo mkdir /etc/samba/credentials
|
|
if [[ -d "/etc/samba/credentials" ]]; then
|
|
echo
|
|
echo -n "username: "
|
|
read username
|
|
echo -n "password: "
|
|
read -s password
|
|
echo
|
|
echo "Writing config to /etc/samba/credentials/$samba_host"
|
|
printf "username=$username\npassword=$password" | sudo tee "/etc/samba/credentials/$samba_host" >> /dev/null
|
|
unset username
|
|
unset password
|
|
fi
|
|
fi
|
|
while true; do
|
|
echo
|
|
echo -n "Would you like to configure an SMB volume mount for this host? (y/N) "
|
|
read response
|
|
if [[ "$response" == 'y' ]] || [[ "$response" == 'Y' ]]; then
|
|
echo
|
|
echo -n "What is the SMB volume mount name? "
|
|
read samba_share
|
|
echo -n "What directory would you like to mount the volume to in /mnt? "
|
|
read mnt_dir
|
|
fstab_line="//$samba_ip/$samba_share /mnt/$mnt_dir cifs _netdev,nofail,x-systemd.automount,uid=$(id -u),gid=$(id -g),credentials=/etc/samba/credentials/$samba_host 0 0"
|
|
echo
|
|
echo "$fstab_line"
|
|
echo -n "Would you like to write this line to /etc/fstab? (y/N) "
|
|
read response
|
|
if [[ "$response" == 'y' ]] || [[ "$response" == 'Y' ]]; then
|
|
if [ ! -d /mnt/"$mnt_dir" ]; then
|
|
echo "Creating mount directory /mnt/$mnt_dir"
|
|
sudo mkdir "/mnt/$mnt_dir"
|
|
fi
|
|
echo "Writing volume mount to /etc/fstab"
|
|
echo "$fstab_line" | sudo tee -a /etc/fstab
|
|
fi
|
|
unset response
|
|
else
|
|
echo "Add lines to /etc/fstab for each share to mount:"
|
|
echo "//{SAMBA_HOST_IP}/{SAMBA_SHARE} /mnt/{MOUNT_DIR} cifs _netdev,nofail,x-systemd.automount,uid=`id -u`,gid=`id -g`,credentials=/etc/samba/credentials/$samba_host 0 0"
|
|
break
|
|
fi
|
|
done
|
|
fi
|
|
# Recurse in case another host needs setup
|
|
setup_samba
|
|
fi
|
|
echo
|
|
unset samba_host
|
|
}
|
|
|
|
function setup_ssh() {
|
|
echo
|
|
echo -n "Would you like to configure an SSH host? (y/N) "
|
|
read response
|
|
if [[ "$response" == 'y' ]] || [[ "$response" == 'Y' ]]; then
|
|
if [ ! -d "$HOME/.ssh" ]; then
|
|
mkdir "$HOME/.ssh"
|
|
fi
|
|
if [[ ! -f $HOME/.ssh/id_ed25519.pub ]]; then
|
|
echo "No SSH key found"
|
|
echo -n "Would you like to set up a new public/private key pair? (y/N) "
|
|
read response
|
|
if [[ "$response" == 'y' ]] || [[ "$response" == 'Y' ]]; then
|
|
ssh-keygen -t ed25519
|
|
echo
|
|
|
|
echo -n "Would you like to add this key to ssh-agent? (y/N) "
|
|
read response
|
|
if [[ "$response" == 'y' ]] || [[ "$response" == 'Y' ]]; then
|
|
ssh-add ~/.ssh/id_ed25519
|
|
fi
|
|
fi
|
|
echo
|
|
fi
|
|
echo -n "What host would you like to send public key to? (eg user@host, host if user is same) "
|
|
read ssh_host
|
|
if [[ "$ssh_host" != '' ]]; then
|
|
ssh-copy-id -i ~/.ssh/id_ed25519.pub "$ssh_host"
|
|
unset ssh_host
|
|
setup_ssh
|
|
fi
|
|
fi
|
|
}
|
|
|
|
function setup_coder() {
|
|
echo "Installing coder"
|
|
curl -L https://coder.com/install.sh | sh
|
|
coder login https://coderbox.branderson.io
|
|
coder config-ssh
|
|
}
|
|
|
|
function push_dotfiles() {
|
|
cd "$DOTFILES_DIR"
|
|
echo "Pushing dotfiles"
|
|
git add -A
|
|
git commit
|
|
git push origin master
|
|
}
|
|
|
|
function update_dotfiles() {
|
|
cd "$DOTFILES_DIR"
|
|
git pull origin master
|
|
}
|
|
|
|
function install_local() {
|
|
if [ -f "$DOTFILES_DIR/install_local.sh" ]; then
|
|
"$DOTFILES_DIR"/install_local.sh
|
|
else
|
|
echo "No file at install_local.sh, skipping local installation script."
|
|
fi
|
|
}
|
|
|
|
function list_options() {
|
|
if program_installed pacman; then
|
|
if program_installed yay; then
|
|
echo "[complete] Complete install (dotfiles, pacman, aur, flatpak, gem, pipx, system-configs, samba, local-install)"
|
|
else
|
|
echo "[complete] Complete install (dotfiles, pacman, flatpak, gem, pipx, system-configs, samba, local-install)"
|
|
fi
|
|
elif program_installed apt; then
|
|
echo "[complete] Complete install (dotfiles, apt, flatpak, gem, pipx, system-configs, samba, install-local)"
|
|
elif program_installed brew; then
|
|
echo "[complete] Complete install (dotfiles, brew, flatpak, gem, pipx, system-configs, samba,install-local)"
|
|
fi
|
|
echo "[dotfiles] Install dotfiles only"
|
|
echo "[dotfiles-local] Sync local dotfiles to git"
|
|
if program_installed pacman; then
|
|
echo "[programs] Install programs from all package managers (pacman, aur, flatpak, gem)"
|
|
elif program_installed apt; then
|
|
echo "[programs] Install programs from all package managers (apt, flatpak, gem)"
|
|
echo "[programs] Install programs from (apt) only"
|
|
elif program_installed brew; then
|
|
echo "[programs] Install programs from all package managers (brew, flatpak, gem)"
|
|
echo "[programs] Install programs (brew) only"
|
|
fi
|
|
if program_installed pacman; then
|
|
echo "[programs-main] Install main package manager (pacman) only"
|
|
if program_installed yay; then
|
|
echo "[programs-aur] Install AUR programs only"
|
|
fi
|
|
elif program_installed apt; then
|
|
echo "[programs-main] Install main package manager (apt) only"
|
|
elif program_installed brew; then
|
|
echo "[programs-main] Install main package manager (brew) only"
|
|
fi
|
|
if program_installed nvidia-smi; then
|
|
echo "[gpu-monitoring] Install nvidia-gpu-exporter"
|
|
fi
|
|
echo "[system-configs] Set up system configs only"
|
|
echo "[desktop-environment] Choose a desktop environment"
|
|
echo "[samba] Set up samba credentials only"
|
|
echo "[ssh] Set up SSH or send public key to host"
|
|
echo "[coder] Set up coder and login to coderbox"
|
|
echo "[install-local] Run local installer only ($DOTFILES_DIR/install_local.sh)"
|
|
echo "[push] Push to gitbox"
|
|
echo "[pull] Pull from gitbox"
|
|
echo "[quit] Quit"
|
|
}
|
|
|
|
function run_interactively() {
|
|
unset response
|
|
if [ -n "$1" ]; then
|
|
# Use the first CLI argument if provided
|
|
response="$1"
|
|
fi
|
|
if [ ! -n "$response" ]; then
|
|
list_options
|
|
echo ""
|
|
echo "What would you like to do?"
|
|
read response
|
|
fi
|
|
if [[ $response == "complete" ]]; then
|
|
link_dotfiles
|
|
install_main
|
|
install_flatpak
|
|
install_gem
|
|
install_pipx
|
|
echo ""
|
|
if program_installed yay; then
|
|
echo -n "Do you want to upgrade/install from AUR? (y/N) "
|
|
read response
|
|
if [[ $response == 'y' ]] || [[ $response == 'Y' ]]; then
|
|
install_aur
|
|
fi
|
|
fi
|
|
setup_system_configs
|
|
setup_samba
|
|
install_local
|
|
if [ "$#" -eq 0 ]; then
|
|
echo ""
|
|
run_interactively
|
|
fi
|
|
elif [[ $response == "push" ]]; then
|
|
push_dotfiles
|
|
if [ "$#" -eq 0 ]; then
|
|
echo ""
|
|
run_interactively
|
|
fi
|
|
elif [[ $response == "pull" ]]; then
|
|
update_dotfiles
|
|
if [ "$#" -eq 0 ]; then
|
|
echo ""
|
|
run_interactively
|
|
fi
|
|
elif [[ $response == "dotfiles" ]]; then
|
|
link_dotfiles
|
|
if [ "$#" -eq 0 ]; then
|
|
echo ""
|
|
run_interactively
|
|
fi
|
|
elif [[ $response == "dotfiles-local" ]]; then
|
|
link_dotfiles_local
|
|
if [ "$#" -eq 0 ]; then
|
|
echo ""
|
|
run_interactively
|
|
fi
|
|
elif [[ $response == "programs" ]]; then
|
|
install_main
|
|
install_flatpak
|
|
install_gem
|
|
install_pipx
|
|
if program_installed yay; then
|
|
echo ""
|
|
echo -n "Do you want to upgrade/install from AUR? (y/N) "
|
|
read response
|
|
if [[ $response == 'y' ]] || [[ $response == 'Y' ]]; then
|
|
install_aur
|
|
fi
|
|
fi
|
|
if [ "$#" -eq 0 ]; then
|
|
echo ""
|
|
run_interactively
|
|
fi
|
|
elif [[ $response == "programs-main" ]]; then
|
|
install_main
|
|
if [ "$#" -eq 0 ]; then
|
|
echo ""
|
|
run_interactively
|
|
fi
|
|
elif [[ $response == "aur-only" ]]; then
|
|
install_aur
|
|
if [ "$#" -eq 0 ]; then
|
|
echo ""
|
|
run_interactively
|
|
fi
|
|
elif [[ $response == "gpu-monitoring" ]]; then
|
|
install_gpu_monitoring
|
|
if [ "$#" -eq 0 ]; then
|
|
echo ""
|
|
run_interactively
|
|
fi
|
|
elif [[ $response == "system-configs" ]]; then
|
|
setup_system_configs
|
|
if [ "$#" -eq 0 ]; then
|
|
echo ""
|
|
run_interactively
|
|
fi
|
|
elif [[ $response == "desktop-environment" ]]; then
|
|
choose_desktop_environment
|
|
if [ "$#" -eq 0 ]; then
|
|
echo ""
|
|
run_interactively
|
|
fi
|
|
elif [[ $response == "samba" ]]; then
|
|
setup_samba
|
|
if [ "$#" -eq 0 ]; then
|
|
echo ""
|
|
run_interactively
|
|
fi
|
|
elif [[ $response = "ssh" ]]; then
|
|
setup_ssh
|
|
if [ "$#" -eq 0 ]; then
|
|
echo ""
|
|
run_interactively
|
|
fi
|
|
elif [[ $response = "coder" ]]; then
|
|
setup_coder
|
|
if [ "$#" -eq 0 ]; then
|
|
echo ""
|
|
run_interactively
|
|
fi
|
|
elif [[ $response == "install-local" ]]; then
|
|
install_local
|
|
if [ "$#" -eq 0 ]; then
|
|
echo ""
|
|
run_interactively
|
|
fi
|
|
elif [[ $response == "quit" ]]; then
|
|
exit 0
|
|
else
|
|
if [ "$#" -eq 0 ]; then
|
|
echo "Error: Please enter one of the supported options"
|
|
echo ""
|
|
run_interactively
|
|
else
|
|
echo ""
|
|
echo "Usage: dotfiles-install [option]"
|
|
echo "Options:"
|
|
list_options
|
|
exit 1
|
|
fi
|
|
fi
|
|
}
|
|
|
|
load_package_lists
|
|
|
|
cd "$DOTFILES_DIR"
|
|
|
|
echo "Updating submodules"
|
|
git submodule update --init
|
|
|
|
# Check if running interactively
|
|
if [ -t 0 ]; then
|
|
# Interactive session
|
|
interactive=1
|
|
run_interactively "$@"
|
|
else
|
|
# Non-interactive session (e.g. Coder workspace initialization)
|
|
link_dotfiles
|
|
link_dotfiles_local
|
|
cd -
|
|
fi
|
|
|