aboutsummaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
authorsrdusr <trevorgray@srdusr.com>2025-09-30 11:50:05 +0200
committersrdusr <trevorgray@srdusr.com>2025-09-30 11:50:05 +0200
commita6243585ba861c80d19f5f135170204e22bfc346 (patch)
tree0710801dd067d27e70988b7477a5aa06157b4d91 /common
parent8051e7846625a06b30baa15868631de286f7ee5d (diff)
downloaddotfiles-a6243585ba861c80d19f5f135170204e22bfc346.tar.gz
dotfiles-a6243585ba861c80d19f5f135170204e22bfc346.zip
Various changes, fixed .zshenv initializing properly, updated install.sh/packages.yml (testing shell-git invocation/make tmp and re-exec with bash)
Diffstat (limited to 'common')
-rwxr-xr-x[-rw-r--r--]common/.profile164
-rw-r--r--common/.zshenv2
-rw-r--r--common/.zshrc10
-rwxr-xr-xcommon/install.sh200
-rw-r--r--common/packages.yml14
5 files changed, 268 insertions, 122 deletions
diff --git a/common/.profile b/common/.profile
index b847d6c..53703b7 100644..100755
--- a/common/.profile
+++ b/common/.profile
@@ -1,102 +1,84 @@
#!/bin/bash
-
-#~/.profile
-
-# ======================================
-# Basic environment setup
-# ======================================
-
-export EDITOR="$(command -v nvim || command -v vim || echo nano)"
-
-# Load zsh env if running zsh
-if [ -n "$ZSH_VERSION" ] && [ -f "$HOME/.config/zsh/.zshenv" ]; then
- . "$HOME/.config/zsh/.zshenv"
-fi
-
-cd "$HOME" || exit 1
-
# ======================================
# Session launcher
# ======================================
-# Detect graphical DE session
-if [ -n "$DISPLAY" ]; then
- #echo "Graphical session detected ($XDG_SESSION_DESKTOP). Skipping auto TTY session launch."
- return
-fi
-
-# Only run on first virtual terminal
-if [ -z "$XDG_VTNR" ] || [ "$XDG_VTNR" -ne 1 ]; then
- return
-fi
-
-# Clean environment
-unset DISPLAY XAUTHORITY DBUS_SESSION_BUS_ADDRESS
-
-# Priority-ordered list of sessions (WM/DE)
-sessions=(
- "Hyprland"
- "bspwm"
- "sway"
- "gnome-session"
- "startplasma-x11"
- "startxfce4"
- "openbox"
- "i3"
-)
-
-# Handle saved session
-if [ -f "$HOME/.session" ]; then
- chosen_session=$(<"$HOME/.session")
- rm -f "$HOME/.session"
-fi
-
-# Start a session
start_session() {
- local s="$1"
- case "$s" in
- bspwm)
- export XDG_SESSION_TYPE="x11"
- exec startx /usr/bin/bspwm
- ;;
- Hyprland|sway)
- #exec dbus-launch --sh-syntax --exit-with-session "$s"
- exec dbus-launch --sh-syntax --exit-with-session "$s" >/dev/null 2>&1
- ;;
- gnome-session|startplasma-x11|startxfce4|openbox|i3)
- exec "$s"
- ;;
- *)
- return 1
- ;;
- esac
-}
-
-# Try saved session first
-if [ -n "$chosen_session" ]; then
- if start_session "$chosen_session"; then
- exit
- else
- echo "Saved session '$chosen_session' not found. Falling back..."
+ # Clean environment
+ unset DISPLAY XAUTHORITY DBUS_SESSION_BUS_ADDRESS
+
+ # Priority-ordered list of sessions (WM/DE)
+ sessions=(
+ "Hyprland"
+ "bspwm"
+ "sway"
+ "gnome-session"
+ "startplasma-x11"
+ "startxfce4"
+ "openbox"
+ "i3"
+ )
+
+ # Handle saved session
+ if [ -f "$HOME/.session" ]; then
+ chosen_session=$(<"$HOME/.session")
+ rm -f "$HOME/.session"
fi
-fi
-# Try default sessions in priority
-for wm in "${sessions[@]}"; do
- if command -v "$wm" >/dev/null 2>&1; then
- echo "Starting session: $wm"
- start_session "$wm"
- exit
+ launch_session() {
+ local s="$1"
+ case "$s" in
+ bspwm)
+ export XDG_SESSION_TYPE="x11"
+ exec startx /usr/bin/bspwm
+ ;;
+ Hyprland|sway)
+ exec dbus-launch --sh-syntax --exit-with-session "$s" >/dev/null 2>&1
+ ;;
+ gnome-session|startplasma-x11|startxfce4|openbox|i3)
+ exec "$s"
+ ;;
+ *)
+ return 1
+ ;;
+ esac
+ }
+
+ # Try saved session first
+ if [ -n "$chosen_session" ]; then
+ if launch_session "$chosen_session"; then
+ exit
+ else
+ echo "Saved session '$chosen_session' not found. Falling back..."
+ fi
fi
-done
-# Fallback: Check for common display managers (GDM/LightDM/SDDM)
-for dm in gdm lightdm sddm; do
- if command -v "$dm" >/dev/null 2>&1; then
- echo "Launching display manager: $dm"
- exec "$dm"
- fi
-done
+ # Try default sessions in priority
+ for wm in "${sessions[@]}"; do
+ if command -v "$wm" >/dev/null 2>&1; then
+ echo "Starting session: $wm"
+ launch_session "$wm"
+ exit
+ fi
+ done
+
+ # Fallback: Check for common display managers
+ for dm in gdm lightdm sddm; do
+ if command -v "$dm" >/dev/null 2>&1; then
+ echo "Launching display manager: $dm"
+ exec "$dm"
+ fi
+ done
+
+ echo "No suitable window manager or display manager found."
+ exit 1
+}
-echo "No suitable window manager or display manager found."
-exit 1
+# -------------------------
+# Only run session loader when:
+# - No DISPLAY (not inside an existing GUI)
+# - On first VT (tty1)
+# -------------------------
+if [ -z "$DISPLAY" ] && [ -n "$XDG_VTNR" ] && [ "$XDG_VTNR" -eq 1 ]; then
+ start_session
+fi
diff --git a/common/.zshenv b/common/.zshenv
new file mode 100644
index 0000000..12b221e
--- /dev/null
+++ b/common/.zshenv
@@ -0,0 +1,2 @@
+ZDOTDIR="$HOME/.config/zsh"
+source -- "$ZDOTDIR/.zshenv"
diff --git a/common/.zshrc b/common/.zshrc
deleted file mode 100644
index bd22e32..0000000
--- a/common/.zshrc
+++ /dev/null
@@ -1,10 +0,0 @@
-# ~/.zshrc
-[[ -f ~/.config/zsh/.zshrc ]] && source ~/.config/zsh/.zshrc
-
-# Point all zsh startup files to ~/.config/zsh
-export ZDOTDIR="$HOME/.config/zsh"
-
-# If you want, you can still source your real zshenv from there:
-if [[ -f "$ZDOTDIR/.zshenv" ]]; then
- source "$ZDOTDIR/.zshenv"
-fi
diff --git a/common/install.sh b/common/install.sh
index 6ef2787..4f531bf 100755
--- a/common/install.sh
+++ b/common/install.sh
@@ -4,10 +4,18 @@
# Created On: Tue 06 Sep 2025 16:20:52 PM CAT
# Project: Dotfiles installation script
-# TODO: allow optional change user/password, also optional change root password, first check if they are the same (auto)
-
# Dependencies: git, curl
+# POSIX-compatible shim: if not running under bash (e.g., invoked via `sh -c "$(curl ...)"`),
+# re-exec the remainder of this script with bash.
+if [ -z "${BASH_VERSION:-}" ]; then
+ tmp="$(mktemp)" || exit 1
+ # Read the rest of the script into a temp file, then exec bash on it
+ cat > "$tmp"
+ exec bash "$tmp" "$@"
+ exit 1
+fi
+
set -euo pipefail # Exit on error, undefined vars, pipe failures
#======================================
@@ -140,6 +148,7 @@ declare -A INSTALLATION_STEPS=(
["install_dependencies"]="Install dependencies"
["install_dotfiles"]="Install dotfiles repository"
["setup_user_dirs"]="Setup user directories"
+ ["setup_passwords"]="Setup user and root passwords (optional)"
["install_essentials"]="Install essential tools"
["install_packages"]="Install system packages"
["setup_shell"]="Setup shell environment"
@@ -159,6 +168,7 @@ STEP_ORDER=(
"install_dotfiles"
"deploy_config"
"setup_user_dirs"
+ "setup_passwords"
"install_essentials"
"install_packages"
"setup_shell"
@@ -525,7 +535,18 @@ detect_package_manager() {
# Find packages.yml in standard locations
local original_dir="$PWD"
cd "$HOME" 2>/dev/null || true
- local packages_files=("$PACKAGES_FILE" "common/$PACKAGES_FILE" ".cfg/common/$PACKAGES_FILE")
+ # Search common locations for packages.yml, including repo-local and script directory
+ local __script_dir
+ __script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)"
+ local packages_files=(
+ "$PACKAGES_FILE" \
+ "common/$PACKAGES_FILE" \
+ ".cfg/common/$PACKAGES_FILE" \
+ "$__script_dir/../packages.yml" \
+ "$__script_dir/packages.yml" \
+ "$DOTFILES_DIR/common/$PACKAGES_FILE" \
+ "$DOTFILES_DIR/packages.yml"
+ )
local found_packages_file=""
for pf in "${packages_files[@]}"; do
if [[ -f "$pf" ]]; then
@@ -535,17 +556,54 @@ detect_package_manager() {
done
cd "$original_dir" 2>/dev/null || true
+ # Optionally merge a profile overlay packages.yml over the base file
+ local merged_packages_file=""
if command_exists yq && [[ -n "$found_packages_file" ]]; then
+ local overlay_candidates=(
+ "$HOME/.cfg/profile/$INSTALL_MODE/packages.yml"
+ "$HOME/profile/$INSTALL_MODE/packages.yml"
+ "$__script_dir/../profile/$INSTALL_MODE/packages.yml"
+ "$__script_dir/profile/$INSTALL_MODE/packages.yml"
+ "$DOTFILES_DIR/profile/$INSTALL_MODE/packages.yml"
+ )
+ local overlay_file=""
+ for opf in "${overlay_candidates[@]}"; do
+ [[ -f "$opf" ]] && { overlay_file="$opf"; break; }
+ done
+ if [[ -n "$overlay_file" ]]; then
+ merged_packages_file="$(mktemp)"
+ if yq eval-all 'select(fileIndex==0) * select(fileIndex==1)' "$found_packages_file" "$overlay_file" >"$merged_packages_file" 2>/dev/null; then
+ print_info "Using merged packages.yml (base + profile overlay: $INSTALL_MODE)"
+ else
+ print_warning "Failed to merge profile packages overlay; using base packages.yml"
+ rm -f "$merged_packages_file" 2>/dev/null || true
+ merged_packages_file=""
+ fi
+ fi
+ fi
+
+ # If we have a resolved file, set PACKAGES_FILE to its absolute path for downstream steps
+ if [[ -n "$found_packages_file" ]]; then
+ if [[ -n "$merged_packages_file" ]]; then
+ PACKAGES_FILE="$merged_packages_file"
+ else
+ # Canonical absolute path
+ PACKAGES_FILE="$(cd "$(dirname "$found_packages_file")" && pwd -P)/$(basename "$found_packages_file")"
+ fi
+ export PACKAGES_FILE
+ fi
+
+ if command_exists yq && [[ -n "${merged_packages_file:-$found_packages_file}" ]]; then
# Prefer distro block, fallback to manager block
# Initialize to avoid set -u (nounset) issues before assignment
local pm_update="" pm_install=""
if [[ -n "$DISTRO" ]]; then
- pm_update=$(yq eval ".package_managers.${DISTRO}.update" "$found_packages_file" 2>/dev/null | grep -v "^null$" || echo "")
- pm_install=$(yq eval ".package_managers.${DISTRO}.install" "$found_packages_file" 2>/dev/null | grep -v "^null$" || echo "")
+ pm_update=$(yq eval ".package_managers.${DISTRO}.update" "${merged_packages_file:-$found_packages_file}" 2>/dev/null | grep -v "^null$" || echo "")
+ pm_install=$(yq eval ".package_managers.${DISTRO}.install" "${merged_packages_file:-$found_packages_file}" 2>/dev/null | grep -v "^null$" || echo "")
fi
if [[ -z "$pm_update" || -z "$pm_install" ]]; then
- pm_update=$(yq eval ".package_managers.${PACKAGE_MANAGER}.update" "$found_packages_file" 2>/dev/null | grep -v "^null$" || echo "")
- pm_install=$(yq eval ".package_managers.${PACKAGE_MANAGER}.install" "$found_packages_file" 2>/dev/null | grep -v "^null$" || echo "")
+ pm_update=$(yq eval ".package_managers.${PACKAGE_MANAGER}.update" "${merged_packages_file:-$found_packages_file}" 2>/dev/null | grep -v "^null$" || echo "")
+ pm_install=$(yq eval ".package_managers.${PACKAGE_MANAGER}.install" "${merged_packages_file:-$found_packages_file}" 2>/dev/null | grep -v "^null$" || echo "")
fi
if [[ -n "$pm_update" && -n "$pm_install" ]]; then
PACKAGE_UPDATE_CMD="$pm_update"
@@ -2110,6 +2168,119 @@ setup_user_dirs() {
mark_step_completed "setup_user_dirs"
}
+setup_passwords() {
+ print_section "Setting Up Passwords (Optional)"
+ save_state "setup_passwords" "started"
+
+ if [[ "$ASK_MODE" != true && "$FORCE_MODE" != true ]]; then
+ print_info "Skipping password setup (non-interactive). Use --ask to be prompted."
+ mark_step_completed "setup_passwords"
+ return 0
+ fi
+
+ # Change current user password
+ if prompt_user "Change password for user '$USER'?" "N"; then
+ print_color "$YELLOW" "Enter new password for $USER: "
+ read -rs __pw_user; echo
+ print_color "$YELLOW" "Confirm new password for $USER: "
+ read -rs __pw_user2; echo
+ if [[ "$__pw_user" == "$__pw_user2" && -n "$__pw_user" ]]; then
+ if execute_with_privilege "bash -lc 'echo \"$USER:$__pw_user\" | chpasswd'"; then
+ print_success "Password updated for $USER"
+ else
+ print_error "Failed to update password for $USER"
+ fi
+ else
+ print_warning "Passwords did not match; skipping $USER"
+ fi
+ unset __pw_user __pw_user2
+ else
+ print_skip "User password change (skipped)"
+ fi
+
+ # Change root password
+ if prompt_user "Change password for 'root'?" "N"; then
+ print_color "$YELLOW" "Enter new password for root: "
+ read -rs __pw_root; echo
+ print_color "$YELLOW" "Confirm new password for root: "
+ read -rs __pw_root2; echo
+ if [[ "$__pw_root" == "$__pw_root2" && -n "$__pw_root" ]]; then
+ if execute_with_privilege "bash -lc 'echo \"root:$__pw_root\" | chpasswd'"; then
+ print_success "Password updated for root"
+ else
+ print_error "Failed to update password for root"
+ fi
+ else
+ print_warning "Passwords did not match; skipping root"
+ fi
+ unset __pw_root __pw_root2
+ else
+ print_skip "Root password change (skipped)"
+ fi
+
+ mark_step_completed "setup_passwords"
+}
+
+# Safely sync a system file with backup. Usage: sync_system_file_with_backup /etc/target /path/to/source
+sync_system_file_with_backup() {
+ local target="$1" src="$2"
+ if [[ -z "$target" || -z "$src" ]]; then
+ print_error "sync_system_file_with_backup: missing arguments"
+ return 1
+ fi
+ if [[ ! -f "$src" ]]; then
+ print_error "Source file not found: $src"
+ return 1
+ fi
+ local backup="${target}.bak.$(date +%Y%m%d-%H%M%S)"
+ run_privileged "mkdir -p '$(dirname "$target")'" || return 1
+ if run_privileged "test -f '$target'"; then
+ run_privileged "cp -a '$target' '$backup'" || return 1
+ print_info "Backed up $target to $backup"
+ fi
+ run_privileged "install -m 644 '$src' '$target'" && print_success "Updated $target"
+}
+
+# Pre-install essentials (git, curl) early if missing
+preinstall_essentials() {
+ local need_any=false
+ command_exists git || need_any=true
+ command_exists curl || need_any=true
+ if [[ "$need_any" != true ]]; then
+ return 0
+ fi
+ detect_os
+ detect_package_manager || return 1
+ update_package_database || true
+ local ok=true
+ command_exists git || install_single_package git dependency || ok=false
+ command_exists curl || install_single_package curl dependency || ok=false
+ [[ "$ok" == true ]]
+}
+
+## Privileged file helpers (Utility)
+# Ensure a line exists in a file (exact match). Creates file and parent dir if needed. Uses privilege.
+ensure_line_in_file_privileged() {
+ local file="$1"
+ local line="$2"
+
+ # Create parent dir if needed
+ local dir
+ dir="$(dirname "$file")"
+ run_privileged "mkdir -p '$dir'" || return 1
+
+ # Create file if missing
+ run_privileged "touch '$file'" || return 1
+
+ # Check exact line presence
+ if run_privileged "grep -Fqx -- '$(printf %s "$line" | sed "s/'/'\\''/g")' '$file'"; then
+ return 0
+ fi
+
+ # Append safely
+ run_privileged "printf '%s\n' '$(printf %s "$line" | sed "s/'/'\\''/g")' >> '$file'"
+}
+
install_essentials() {
print_section "Installing Essential Tools"
save_state "install_essentials" "started"
@@ -2351,8 +2522,6 @@ setup_shell() {
mark_step_completed "setup_shell"
}
-## install_zsh_plugins deprecated; handled via packages.yml
-
setup_ssh() {
print_section "Setting Up SSH"
save_state "setup_ssh" "started"
@@ -3718,13 +3887,14 @@ trap handle_interrupt INT
# Execute main if script is run directly
if [[ "${BASH_SOURCE[0]-}" == "$0" ]]; then
- # Check basic requirements
- for req in git curl; do
- if ! command_exists "$req"; then
- print_error "$req is required but not installed"
+ # Ensure basic requirements (attempt auto-install if possible)
+ if ! command_exists git || ! command_exists curl; then
+ print_warning "git/curl missing; attempting to install prerequisites"
+ preinstall_essentials || {
+ print_error "Required tools git/curl are not installed and could not be auto-installed"
exit 1
- fi
- done
+ }
+ fi
main "$@"
fi
diff --git a/common/packages.yml b/common/packages.yml
index 0fce986..2aa435f 100644
--- a/common/packages.yml
+++ b/common/packages.yml
@@ -1,6 +1,10 @@
# Dotfiles Installation Packages Configuration
# This file defines packages to install based on installation profiles and distribution-specific mappings
+# TODO:
+# tree-sitter-cli
+# make sure rust is installed, go pipx virtualenvwrapper
+
#======================================
# Installation Profiles
#======================================
@@ -214,7 +218,6 @@ fedora:
hdparm: hdparm
acpi: acpi
parted: parted
- cups: cups
sysstat: sysstat
hwinfo: hwinfo
@@ -254,7 +257,6 @@ rhel:
hdparm: hdparm
acpi: acpi
parted: parted
- cups: cups
sysstat: sysstat
opensuse:
@@ -319,7 +321,6 @@ gentoo:
hdparm: sys-apps/hdparm
acpi: sys-power/acpi
parted: sys-block/parted
- cups: net-print/cups
sysstat: app-admin/sysstat
hwinfo: sys-apps/hwinfo
hack-font: media-fonts/hack
@@ -553,11 +554,11 @@ gentoo_use_flags:
openssh: "ssl kerberos ldap pam"
firefox: "dbus gtk3 pulseaudio startup-notification wifi"
mpv: "alsa pulseaudio lua drm wayland X"
- gtk: "wayland X cups introspection"
+ gtk: "wayland X introspection"
pipewire: "alsa bluetooth jack pulseaudio sound-server"
ffmpeg: "alsa encode mp3 opus pulseaudio theora vorbis webp x264 x265"
networkmanager: "bluetooth dhclient introspection wifi"
- bluez: "alsa cups obex readline"
+ bluez: "alsa obex readline"
qemu: "aio alsa bluetooth curl gtk jpeg ncurses opengl png pulseaudio sdl spice ssh usb vnc"
libvirt: "firewalld libssh nfs numa parted qemu sasl udev"
@@ -814,7 +815,6 @@ services:
- chronyd
desktop:
- bluetooth
- - cups
disable:
server:
- bluetooth
@@ -845,9 +845,11 @@ development:
- typescript
- eslint
- prettier
+ - tree-sitter-cli
python:
global_packages:
+ - pipx
- black
- flake8
- mypy