diff --git a/scripts/cleanup_i3_after_sway_migration.sh b/scripts/cleanup_i3_after_sway_migration.sh new file mode 100755 index 0000000..7b8b697 --- /dev/null +++ b/scripts/cleanup_i3_after_sway_migration.sh @@ -0,0 +1,242 @@ +#!/usr/bin/env sh + +set -eu + +APPLY=0 +AGGRESSIVE=0 + +SAFE_PACKAGES=" +arandr +autorandr +feh +i3 +i3blocks +i3blocks-blocklets +i3lock-color +i3status +scrot +setxkbmap +volumeicon +xclip +xkbutils +xorg-fonts +xorg-minimal +xss-lock +" + +AGGRESSIVE_PACKAGES=" +dunst +rofi +blueman +network-manager-applet +xfce-polkit +xfce4-clipman-plugin +xfce4-screenshooter +" + +SAFE_PATHS=" +$HOME/.config/i3 +$HOME/.config/i3blocks +$HOME/.config/autorandr +$HOME/.xinitrc +" + +AGGRESSIVE_PATHS=" +$HOME/.config/dunst +$HOME/.config/rofi +" + +usage() { + cat <<'EOF' +Usage: cleanup_i3_after_sway_migration.sh [--apply] [--aggressive] + +One-shot cleanup for removing i3/X11-only packages and dotfiles after a host +has already migrated to SwayFX + Noctalia. + +Options: + --apply perform the cleanup for real + --aggressive also remove extra desktop apps/configs that were mainly useful + in the old i3 setup (dunst, rofi, blueman, etc.) + -h, --help show this help + +Default mode is dry-run. +EOF +} + +have_command() { + command -v "$1" >/dev/null 2>&1 +} + +require_sway_noctalia() { + if [ ! -f "$HOME/.config/sway/config" ]; then + printf 'Error: Sway config not found at %s\n' "$HOME/.config/sway/config" >&2 + exit 1 + fi + + if [ ! -f "$HOME/.config/noctalia/settings.json" ]; then + printf 'Error: Noctalia settings not found at %s\n' "$HOME/.config/noctalia/settings.json" >&2 + exit 1 + fi +} + +append_lines() { + src_lines=$1 + dst_var=$2 + + for line in $src_lines; do + line=$(printf '%s' "$line" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//') + [ -n "$line" ] || continue + case "$dst_var" in + PACKAGES) + PACKAGES="$PACKAGES $line" + ;; + PATHS) + PATHS="$PATHS $line" + ;; + *) + printf 'Error: unsupported destination list: %s\n' "$dst_var" >&2 + exit 1 + ;; + esac + done +} + +filter_installed_packages() { + packages=$1 + installed='' + + for pkg in $packages; do + pkg=$(printf '%s' "$pkg" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//') + [ -n "$pkg" ] || continue + if xbps-query -s "$pkg" >/dev/null 2>&1; then + installed="$installed $pkg" + fi + done + + printf '%s' "$installed" +} + +filter_existing_paths() { + paths=$1 + existing='' + + for path in $paths; do + path=$(printf '%s' "$path" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//') + [ -n "$path" ] || continue + if [ -e "$path" ] || [ -L "$path" ]; then + existing="$existing $path" + fi + done + + printf '%s' "$existing" +} + +print_section() { + title=$1 + items=$2 + + printf '%s\n' "$title" + if [ -z "$items" ]; then + printf ' (none)\n' + return + fi + + for item in $items; do + item=$(printf '%s' "$item" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//') + [ -n "$item" ] || continue + printf ' - %s\n' "$item" + done +} + +confirm_apply() { + printf 'Proceed with i3 cleanup? [y/N] ' + IFS= read -r answer + case "$answer" in + y|Y|yes|YES) + ;; + *) + printf 'Aborted.\n' + exit 0 + ;; + esac +} + +run_remove_packages() { + packages=$1 + [ -n "$packages" ] || return 0 + + if [ "$(id -u)" -eq 0 ]; then + xbps-remove -R $packages + elif have_command sudo; then + sudo xbps-remove -R $packages + else + printf 'Error: package removal requires root and sudo was not found.\n' >&2 + exit 1 + fi +} + +run_remove_paths() { + paths=$1 + [ -n "$paths" ] || return 0 + + for path in $paths; do + path=$(printf '%s' "$path" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//') + [ -n "$path" ] || continue + rm -rf "$path" + done +} + +while [ $# -gt 0 ]; do + case "$1" in + --apply) + APPLY=1 + ;; + --aggressive) + AGGRESSIVE=1 + ;; + -h|--help) + usage + exit 0 + ;; + *) + printf 'Error: unknown argument: %s\n\n' "$1" >&2 + usage >&2 + exit 1 + ;; + esac + shift +done + +require_sway_noctalia + +PACKAGES='' +PATHS='' +append_lines "$SAFE_PACKAGES" PACKAGES +append_lines "$SAFE_PATHS" PATHS + +if [ "$AGGRESSIVE" -eq 1 ]; then + append_lines "$AGGRESSIVE_PACKAGES" PACKAGES + append_lines "$AGGRESSIVE_PATHS" PATHS +fi + +INSTALLED_PACKAGES=$(filter_installed_packages "$PACKAGES") +EXISTING_PATHS=$(filter_existing_paths "$PATHS") + +printf 'Mode: %s\n' "$( [ "$APPLY" -eq 1 ] && printf 'apply' || printf 'dry-run' )" +printf 'Aggressive cleanup: %s\n\n' "$( [ "$AGGRESSIVE" -eq 1 ] && printf 'yes' || printf 'no' )" + +print_section 'Packages to remove:' "$INSTALLED_PACKAGES" +printf '\n' +print_section 'Paths to remove:' "$EXISTING_PATHS" + +if [ "$APPLY" -ne 1 ]; then + printf '\nDry-run only. Re-run with --apply to perform the cleanup.\n' + exit 0 +fi + +confirm_apply + +run_remove_packages "$INSTALLED_PACKAGES" +run_remove_paths "$EXISTING_PATHS" + +printf '\nCleanup complete.\n'