From 62f1bd1b7586f0fd1777f724e4943bab8c130928 Mon Sep 17 00:00:00 2001 From: Hector van der Aa Date: Wed, 22 Apr 2026 18:50:10 +0200 Subject: [PATCH] V0.1.2 --- part1.sh | 471 ++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 345 insertions(+), 126 deletions(-) mode change 100755 => 100644 part1.sh diff --git a/part1.sh b/part1.sh old mode 100755 new mode 100644 index ed0cfe9..bac31c0 --- a/part1.sh +++ b/part1.sh @@ -1,13 +1,14 @@ -#!/bin/bash +#!/usr/bin/env bash set -euo pipefail -# ------------------------------- -# Helpers -# ------------------------------- info() { printf '\n==> %s\n' "$1" } +warn() { + printf 'WARN: %s\n' "$1" >&2 +} + append_if_missing() { local line="$1" local file="$2" @@ -15,17 +16,148 @@ append_if_missing() { grep -qxF "$line" "$file" || echo "$line" >>"$file" } -# ------------------------------- -# Paths and config -# ------------------------------- +command_exists() { + command -v "$1" >/dev/null 2>&1 +} + +prompt_yes_no() { + local prompt="$1" + local default="${2:-Y}" + local reply="" + + while true; do + if [[ "$default" == "Y" ]]; then + read -r -p "$prompt [Y/n] " reply + reply="${reply:-Y}" + else + read -r -p "$prompt [y/N] " reply + reply="${reply:-N}" + fi + + case "${reply,,}" in + y|yes) + return 0 + ;; + n|no) + return 1 + ;; + esac + done +} + +prompt_value() { + local prompt="$1" + local default="${2:-}" + local reply="" + + if [[ -n "$default" ]]; then + read -r -p "$prompt [$default] " reply + printf '%s' "${reply:-$default}" + else + read -r -p "$prompt " reply + printf '%s' "$reply" + fi +} + +prompt_required_value() { + local prompt="$1" + local default="${2:-}" + local value="" + + while true; do + value="$(prompt_value "$prompt" "$default")" + if [[ -n "$value" ]]; then + printf '%s' "$value" + return 0 + fi + done +} + +prompt_passphrase() { + local pass1="" + local pass2="" + + while true; do + read -r -s -p "Enter SSH key passphrase: " pass1 + printf '\n' + read -r -s -p "Confirm SSH key passphrase: " pass2 + printf '\n' + + if [[ "$pass1" == "$pass2" ]]; then + printf '%s' "$pass1" + return 0 + fi + + warn "Passphrases did not match. Try again." + done +} + +sanitize_slug() { + local value="$1" + value="${value,,}" + value="${value// /-}" + value="$(printf '%s' "$value" | tr -cd 'a-z0-9_-')" + printf '%s' "$value" +} + +extract_host_from_git_url() { + local url="$1" + + if [[ "$url" =~ ^ssh://([^/@]+@)?([^/:]+) ]]; then + printf '%s' "${BASH_REMATCH[2]}" + return 0 + fi + + if [[ "$url" =~ ^([^/@]+@)?([^:]+): ]]; then + printf '%s' "${BASH_REMATCH[2]}" + return 0 + fi + + if [[ "$url" =~ ^https?://([^/]+) ]]; then + printf '%s' "${BASH_REMATCH[1]}" + return 0 + fi + + return 1 +} + +install_pacman_package() { + local package="$1" + sudo pacman -S --needed --noconfirm "$package" +} + +install_yay() { + if command_exists yay; then + info "yay already installed" + return 0 + fi + + info "Installing yay" + git clone https://aur.archlinux.org/yay.git "$TMP_DIR/yay" + ( + cd "$TMP_DIR/yay" + makepkg -si --noconfirm + ) +} + +write_element_desktop_entry() { + local desktop_file="$1" + local display_name="$2" + local exec_line="$3" + + mkdir -p "$HOME_DIR/.local/share/applications" + cat >"$desktop_file" </dev/null 2>&1; then - info "Installing yay" - git clone https://aur.archlinux.org/yay.git "$TMP_DIR/yay" - ( - cd "$TMP_DIR/yay" - makepkg -si --noconfirm - ) -else - info "yay already installed" +info "Package selection" +for package in "${PACMAN_PACKAGES[@]}"; do + if prompt_yes_no "Install package '$package'?" "Y"; then + install_pacman_package "$package" + fi +done + +if prompt_yes_no "Install AUR helper 'yay'?" "Y"; then + install_yay fi -# ------------------------------- -# AUR packages -# ------------------------------- -info "Installing AUR packages" -yay -S --needed --noconfirm zen-browser-bin - -# ------------------------------- -# ble.sh -# ------------------------------- -if [ ! -f "$HOME_DIR/.local/share/blesh/ble.sh" ]; then - info "Installing ble.sh" - git clone --recursive --depth 1 --shallow-submodules https://github.com/akinomyoga/ble.sh.git "$TMP_DIR/ble.sh" - make -C "$TMP_DIR/ble.sh" install PREFIX="$HOME_DIR/.local" -else - info "ble.sh already installed" +if command_exists yay && prompt_yes_no "Install AUR package 'zen-browser-bin'?" "Y"; then + info "Installing zen-browser-bin" + yay -S --needed --noconfirm zen-browser-bin fi -append_if_missing 'source -- ~/.local/share/blesh/ble.sh' "$BASHRC" -touch ~/.blerc -echo '[ -f "$HOME/.config/blerc" ] && source "$HOME/.config/blerc"' >>~/.blerc -# ------------------------------- -# Shell setup -# ------------------------------- -info "Configuring shell" -append_if_missing 'eval "$(starship init bash)"' "$BASHRC" +if prompt_yes_no "Install ble.sh?" "Y"; then + if [[ ! -f "$HOME_DIR/.local/share/blesh/ble.sh" ]]; then + info "Installing ble.sh" + git clone --recursive --depth 1 --shallow-submodules https://github.com/akinomyoga/ble.sh.git "$TMP_DIR/ble.sh" + make -C "$TMP_DIR/ble.sh" install PREFIX="$HOME_DIR/.local" + else + info "ble.sh already installed" + fi + + append_if_missing 'source -- ~/.local/share/blesh/ble.sh' "$BASHRC" + touch "$HOME_DIR/.blerc" + append_if_missing '[ -f "$HOME/.config/blerc" ] && source "$HOME/.config/blerc"' "$HOME_DIR/.blerc" +fi + +if prompt_yes_no "Enable starship in ~/.bashrc?" "Y"; then + info "Configuring shell" + append_if_missing 'eval "$(starship init bash)"' "$BASHRC" +fi stty sane || true -# ------------------------------- -# Git setup -# ------------------------------- -info "Configuring git" -git config --global user.email "$SSH_KEY_EMAIL" -git config --global user.name "Hector van der Aa" - -# ------------------------------- -# SSH key setup for Gitea -# ------------------------------- -info "Preparing SSH key for git access" -mkdir -p "$HOME_DIR/.ssh" -chmod 700 "$HOME_DIR/.ssh" - -if [ ! -f "$SSH_KEY_PATH" ]; then - ssh-keygen -t ed25519 -C "$SSH_KEY_EMAIL" -f "$SSH_KEY_PATH" -N "" -else - info "SSH key already exists at $SSH_KEY_PATH, reusing it" +if prompt_yes_no "Configure global git identity?" "Y"; then + info "Configuring git" + git_name="$(prompt_required_value "Git user name:")" + git_email="$(prompt_required_value "Git user email:")" + git config --global user.name "$git_name" + git config --global user.email "$git_email" fi -chmod 600 "$SSH_KEY_PATH" -chmod 644 "$SSH_KEY_PATH.pub" +if prompt_yes_no "Create or reuse an SSH key for git access?" "Y"; then + info "Preparing SSH key" + ssh_key_path="$(prompt_required_value "SSH key path:" "$HOME_DIR/.ssh/id_ed25519")" + ssh_key_comment="$(prompt_required_value "SSH key comment/email:")" + mkdir -p "$HOME_DIR/.ssh" + chmod 700 "$HOME_DIR/.ssh" -if command -v ssh-keyscan >/dev/null 2>&1; then - touch "$HOME_DIR/.ssh/known_hosts" - ssh-keyscan -H git.h3cx.dev >>"$HOME_DIR/.ssh/known_hosts" 2>/dev/null || true + if [[ ! -f "$ssh_key_path" ]]; then + ssh_key_passphrase="" + if prompt_yes_no "Protect the SSH key with a passphrase?" "Y"; then + ssh_key_passphrase="$(prompt_passphrase)" + fi + + ssh-keygen -t ed25519 -C "$ssh_key_comment" -f "$ssh_key_path" -N "$ssh_key_passphrase" + else + info "SSH key already exists at $ssh_key_path, reusing it" + fi + + chmod 600 "$ssh_key_path" + chmod 644 "$ssh_key_path.pub" + + if prompt_yes_no "Add a git host to ~/.ssh/known_hosts?" "Y"; then + git_host="$(prompt_required_value "Git host (for ssh-keyscan):")" + if command_exists ssh-keyscan; then + touch "$HOME_DIR/.ssh/known_hosts" + ssh-keyscan -H "$git_host" >>"$HOME_DIR/.ssh/known_hosts" 2>/dev/null || true + fi + fi + + if prompt_yes_no "Copy the public SSH key to the clipboard?" "Y"; then + if command_exists wl-copy; then + wl-copy <"$ssh_key_path.pub" + info "Your public SSH key has been copied to the clipboard" + else + warn "wl-copy is not installed; printing the key instead" + cat "$ssh_key_path.pub" + fi + fi + + printf '\nPublic key: %s.pub\n' "$ssh_key_path" fi -if command -v wl-copy >/dev/null 2>&1; then - wl-copy <"$SSH_KEY_PATH.pub" - info "Your public SSH key has been copied to the clipboard" -else - info "wl-copy not found, public key is below" - cat "$SSH_KEY_PATH.pub" +if prompt_yes_no "Clone a dotfiles repository into ~/.config?" "Y"; then + info "Cloning dotfiles" + dotfiles_repo="$(prompt_required_value "Dotfiles repository URL:")" + config_target="$(prompt_required_value "Target config directory:" "$HOME_DIR/.config")" + + if [[ -d "$config_target" ]]; then + if prompt_yes_no "Back up the existing '$config_target' before replacing it?" "Y"; then + config_backup="${config_target}.backup.$(date +%Y%m%d-%H%M%S)" + mv "$config_target" "$config_backup" + info "Existing config moved to $config_backup" + elif prompt_yes_no "Delete the existing '$config_target' and replace it?" "N"; then + rm -rf "$config_target" + else + warn "Skipping dotfiles clone because target already exists" + dotfiles_repo="" + fi + fi + + if [[ -n "$dotfiles_repo" ]]; then + git clone "$dotfiles_repo" "$config_target" + + if prompt_yes_no "Add the dotfiles git host to ~/.ssh/known_hosts?" "Y"; then + if dotfiles_host="$(extract_host_from_git_url "$dotfiles_repo")"; then + mkdir -p "$HOME_DIR/.ssh" + touch "$HOME_DIR/.ssh/known_hosts" + ssh-keyscan -H "$dotfiles_host" >>"$HOME_DIR/.ssh/known_hosts" 2>/dev/null || true + else + warn "Could not determine a host from '$dotfiles_repo'" + fi + fi + fi fi -echo -echo "Add this SSH public key as an authorized key in your Gitea account:" -echo " $SSH_KEY_PATH.pub" -echo -read -rp "Press Enter once the key has been added to git.h3cx.dev... " +if prompt_yes_no "Clone a wallpapers repository?" "Y"; then + info "Cloning wallpapers" + wallpapers_repo="$(prompt_required_value "Wallpapers repository URL:")" + wallpaper_target="$(prompt_required_value "Wallpaper target directory:" "$HOME_DIR/.local/share/wallpapers")" -# ------------------------------- -# Clone private repositories -# ------------------------------- -info "Replacing ~/.config with HectorsDotFiles" -if [ -d "$HOME_DIR/.config" ]; then - mv "$HOME_DIR/.config" "$CONFIG_BACKUP" - info "Existing ~/.config moved to $CONFIG_BACKUP" + mkdir -p "$(dirname "$wallpaper_target")" + if [[ -d "$wallpaper_target" ]]; then + if prompt_yes_no "Delete the existing wallpaper directory '$wallpaper_target' first?" "Y"; then + rm -rf "$wallpaper_target" + else + warn "Skipping wallpapers clone because target already exists" + wallpapers_repo="" + fi + fi + + if [[ -n "$wallpapers_repo" ]]; then + git clone "$wallpapers_repo" "$wallpaper_target" + fi fi -git clone "$DOTFILES_REPO" "$HOME_DIR/.config" -info "Installing wallpapers repository" -mkdir -p "$HOME_DIR/.local/share" -rm -rf "$WALLPAPER_TARGET" -git clone "$WALLPAPERS_REPO" "$WALLPAPER_TARGET" +if prompt_yes_no "Create two custom Element desktop launchers?" "Y"; then + info "Creating Element desktop entries" + element_name_default="$(prompt_required_value "Name for the default Element profile launcher:")" + element_name_secondary="$(prompt_required_value "Name for the second Element profile launcher:")" + element_slug_default="$(sanitize_slug "$element_name_default")" + element_slug_secondary="$(sanitize_slug "$element_name_secondary")" + element_profile_secondary="$(prompt_required_value "Secondary Element profile id:" "profile1")" + + write_element_desktop_entry \ + "$HOME_DIR/.local/share/applications/element-${element_slug_default}.desktop" \ + "$element_name_default" \ + 'element-desktop --ozone-platform=x11' + + write_element_desktop_entry \ + "$HOME_DIR/.local/share/applications/element-${element_slug_secondary}.desktop" \ + "$element_name_secondary" \ + "element-desktop --profile $element_profile_secondary" + + update-desktop-database "$HOME_DIR/.local/share/applications" >/dev/null 2>&1 || true +fi + +if prompt_yes_no "Enable the sshd system service?" "Y"; then + info "Enabling sshd" + sudo systemctl enable --now sshd.service +fi + +if prompt_yes_no "Configure SDDM autologin?" "N"; then + info "Configuring SDDM autologin" + autologin_user="$(prompt_required_value "Autologin user:")" + autologin_session="$(prompt_required_value "Autologin session:" "hyprland-uwsm")" + sudo mkdir -p /etc/sddm.conf.d + sudo tee /etc/sddm.conf.d/autologin.conf >/dev/null </dev/null <<'EOF' -[Autologin] -User=hector -Session=hyprland-uwsm -EOF +printf 'You may want to restart your shell or run: source %s\n' "$BASHRC"