forked from Shinonome/dots-hyprland
feat(exp-update): add --default-choice option (#2915)
This commit is contained in:
+123
-116
@@ -113,7 +113,16 @@ safe_read() {
|
|||||||
|
|
||||||
echo -n "$prompt"
|
echo -n "$prompt"
|
||||||
|
|
||||||
# Try to read from terminal with better detection
|
# First, try reading from stdin (supports piped input like "yes 1 |")
|
||||||
|
if read -r -t 0.1 input_value 2>/dev/null; then
|
||||||
|
# Successfully read from stdin (piped input)
|
||||||
|
if [[ -n "$input_value" ]]; then
|
||||||
|
printf -v "$varname" '%s' "$input_value"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# If stdin had no data, try interactive terminal
|
||||||
if [[ -t 0 ]]; then
|
if [[ -t 0 ]]; then
|
||||||
# stdin is a terminal
|
# stdin is a terminal
|
||||||
read -r input_value
|
read -r input_value
|
||||||
@@ -339,145 +348,124 @@ handle_file_conflict() {
|
|||||||
local home_file="$2"
|
local home_file="$2"
|
||||||
local filename=$(basename "$home_file")
|
local filename=$(basename "$home_file")
|
||||||
local dirname=$(dirname "$home_file")
|
local dirname=$(dirname "$home_file")
|
||||||
|
local choice=""
|
||||||
|
local default_val="${DEFAULT_CHOICE:-6}" # Use DEFAULT_CHOICE or 6 (skip) as fallback
|
||||||
|
|
||||||
echo -e "\n${STY_YELLOW}Conflict detected:${STY_RST} $home_file"
|
# In non-interactive mode, use default directly (acts like pressing Enter)
|
||||||
echo "Repository version differs from your local version."
|
if [[ "$NON_INTERACTIVE" == true ]]; then
|
||||||
echo
|
choice="$default_val"
|
||||||
echo "Choose an action:"
|
log_info "Using choice $choice for: $home_file"
|
||||||
echo "1) Replace local file with repository version"
|
else
|
||||||
echo "2) Keep local file unchanged"
|
echo -e "\n${STY_YELLOW}Conflict detected:${STY_RST} $home_file"
|
||||||
echo "3) Backup local file as ${filename}.old, use repository version"
|
echo "Repository version differs from your local version."
|
||||||
echo "4) Save repository version as ${filename}.new, keep local file"
|
echo
|
||||||
echo "5) Show diff and decide"
|
echo "Choose an action:"
|
||||||
echo "6) Skip this file"
|
echo "1) Replace local file with repository version"
|
||||||
echo "7) Add to ignore and skip"
|
echo "2) Keep local file unchanged"
|
||||||
echo "8) Backup to .update-backups/ and replace with repository version"
|
echo "3) Backup local file as ${filename}.old, use repository version"
|
||||||
echo
|
echo "4) Save repository version as ${filename}.new, keep local file"
|
||||||
|
echo "5) Show diff and decide"
|
||||||
|
echo "6) Skip this file"
|
||||||
|
echo "7) Add to ignore and skip"
|
||||||
|
echo "8) Backup to .update-backups/ and replace with repository version"
|
||||||
|
echo
|
||||||
|
|
||||||
while true; do
|
while true; do
|
||||||
if ! safe_read "Enter your choice (1-8): " choice "6"; then
|
if ! safe_read "Enter your choice (1-8 or name) [${default_val}]: " choice "$default_val"; then
|
||||||
|
echo
|
||||||
|
log_warning "Failed to read input. Skipping file."
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Validate choice
|
||||||
|
if [[ "$choice" =~ ^[1-8]$ ]] || [[ "$choice" =~ ^(replace|keep|old|new|diff|skip|ignore|backup)$ ]]; then
|
||||||
|
break
|
||||||
|
else
|
||||||
|
echo "Invalid choice. Please enter 1-8 or a valid name (replace, keep, old ...)."
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
case $choice in
|
||||||
|
1|replace)
|
||||||
|
if [[ "$DRY_RUN" == true ]]; then
|
||||||
|
log_info "[DRY-RUN] Would replace $home_file with repository version"
|
||||||
|
else
|
||||||
|
cp -p "$repo_file" "$home_file"
|
||||||
|
log_success "Replaced $home_file with repository version"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
2|keep)
|
||||||
|
log_info "Keeping local version of $home_file"
|
||||||
|
;;
|
||||||
|
3|old)
|
||||||
|
if [[ "$DRY_RUN" == true ]]; then
|
||||||
|
log_info "[DRY-RUN] Would backup local file to ${filename}.old and update with repository version"
|
||||||
|
else
|
||||||
|
mv "$home_file" "${dirname}/${filename}.old"
|
||||||
|
cp -p "$repo_file" "$home_file"
|
||||||
|
log_success "Backed up local file to ${filename}.old and updated with repository version"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
4|new)
|
||||||
|
if [[ "$DRY_RUN" == true ]]; then
|
||||||
|
log_info "[DRY-RUN] Would save repository version as ${filename}.new, keep local file"
|
||||||
|
else
|
||||||
|
cp -p "$repo_file" "${dirname}/${filename}.new"
|
||||||
|
log_success "Saved repository version as ${filename}.new, kept local file"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
5|diff)
|
||||||
|
show_diff "$home_file" "$repo_file"
|
||||||
|
echo
|
||||||
|
echo "After reviewing the diff, choose:"
|
||||||
|
echo "r) Replace with repository version"
|
||||||
|
echo "k) Keep local version"
|
||||||
|
echo "b) Backup local and use repository version"
|
||||||
|
echo "n) Save repository version as .new"
|
||||||
|
echo "s) Skip this file"
|
||||||
|
echo "i) Add to ignore and skip"
|
||||||
|
echo "B) Backup to .update-backups/ and replace"
|
||||||
|
|
||||||
|
if ! safe_read "Enter your choice (r/k/b/n/s/i/B): " subchoice "s"; then
|
||||||
echo
|
echo
|
||||||
log_warning "Failed to read input. Skipping file."
|
log_warning "Failed to read input. Skipping file."
|
||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
|
|
||||||
case $choice in
|
case $subchoice in
|
||||||
1)
|
r)
|
||||||
if [[ "$DRY_RUN" == true ]]; then
|
if [[ "$DRY_RUN" == true ]]; then
|
||||||
log_info "[DRY-RUN] Would replace $home_file with repository version"
|
log_info "[DRY-RUN] Would replace $home_file with repository version"
|
||||||
else
|
else
|
||||||
cp -p "$repo_file" "$home_file"
|
cp -p "$repo_file" "$home_file"
|
||||||
log_success "Replaced $home_file with repository version"
|
log_success "Replaced $home_file with repository version"
|
||||||
fi
|
fi
|
||||||
break
|
|
||||||
;;
|
;;
|
||||||
2)
|
k)
|
||||||
log_info "Keeping local version of $home_file"
|
log_info "Keeping local version of $home_file"
|
||||||
break
|
|
||||||
;;
|
;;
|
||||||
3)
|
b)
|
||||||
if [[ "$DRY_RUN" == true ]]; then
|
if [[ "$DRY_RUN" == true ]]; then
|
||||||
log_info "[DRY-RUN] Would backup local file to ${filename}.old and update with repository version"
|
log_info "[DRY-RUN] Would backup local file to ${filename}.old and update"
|
||||||
else
|
else
|
||||||
mv "$home_file" "${dirname}/${filename}.old"
|
mv "$home_file" "${dirname}/${filename}.old"
|
||||||
cp -p "$repo_file" "$home_file"
|
cp -p "$repo_file" "$home_file"
|
||||||
log_success "Backed up local file to ${filename}.old and updated with repository version"
|
log_success "Backed up local file to ${filename}.old and updated"
|
||||||
fi
|
fi
|
||||||
break
|
|
||||||
;;
|
;;
|
||||||
4)
|
n)
|
||||||
if [[ "$DRY_RUN" == true ]]; then
|
if [[ "$DRY_RUN" == true ]]; then
|
||||||
log_info "[DRY-RUN] Would save repository version as ${filename}.new, keep local file"
|
log_info "[DRY-RUN] Would save repository version as ${filename}.new"
|
||||||
else
|
else
|
||||||
cp -p "$repo_file" "${dirname}/${filename}.new"
|
cp -p "$repo_file" "${dirname}/${filename}.new"
|
||||||
log_success "Saved repository version as ${filename}.new, kept local file"
|
log_success "Saved repository version as ${filename}.new"
|
||||||
fi
|
fi
|
||||||
break
|
|
||||||
;;
|
;;
|
||||||
5)
|
s)
|
||||||
show_diff "$home_file" "$repo_file"
|
|
||||||
echo
|
|
||||||
echo "After reviewing the diff, choose:"
|
|
||||||
echo "r) Replace with repository version"
|
|
||||||
echo "k) Keep local version"
|
|
||||||
echo "b) Backup local and use repository version"
|
|
||||||
echo "n) Save repository version as .new"
|
|
||||||
echo "s) Skip this file"
|
|
||||||
echo "i) Add to ignore and skip"
|
|
||||||
echo "B) Backup to .update-backups/ and replace"
|
|
||||||
|
|
||||||
if ! safe_read "Enter your choice (r/k/b/n/s/i/B): " subchoice "s"; then
|
|
||||||
echo
|
|
||||||
log_warning "Failed to read input. Skipping file."
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
|
|
||||||
case $subchoice in
|
|
||||||
r)
|
|
||||||
if [[ "$DRY_RUN" == true ]]; then
|
|
||||||
log_info "[DRY-RUN] Would replace $home_file with repository version"
|
|
||||||
else
|
|
||||||
cp -p "$repo_file" "$home_file"
|
|
||||||
log_success "Replaced $home_file with repository version"
|
|
||||||
fi
|
|
||||||
break
|
|
||||||
;;
|
|
||||||
k)
|
|
||||||
log_info "Keeping local version of $home_file"
|
|
||||||
break
|
|
||||||
;;
|
|
||||||
b)
|
|
||||||
if [[ "$DRY_RUN" == true ]]; then
|
|
||||||
log_info "[DRY-RUN] Would backup local file to ${filename}.old and update"
|
|
||||||
else
|
|
||||||
mv "$home_file" "${dirname}/${filename}.old"
|
|
||||||
cp -p "$repo_file" "$home_file"
|
|
||||||
log_success "Backed up local file to ${filename}.old and updated"
|
|
||||||
fi
|
|
||||||
break
|
|
||||||
;;
|
|
||||||
n)
|
|
||||||
if [[ "$DRY_RUN" == true ]]; then
|
|
||||||
log_info "[DRY-RUN] Would save repository version as ${filename}.new"
|
|
||||||
else
|
|
||||||
cp -p "$repo_file" "${dirname}/${filename}.new"
|
|
||||||
log_success "Saved repository version as ${filename}.new"
|
|
||||||
fi
|
|
||||||
break
|
|
||||||
;;
|
|
||||||
s)
|
|
||||||
log_info "Skipping $home_file"
|
|
||||||
break
|
|
||||||
;;
|
|
||||||
i)
|
|
||||||
local relative_path_to_home="${home_file#$HOME/}"
|
|
||||||
if [[ "$DRY_RUN" == true ]]; then
|
|
||||||
log_info "[DRY-RUN] Would add '$relative_path_to_home' to $XDG_UPDATE_IGNORE_FILE"
|
|
||||||
else
|
|
||||||
echo "$relative_path_to_home" >>"$XDG_UPDATE_IGNORE_FILE"
|
|
||||||
log_success "Added '$relative_path_to_home' to $XDG_UPDATE_IGNORE_FILE and skipped."
|
|
||||||
fi
|
|
||||||
break
|
|
||||||
;;
|
|
||||||
B)
|
|
||||||
if backup_file "$home_file"; then
|
|
||||||
if [[ "$DRY_RUN" != true ]]; then
|
|
||||||
cp -p "$repo_file" "$home_file"
|
|
||||||
log_success "Replaced $home_file with repository version"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
break
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
echo "Invalid choice. Please try again."
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
;;
|
|
||||||
6)
|
|
||||||
log_info "Skipping $home_file"
|
log_info "Skipping $home_file"
|
||||||
break
|
|
||||||
;;
|
;;
|
||||||
7)
|
i)
|
||||||
local relative_path_to_home="${home_file#$HOME/}"
|
local relative_path_to_home="${home_file#$HOME/}"
|
||||||
if [[ "$DRY_RUN" == true ]]; then
|
if [[ "$DRY_RUN" == true ]]; then
|
||||||
log_info "[DRY-RUN] Would add '$relative_path_to_home' to $XDG_UPDATE_IGNORE_FILE"
|
log_info "[DRY-RUN] Would add '$relative_path_to_home' to $XDG_UPDATE_IGNORE_FILE"
|
||||||
@@ -485,22 +473,41 @@ handle_file_conflict() {
|
|||||||
echo "$relative_path_to_home" >>"$XDG_UPDATE_IGNORE_FILE"
|
echo "$relative_path_to_home" >>"$XDG_UPDATE_IGNORE_FILE"
|
||||||
log_success "Added '$relative_path_to_home' to $XDG_UPDATE_IGNORE_FILE and skipped."
|
log_success "Added '$relative_path_to_home' to $XDG_UPDATE_IGNORE_FILE and skipped."
|
||||||
fi
|
fi
|
||||||
break
|
|
||||||
;;
|
;;
|
||||||
8)
|
B)
|
||||||
if backup_file "$home_file"; then
|
if backup_file "$home_file"; then
|
||||||
if [[ "$DRY_RUN" != true ]]; then
|
if [[ "$DRY_RUN" != true ]]; then
|
||||||
cp -p "$repo_file" "$home_file"
|
cp -p "$repo_file" "$home_file"
|
||||||
log_success "Replaced $home_file with repository version"
|
log_success "Replaced $home_file with repository version"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
break
|
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
echo "Invalid choice. Please enter 1-8."
|
log_info "Skipping $home_file"
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
done
|
;;
|
||||||
|
6|skip)
|
||||||
|
log_info "Skipping $home_file"
|
||||||
|
;;
|
||||||
|
7|ignore)
|
||||||
|
local relative_path_to_home="${home_file#$HOME/}"
|
||||||
|
if [[ "$DRY_RUN" == true ]]; then
|
||||||
|
log_info "[DRY-RUN] Would add '$relative_path_to_home' to $XDG_UPDATE_IGNORE_FILE"
|
||||||
|
else
|
||||||
|
echo "$relative_path_to_home" >>"$XDG_UPDATE_IGNORE_FILE"
|
||||||
|
log_success "Added '$relative_path_to_home' to $XDG_UPDATE_IGNORE_FILE and skipped."
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
8|backup)
|
||||||
|
if backup_file "$home_file"; then
|
||||||
|
if [[ "$DRY_RUN" != true ]]; then
|
||||||
|
cp -p "$repo_file" "$home_file"
|
||||||
|
log_success "Replaced $home_file with repository version"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
esac
|
||||||
}
|
}
|
||||||
|
|
||||||
# Function to check if PKGBUILD has changed
|
# Function to check if PKGBUILD has changed
|
||||||
|
|||||||
@@ -15,7 +15,10 @@ Options:
|
|||||||
-h, --help Show this help message
|
-h, --help Show this help message
|
||||||
-s, --skip-notice Skip notice about script being untested
|
-s, --skip-notice Skip notice about script being untested
|
||||||
--non-interactive
|
--non-interactive
|
||||||
Run without prompting for user input
|
Set default choice for file conflicts
|
||||||
|
replace: Replace local keep: Keep local old: Backup as .old
|
||||||
|
new: Save as .new diff: Show diff skip: Skip
|
||||||
|
ignore: Add to ignore backup: Backup and replace
|
||||||
|
|
||||||
This script updates your dotfiles by:
|
This script updates your dotfiles by:
|
||||||
1. Auto-detecting repository structure (dots/ prefix or direct)
|
1. Auto-detecting repository structure (dots/ prefix or direct)
|
||||||
@@ -35,7 +38,7 @@ Ignore file patterns support:
|
|||||||
# `man getopt` to see more
|
# `man getopt` to see more
|
||||||
para=$(getopt \
|
para=$(getopt \
|
||||||
-o hfpnvs \
|
-o hfpnvs \
|
||||||
-l help,force,packages,dry-run,verbose,skip-notice,non-interactive \
|
-l help,force,packages,dry-run,verbose,skip-notice,non-interactive,default-choice: \
|
||||||
-n "$0" -- "$@")
|
-n "$0" -- "$@")
|
||||||
[ $? != 0 ] && echo "$0: Error when getopt, please recheck parameters." && exit 1
|
[ $? != 0 ] && echo "$0: Error when getopt, please recheck parameters." && exit 1
|
||||||
#####################################################################################
|
#####################################################################################
|
||||||
@@ -58,6 +61,7 @@ DRY_RUN=false
|
|||||||
VERBOSE=false
|
VERBOSE=false
|
||||||
SKIP_NOTICE=false
|
SKIP_NOTICE=false
|
||||||
NON_INTERACTIVE=false
|
NON_INTERACTIVE=false
|
||||||
|
DEFAULT_CHOICE=""
|
||||||
|
|
||||||
eval set -- "$para"
|
eval set -- "$para"
|
||||||
while true ; do
|
while true ; do
|
||||||
@@ -81,6 +85,25 @@ while true ; do
|
|||||||
--non-interactive) NON_INTERACTIVE=true;shift
|
--non-interactive) NON_INTERACTIVE=true;shift
|
||||||
log_info "Non-interactive mode enabled"
|
log_info "Non-interactive mode enabled"
|
||||||
;;
|
;;
|
||||||
|
--default-choice)
|
||||||
|
case "$2" in
|
||||||
|
replace) DEFAULT_CHOICE="1" ;;
|
||||||
|
keep) DEFAULT_CHOICE="2" ;;
|
||||||
|
old) DEFAULT_CHOICE="3" ;;
|
||||||
|
new) DEFAULT_CHOICE="4" ;;
|
||||||
|
diff) DEFAULT_CHOICE="5" ;;
|
||||||
|
skip) DEFAULT_CHOICE="6" ;;
|
||||||
|
ignore) DEFAULT_CHOICE="7" ;;
|
||||||
|
backup) DEFAULT_CHOICE="8" ;;
|
||||||
|
*)
|
||||||
|
log_error "Invalid --default-choice value: $2"
|
||||||
|
log_error "Valid values: replace, keep, old, new, diff, skip, ignore, backup"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
shift 2
|
||||||
|
log_info "Default conflict choice set to: $DEFAULT_CHOICE"
|
||||||
|
;;
|
||||||
|
|
||||||
## Ending
|
## Ending
|
||||||
--) break ;;
|
--) break ;;
|
||||||
|
|||||||
Reference in New Issue
Block a user