aboutsummaryrefslogtreecommitdiffstats
path: root/scripts/lib_copy.sh
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/lib_copy.sh')
-rw-r--r--scripts/lib_copy.sh299
1 files changed, 228 insertions, 71 deletions
diff --git a/scripts/lib_copy.sh b/scripts/lib_copy.sh
index fa1231c5..331c6906 100644
--- a/scripts/lib_copy.sh
+++ b/scripts/lib_copy.sh
@@ -12,25 +12,30 @@ copy_phase1() {
echo -n "${CAT:-[ACTION]} Do you want to replace ${YELLOW:-}$DIR2${RESET:-} config? (y/n): "
read DIR1_CHOICE
case "$DIR1_CHOICE" in
- [Yy]*) BACKUP_DIR=$(get_backup_dirname)
- mv "$DIRPATH" "$DIRPATH-backup-$BACKUP_DIR" 2>&1 | tee -a "$log"
- echo -e "${NOTE:-[NOTE]} - Backed up $DIR2 to $DIRPATH-backup-$BACKUP_DIR." 2>&1 | tee -a "$log"
- cp -r "config/$DIR2" "$HOME/.config/$DIR2" 2>&1 | tee -a "$log"
- echo -e "${OK:-[OK]} - Replaced $DIR2 with new configuration." 2>&1 | tee -a "$log"
- if [ "$DIR2" = "rofi" ]; then
- if [ -d "$DIRPATH-backup-$BACKUP_DIR/themes" ]; then
- for file in "$DIRPATH-backup-$BACKUP_DIR/themes"/*; do
- [ -e "$file" ] || continue
- cp -n "$file" "$HOME/.config/rofi/themes/" >>"$log" 2>&1 || true
- done || true
- fi
- if [ -f "$DIRPATH-backup-$BACKUP_DIR/0-shared-fonts.rasi" ]; then
- cp "$DIRPATH-backup-$BACKUP_DIR/0-shared-fonts.rasi" "$HOME/.config/rofi/0-shared-fonts.rasi" >>"$log" 2>&1
- fi
- fi
- break ;;
- [Nn]*) echo -e "${NOTE:-[NOTE]} - Skipping ${YELLOW:-}$DIR2${RESET:-}" 2>&1 | tee -a "$log"; break ;;
- *) echo -e "${WARN:-[WARN]} - Invalid choice. Please enter Y or N." ;;
+ [Yy]*)
+ BACKUP_DIR=$(get_backup_dirname)
+ mv "$DIRPATH" "$DIRPATH-backup-$BACKUP_DIR" 2>&1 | tee -a "$log"
+ echo -e "${NOTE:-[NOTE]} - Backed up $DIR2 to $DIRPATH-backup-$BACKUP_DIR." 2>&1 | tee -a "$log"
+ cp -r "config/$DIR2" "$HOME/.config/$DIR2" 2>&1 | tee -a "$log"
+ echo -e "${OK:-[OK]} - Replaced $DIR2 with new configuration." 2>&1 | tee -a "$log"
+ if [ "$DIR2" = "rofi" ]; then
+ if [ -d "$DIRPATH-backup-$BACKUP_DIR/themes" ]; then
+ for file in "$DIRPATH-backup-$BACKUP_DIR/themes"/*; do
+ [ -e "$file" ] || continue
+ cp -n "$file" "$HOME/.config/rofi/themes/" >>"$log" 2>&1 || true
+ done || true
+ fi
+ if [ -f "$DIRPATH-backup-$BACKUP_DIR/0-shared-fonts.rasi" ]; then
+ cp "$DIRPATH-backup-$BACKUP_DIR/0-shared-fonts.rasi" "$HOME/.config/rofi/0-shared-fonts.rasi" >>"$log" 2>&1
+ fi
+ fi
+ break
+ ;;
+ [Nn]*)
+ echo -e "${NOTE:-[NOTE]} - Skipping ${YELLOW:-}$DIR2${RESET:-}" 2>&1 | tee -a "$log"
+ break
+ ;;
+ *) echo -e "${WARN:-[WARN]} - Invalid choice. Please enter Y or N." ;;
esac
done
else
@@ -49,47 +54,52 @@ copy_waybar() {
echo -n "${CAT:-[ACTION]} Do you want to replace ${YELLOW:-}$DIRW${RESET:-} config? (y/n): "
read DIR1_CHOICE
case "$DIR1_CHOICE" in
- [Yy]*) BACKUP_DIR=$(get_backup_dirname)
- cp -r "$DIRPATHw" "$DIRPATHw-backup-$BACKUP_DIR" 2>&1 | tee -a "$log"
- echo -e "${NOTE:-[NOTE]} - Backed up $DIRW to $DIRPATHw-backup-$BACKUP_DIR." 2>&1 | tee -a "$log"
- rm -rf "$DIRPATHw" && cp -r "config/$DIRW" "$DIRPATHw" 2>&1 | tee -a "$log"
- for file in "config" "style.css"; do
- symlink="$DIRPATHw-backup-$BACKUP_DIR/$file"
- target_file="$DIRPATHw/$file"
- if [ -L "$symlink" ]; then
- symlink_target=$(readlink "$symlink")
- if [ -f "$symlink_target" ]; then
- rm -f "$target_file" && cp -f "$symlink_target" "$target_file"
- fi
- fi
- done
- for dir in "$DIRPATHw-backup-$BACKUP_DIR/configs"/*; do
- [ -e "$dir" ] || continue
- if [ -d "$dir" ]; then
- target_dir="$HOME/.config/waybar/configs/$(basename "$dir")"
- [ -d "$target_dir" ] || cp -r "$dir" "$HOME/.config/waybar/configs/"
- fi
- done
- for file in "$DIRPATHw-backup-$BACKUP_DIR/configs"/*; do
- [ -e "$file" ] || continue
- target_file="$HOME/.config/waybar/configs/$(basename "$file")"
- [ -e "$target_file" ] || cp "$file" "$HOME/.config/waybar/configs/"
- done || true
- for file in "$DIRPATHw-backup-$BACKUP_DIR/style"/*; do
- [ -e "$file" ] || continue
- if [ -d "$file" ]; then
- target_dir="$HOME/.config/waybar/style/$(basename "$file")"
- [ -d "$target_dir" ] || cp -r "$file" "$HOME/.config/waybar/style/"
- else
- target_file="$HOME/.config/waybar/style/$(basename "$file")"
- [ -e "$target_file" ] || cp "$file" "$HOME/.config/waybar/style/"
- fi
- done || true
- BACKUP_FILEw="$DIRPATHw-backup-$BACKUP_DIR/UserModules"
- [ -f "$BACKUP_FILEw" ] && cp -f "$BACKUP_FILEw" "$DIRPATHw/UserModules"
- break ;;
- [Nn]*) echo -e "${NOTE:-[NOTE]} - Skipping ${YELLOW:-}$DIRW${RESET:-} config replacement." 2>&1 | tee -a "$log"; break ;;
- *) echo -e "${WARN:-[WARN]} - Invalid choice. Please enter Y or N." ;;
+ [Yy]*)
+ BACKUP_DIR=$(get_backup_dirname)
+ cp -r "$DIRPATHw" "$DIRPATHw-backup-$BACKUP_DIR" 2>&1 | tee -a "$log"
+ echo -e "${NOTE:-[NOTE]} - Backed up $DIRW to $DIRPATHw-backup-$BACKUP_DIR." 2>&1 | tee -a "$log"
+ rm -rf "$DIRPATHw" && cp -r "config/$DIRW" "$DIRPATHw" 2>&1 | tee -a "$log"
+ for file in "config" "style.css"; do
+ symlink="$DIRPATHw-backup-$BACKUP_DIR/$file"
+ target_file="$DIRPATHw/$file"
+ if [ -L "$symlink" ]; then
+ symlink_target=$(readlink "$symlink")
+ if [ -f "$symlink_target" ]; then
+ rm -f "$target_file" && cp -f "$symlink_target" "$target_file"
+ fi
+ fi
+ done
+ for dir in "$DIRPATHw-backup-$BACKUP_DIR/configs"/*; do
+ [ -e "$dir" ] || continue
+ if [ -d "$dir" ]; then
+ target_dir="$HOME/.config/waybar/configs/$(basename "$dir")"
+ [ -d "$target_dir" ] || cp -r "$dir" "$HOME/.config/waybar/configs/"
+ fi
+ done
+ for file in "$DIRPATHw-backup-$BACKUP_DIR/configs"/*; do
+ [ -e "$file" ] || continue
+ target_file="$HOME/.config/waybar/configs/$(basename "$file")"
+ [ -e "$target_file" ] || cp "$file" "$HOME/.config/waybar/configs/"
+ done || true
+ for file in "$DIRPATHw-backup-$BACKUP_DIR/style"/*; do
+ [ -e "$file" ] || continue
+ if [ -d "$file" ]; then
+ target_dir="$HOME/.config/waybar/style/$(basename "$file")"
+ [ -d "$target_dir" ] || cp -r "$file" "$HOME/.config/waybar/style/"
+ else
+ target_file="$HOME/.config/waybar/style/$(basename "$file")"
+ [ -e "$target_file" ] || cp "$file" "$HOME/.config/waybar/style/"
+ fi
+ done || true
+ BACKUP_FILEw="$DIRPATHw-backup-$BACKUP_DIR/UserModules"
+ [ -f "$BACKUP_FILEw" ] && cp -f "$BACKUP_FILEw" "$DIRPATHw/UserModules"
+ break
+ ;;
+ [Nn]*)
+ echo -e "${NOTE:-[NOTE]} - Skipping ${YELLOW:-}$DIRW${RESET:-} config replacement." 2>&1 | tee -a "$log"
+ break
+ ;;
+ *) echo -e "${WARN:-[WARN]} - Invalid choice. Please enter Y or N." ;;
esac
done
else
@@ -187,9 +197,140 @@ compose_overlay_from_backup() {
fi
}
+cleanup_duplicate_userconfigs() {
+ local current_version="$1"
+ local log="$2"
+
+ if [ -z "$current_version" ]; then
+ return
+ fi
+
+ # Run de-dupe only for existing installs up to and including v2.3.19.
+ # For v2.3.20 and newer, the underlying duplication bug is fixed and
+ # this cleanup is no longer needed (and might mask future issues).
+ if version_gte "$current_version" "2.3.20"; then
+ echo "${INFO:-[INFO]} Skipping UserConfigs duplicate cleanup for detected version v$current_version (>= 2.3.20)." 2>&1 | tee -a "$log"
+ return
+ fi
+
+ echo "${INFO:-[INFO]} Running UserConfigs duplicate cleanup for detected version v$current_version (<= 2.3.19)." 2>&1 | tee -a "$log"
+
+ local HYPR_DIR="$HOME/.config/hypr"
+ local BASE_DIR="$HYPR_DIR/configs"
+ local USER_DIR="$HYPR_DIR/UserConfigs"
+
+ local STARTUP_BASE="$BASE_DIR/Startup_Apps.conf"
+ local STARTUP_USER="$USER_DIR/Startup_Apps.conf"
+ local WINDOW_BASE="$BASE_DIR/WindowRules.conf"
+ local WINDOW_USER="$USER_DIR/WindowRules.conf"
+ local KEYBINDS_BASE="$BASE_DIR/Keybinds.conf"
+ local KEYBINDS_USER="$USER_DIR/UserKeybinds.conf"
+
+ # Startup_Apps: strip exec-once lines from UserConfigs that are exact
+ # duplicates of the base Startup_Apps.conf.
+ if [ -f "$STARTUP_BASE" ] && [ -f "$STARTUP_USER" ]; then
+ local tmp_startup
+ local backup_startup
+ backup_startup="$STARTUP_USER.backup-dupfix-$(date +%Y%m%d-%H%M%S)"
+ tmp_startup=$(mktemp)
+ awk '
+ function trim(s){ gsub(/^[ \t]+|[ \t]+$/, "", s); return s }
+ FNR==NR {
+ if ($0 ~ /^[ \t]*exec-once[ \t]*=/) {
+ line=trim($0)
+ base[line]=1
+ }
+ next
+ }
+ {
+ if ($0 ~ /^[ \t]*exec-once[ \t]*=/) {
+ line=trim($0)
+ if (line in base) next
+ }
+ print
+ }
+ ' "$STARTUP_BASE" "$STARTUP_USER" >"$tmp_startup"
+ if ! cmp -s "$STARTUP_USER" "$tmp_startup"; then
+ cp "$STARTUP_USER" "$backup_startup"
+ mv "$tmp_startup" "$STARTUP_USER"
+ echo "${NOTE:-[NOTE]} - Removed duplicate Startup_Apps entries matching base config." 2>&1 | tee -a "$log"
+ else
+ rm -f "$tmp_startup"
+ fi
+ fi
+
+ # WindowRules: strip windowrule/layerrule lines from UserConfigs that
+ # are exact duplicates of the base WindowRules.conf.
+ if [ -f "$WINDOW_BASE" ] && [ -f "$WINDOW_USER" ]; then
+ local tmp_window
+ local backup_window
+ backup_window="$WINDOW_USER.backup-dupfix-$(date +%Y%m%d-%H%M%S)"
+ tmp_window=$(mktemp)
+ awk '
+ function trim(s){ gsub(/^[ \t]+|[ \t]+$/, "", s); return s }
+ FNR==NR {
+ if ($0 ~ /^[ \t]*(windowrule|layerrule)[ \t]*=/) {
+ line=trim($0)
+ base[line]=1
+ }
+ next
+ }
+ {
+ if ($0 ~ /^[ \t]*(windowrule|layerrule)[ \t]*=/) {
+ line=trim($0)
+ if (line in base) next
+ }
+ print
+ }
+ ' "$WINDOW_BASE" "$WINDOW_USER" >"$tmp_window"
+ if ! cmp -s "$WINDOW_USER" "$tmp_window"; then
+ cp "$WINDOW_USER" "$backup_window"
+ mv "$tmp_window" "$WINDOW_USER"
+ echo "${NOTE:-[NOTE]} - Removed duplicate WindowRules entries matching base config." 2>&1 | tee -a "$log"
+ else
+ rm -f "$tmp_window"
+ fi
+ fi
+
+ # Keybinds: strip bind* lines from UserKeybinds.conf that are exact
+ # duplicates of the base Keybinds.conf. Comments and unbinds are kept.
+ if [ -f "$KEYBINDS_BASE" ] && [ -f "$KEYBINDS_USER" ]; then
+ local tmp_keybinds
+ local backup_keybinds
+ backup_keybinds="$KEYBINDS_USER.backup-dupfix-$(date +%Y%m%d-%H%M%S)"
+ tmp_keybinds=$(mktemp)
+ awk '
+ function trim(s){ gsub(/^[ \t]+|[ \t]+$/, "", s); return s }
+ FNR==NR {
+ # Match any Hyprland bind variant: bindd, bindmd, bindld, binded,
+ # bindlnd, bindeld, etc.
+ if ($0 ~ /^[ \t]*bind[a-z]*[ \t]*=/) {
+ line=trim($0)
+ base[line]=1
+ }
+ next
+ }
+ {
+ if ($0 ~ /^[ \t]*bind[a-z]*[ \t]*=/) {
+ line=trim($0)
+ if (line in base) next
+ }
+ print
+ }
+ ' "$KEYBINDS_BASE" "$KEYBINDS_USER" >"$tmp_keybinds"
+ if ! cmp -s "$KEYBINDS_USER" "$tmp_keybinds"; then
+ cp "$KEYBINDS_USER" "$backup_keybinds"
+ mv "$tmp_keybinds" "$KEYBINDS_USER"
+ echo "${NOTE:-[NOTE]} - Removed duplicate UserKeybinds entries matching base Keybinds.conf." 2>&1 | tee -a "$log"
+ else
+ rm -f "$tmp_keybinds"
+ fi
+ fi
+}
restore_user_configs() {
local log="$1"
local express_mode="$2"
+ local old_version="$3"
local DIRPATH="$HOME/.config/hypr"
local BACKUP_DIR
@@ -201,29 +342,32 @@ restore_user_configs() {
exit 1
fi
+ # In express mode we still want to run the de-dupe logic, but we skip
+ # the interactive restoration prompts so the workflow stays non-blocking.
+ local SKIP_RESTORE_PROMPTS=0
if [ -d "$BACKUP_DIR_PATH" ] && [ "$express_mode" -eq 1 ]; then
echo "${NOTE:-[NOTE]} Express mode: skipping UserConfigs restoration prompts." 2>&1 | tee -a "$log"
- return
+ SKIP_RESTORE_PROMPTS=1
fi
- if [ -d "$BACKUP_DIR_PATH" ] && [ "$express_mode" -eq 0 ]; then
+ if [ -d "$BACKUP_DIR_PATH" ] && [ "$SKIP_RESTORE_PROMPTS" -eq 0 ]; then
local VERSION_FILE
VERSION_FILE=$(find "$DIRPATH" -maxdepth 1 -name "v*.*.*" | head -n 1)
local CURRENT_VERSION="999.9.9"
- if [ -n "$VERSION_FILE" ]; then
- CURRENT_VERSION=$(basename "$VERSION_FILE" | sed 's/^v//')
+ if [ -n "$old_version" ]; then
+ CURRENT_VERSION="$old_version"
fi
local TARGET_VERSION="2.3.19"
echo -e "${NOTE:-[NOTE]} Restoring previous ${MAGENTA:-}User-Configs${RESET:-}... " 2>&1 | tee -a "$log"
- printf "${WARNING:-}\
- █▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀█\n\
- NOTES for RESTORING PREVIOUS CONFIGS\n\
- █▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄█\n\n\
- The 'UserConfigs' directory is for all your personal settings.\n\
- Files in this directory will override the default configurations,\n\
- so your customizations are not lost when you update.\n\
+ printf "${WARNING:-}\\
+ █▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀█\\n\\
+ NOTES for RESTORING PREVIOUS CONFIGS\\n\\
+ █▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄█\\n\\n\\
+ The 'UserConfigs' directory is for all your personal settings.\\n\\
+ Files in this directory will override the default configurations,\\n\\
+ so your customizations are not lost when you update.\\n\\
" >&2
if version_gte "$CURRENT_VERSION" "$TARGET_VERSION"; then
@@ -281,6 +425,19 @@ restore_user_configs() {
done
fi
fi
+
+ # Always run de-dupe based on the installed dotfiles version so that
+ # express mode and standard mode behave consistently. Prefer the
+ # pre-upgrade version (old_version) if provided so we still clean up
+ # legacy duplicates when upgrading to a newer release that no longer
+ # needs the fix.
+ local detected_version="$old_version"
+ if [ -z "$detected_version" ]; then
+ detected_version=$(get_installed_dotfiles_version)
+ fi
+ if [ -n "$detected_version" ]; then
+ cleanup_duplicate_userconfigs "$detected_version" "$log"
+ fi
}
restore_user_scripts() {
send patches to the email below
yukais@pinapelz.com
include the subject [PATCH repo_name]
pinapelz.com
homepage