Added support for Darwin, some interaction improvement, and style lint

master
Manpreet Singh 9 years ago
parent 64b7165669
commit 33b59c99b2
  1. 220
      syncthing-resolve-conflicts.sh

@ -1,4 +1,4 @@
#!/usr/bin/bash
#!/usr/bin/env bash
# Check for sync conflicts and resolve them. Idea from the shell
# script 'pacdiff'.
@ -12,41 +12,60 @@ declare -a ignored
declare -a nontext
plain() {
(( QUIET )) && return
local mesg=$1; shift
printf " ${mesg}${ALL_OFF}\n" "$@" >&1
(( QUIET )) && return
local mesg
mesg="$1"; shift
printf " ${mesg}${ALL_OFF}\n" "$@" >&1
}
msg() {
(( QUIET )) && return
local mesg=$1; shift
printf "${GREEN}==>${ALL_OFF} ${mesg}${ALL_OFF}\n" "$@" >&1
(( QUIET )) && return
local mesg
mesg="$1"; shift
# shellcheck disable=SC2059
printf "${GREEN}==>${ALL_OFF} ${mesg}${ALL_OFF}\n" "$@" >&1
}
msg2() {
(( QUIET )) && return
local mesg=$1; shift
printf "${BLUE} ->${ALL_OFF} ${mesg}${ALL_OFF}\n" "$@" >&1
(( QUIET )) && return
local mesg
mesg="$1"; shift
# shellcheck disable=SC2059
printf "${BLUE} ->${ALL_OFF} ${mesg}${ALL_OFF}\n" "$@" >&1
}
ask() {
local mesg=$1; shift
printf " ${BLUE}::${ALL_OFF} ${mesg}${ALL_OFF}" "$@" >&1
local mesg
mesg="$1"; shift
# shellcheck disable=SC2059
printf " ${BLUE}::${ALL_OFF} ${mesg}${ALL_OFF}" "$@" >&1
}
if [ -n "$(command -v gettext)" ]; then
translate() {
gettext "$@"
}
else
translate() {
printf %s "$@"
}
fi
warning() {
local mesg=$1; shift
echo
printf "${YELLOW}==> $(gettext "WARNING:")${ALL_OFF} ${mesg}${ALL_OFF}\n" "$@" >&2
local mesg
mesg="$1"; shift
# shellcheck disable=SC2059
printf "\n${YELLOW}==> $(translate "WARNING:")${ALL_OFF} ${mesg}${ALL_OFF}\n" "$@" >&2
}
error() {
local mesg=$1; shift
printf "${RED}==> $(gettext "ERROR:")${ALL_OFF} ${mesg}${ALL_OFF}\n" "$@" >&2
local mesg
mesg="$1"; shift
# shellcheck disable=SC2059
printf "${RED}==> $(translate "ERROR:")${ALL_OFF} ${mesg}${ALL_OFF}\n" "$@" >&2
}
usage() {
cat <<EOF
cat <<EOF
${myname} v${myver}
Inspired by 'pacdiff'.
@ -70,81 +89,85 @@ EOF
}
version() {
printf "%s %s\n" "$myname" "$myver"
printf "%s %s\n" "$myname" "$myver"
echo 'Copyright (C) 2017 Dominik Schrempf <dominik.schrempf@gmail.com>'
echo 'Inspired by "pacdiff".'
echo 'Inspired by "pacdiff".'
}
cmd() {
locate -0 -e -b sync-conflict
case "$(uname -s)" in
Darwin) locate -0 sync-conflict;;
*) locate -0 -e -b sync-conflict ;;
esac
}
while [[ -n "$1" ]]; do
case "$1" in
-o|--output)
OUTPUTONLY=1;;
--nocolor)
USE_COLOR='n';;
-v|-V|--version)
version; exit 0;;
-h|--help)
usage; exit 0;;
*)
usage; exit 1;;
esac
shift
case "$1" in
-o|--output)
OUTPUTONLY=1;;
--nocolor)
USE_COLOR='n';;
-v|-V|--version)
version; exit 0;;
-h|--help)
usage; exit 0;;
*)
usage; exit 1;;
esac
shift
done
# Check if messages are to be printed using color.
unset ALL_OFF BOLD BLUE GREEN RED YELLOW
if [[ -t 2 && $USE_COLOR = "y" ]]; then
# Prefer terminal safe colored and bold text when tput is supported.
if tput setaf 0 &>/dev/null; then
ALL_OFF="$(tput sgr0)"
BLUE="$(tput setaf 27)"
GREEN="$(tput setaf 2)"
RED="$(tput setaf 1)"
YELLOW="$(tput setaf 3)"
else
ALL_OFF="\e[1;0m"
BLUE="\e[1;34m"
GREEN="\e[1;32m"
RED="\e[1;31m"
YELLOW="\e[1;33m"
fi
# Prefer terminal safe colored and bold text when tput is supported.
if tput setaf 0 &>/dev/null; then
ALL_OFF="$(tput sgr0)"
BLUE="$(tput setaf 27)"
GREEN="$(tput setaf 2)"
RED="$(tput setaf 1)"
YELLOW="$(tput setaf 3)"
else
ALL_OFF="\e[1;0m"
BLUE="\e[1;34m"
GREEN="\e[1;32m"
RED="\e[1;31m"
YELLOW="\e[1;33m"
fi
fi
readonly ALL_OFF BOLD BLUE GREEN RED YELLOW
if ! type -p ${diffprog%% *} >/dev/null && (( ! OUTPUTONLY )); then
error "Cannot find the $diffprog binary required for viewing differences."
exit 1
if [ -z "$(command -v "${diffprog%% *}")" ] && (( ! OUTPUTONLY )); then
error "Cannot find the $diffprog binary required for viewing differences."
exit 1
fi
warning "Recursive sync conflicts are not properly handled."
# See http://mywiki.wooledge.org/BashFAQ/020.
while IFS= read -u 3 -r -d '' conflict; do
if (( OUTPUTONLY )); then
echo "$conflict"
continue
fi
[[ ! -e "$conflict" && ! -L "$conflict" && ! -d "$conflict" ]] && continue
if (( OUTPUTONLY )); then
echo "$conflict"
continue
fi
# Ignore backups in '.stversions' folders.
if [[ "$conflict" = */.stversions/* ]]
then
ignored+=("$conflict")
continue
ignored+=("$conflict")
continue
fi
# XXX: Maybe somebody wants to diff special non-text files?
# Ignore binary files.
if [[ -z $(file -i "$conflict" | grep text) ]]
if file -i "$conflict" | grep -qv text
then
nontext+=("$conflict")
continue
nontext+=("$conflict")
continue
fi
# XXX: Recursive sync conflicts lead to problems if they are
# treated in the wrong order.
@ -152,8 +175,7 @@ while IFS= read -u 3 -r -d '' conflict; do
# Original filename.
file="${conflict/.sync-conflict-????????-??????/}"
msg "Sync conflict found: %s" "$conflict"
msg "Sync conflict: %s" "$conflict"
# Handle sync conflict if original file exists.
if [ ! -f "$file" ]
then
@ -163,25 +185,29 @@ while IFS= read -u 3 -r -d '' conflict; do
fi
msg2 "Original file: %s" "$file"
if cmp -s "$conflict" "$file"; then
msg2 "Files are identical, removing..."
plain "$(rm -v "$conflict")"
else
ask "(V)iew, (S)kip, (R)emove sync conflict, (O)verwrite with sync conflict, (Q)uit: [v/s/r/o/q] "
while read c; do
case $c in
q|Q) exit 0;;
r|R) plain "$(rm -v "$conflict")"; break ;;
o|O) plain "$(mv -v "$conflict" "$file")"; break ;;
v|V)
$diffprog "$conflict" "$file"
ask "(V)iew, (S)kip, (R)emove sync conflict, (O)verwrite with sync conflict, (Q)uit: [v/s/r/o/q] "
continue ;;
s|S) break ;;
*) ask "Invalid answer. Try again: [v/s/r/o/q] "; continue ;;
esac
done
fi
if test "$conflict" -ef "$file"; then
warning "Original file and conflict file point to the same file. Ignoring conflict."
continue
elif cmp -s "$conflict" "$file"; then
msg2 "Files are identical, removing..."
plain "$(rm -v "$conflict")"
else
ask "(V)iew, (S)kip, (R)emove sync conflict, (O)verwrite with sync conflict, (Q)uit: [v/s/r/o/q] "
# shellcheck disable=SC2162
while read c; do
case $c in
q|Q) exit 0;;
r|R) plain "$(rm -v "$conflict")"; break ;;
o|O) plain "$(mv -v "$conflict" "$file")"; break ;;
v|V)
$diffprog "$conflict" "$file"
ask "(V)iew, (S)kip, (R)emove sync conflict, (O)verwrite with sync conflict, (Q)uit: [v/s/r/o/q] "
continue ;;
s|S) break ;;
*) ask "Invalid answer. Try again: [v/s/r/o/q] "; continue ;;
esac
done
fi
done 3< <(cmd)
# Print warning if files have been ignored and delete them if
@ -190,10 +216,27 @@ if [ ! ${#ignored[@]} -eq 0 ]
then
warning "Some files have been ignored."
(( ${#ignored[@]} )) && msg "%s" "${ignored[@]}"
ask "(R)emove ignored files, (Q)uit: [r/q] "
ask "(R)emove all ignored files, (A)sk for each file, (Q)uit: [r/q] "
# shellcheck disable=SC2162
while read c; do
case $c in
case "$c" in
q|Q) exit 0 ;;
a|A)
for f in "${ignored[@]}"
do
msg "Ignored file: %s" "$f"
ask "(R)emove, (S)kip, (Q)uit: [r/s/q] "
# shellcheck disable=SC2162
while read ci; do
case "$ci" in
q|Q) exit 0 ;;
s|S) break ;;
r|R) plain "$(rm -v "$f")"; break ;;
*) ask "Invalid answer. Try again: [r/s/q] "; continue ;;
esac
done
done
;;
r|R) (( ${#ignored[@]} )) && plain "$(rm -v "${ignored[@]}")"; break ;;
*) ask "Invalid answer. Try again: [d/q] "; continue ;;
esac
@ -204,13 +247,14 @@ fi
# delete them one by one if specified.
if [ ! ${#nontext[@]} -eq 0 ]
then
warning "Some files that are not text have been ignored."
warning "The following files that are non-text:"
for f in "${nontext[@]}"
do
msg "%s" "$f"
msg "Non-text file: %s" "$f"
ask "(R)emove, (S)kip, (Q)uit: [r/s/q] "
# shellcheck disable=SC2162
while read c; do
case $c in
case "$c" in
q|Q) exit 0 ;;
s|S) break ;;
r|R) plain "$(rm -v "$f")"; break ;;

Loading…
Cancel
Save