#!/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'