contrib/pkgutils/rejmerge
2006-11-13 21:12:21 +01:00

295 lines
5.3 KiB
Bash

#!/bin/bash
#
# rejmerge (pkgutils)
#
# Copyright (c) 2000-2004 Per Liden
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
# USA.
#
# zsh/bash portability stuff
if [ -z "$ZSH_VERSION" ]; then
port_read()
{
read -n 1 "$@"
}
port_type()
{
type -t "$@"
}
else
alias port_read='read -k 1'
alias port_type='type'
setopt braceexpand
fi
info_n()
{
echo -n "=======> $1"
}
info()
{
info_n "$1"
echo
}
interrupted()
{
echo
info "Aborted."
exit 1
}
atexit()
{
if [ -f "$TMPFILE" ]; then
rm -f "$TMPFILE"
fi
}
rejmerge_diff()
{
diff -u "$1" "$2" > "$3"
}
rejmerge_merge()
{
diff --old-group-format="%<" \
--new-group-format="%>" \
--changed-group-format="<<<<< MERGE CONFLICT $1 >>>>>
%<<<<<< MERGE CONFLICT $2 >>>>>
%><<<<< END MERGE CONFLICT >>>>>
" \
"$1" "$2" > "$3"
REJMERGE_MERGE_INFO="$(grep -c '^<<<<< END MERGE CONFLICT >>>>>$' "$3") merge conflict(s)."
}
merge_menu()
{
rejmerge_merge "$1" "$2" "$TMPFILE"
while :; do
info "Merged $1"
$PAGER "$TMPFILE"
if [ "$REJMERGE_MERGE_INFO" ]; then
info "$REJMERGE_MERGE_INFO"
unset REJMERGE_MERGE_INFO
fi
while :; do
info_n "[I]nstall [E]dit [V]iew [S]kip? "
port_read CMD
echo
case "$CMD" in
i|I)
# Keep permissions
$SUDO sh -c "cat $TMPFILE > $1"
$SUDO rm -f "$2"
break 2
;;
e|E)
$EDITOR "$TMPFILE"
break 1
;;
v|V) break 1 ;;
s|S) break 2 ;;
esac
done
done
: > "$TMPFILE"
}
diff_menu()
{
rejmerge_diff "$1" "$2" "$TMPFILE"
while :; do
info "$1"
$PAGER "$TMPFILE"
while :; do
info_n "[K]eep [U]pgrade [M]erge [D]iff [S]kip? "
port_read CMD
echo
case "$CMD" in
k|K)
$SUDO rm -f "$2"
break 2
;;
u|U)
$SUDO sh -c "cat $2 > $1"
break 2
;;
m|M)
merge_menu "$1" "$2"
break 2
;;
d|D)
break 1
;;
s|S)
break 2
;;
esac
done
done
: > "$TMPFILE"
}
file_menu()
{
while :; do
info "$1"
file "$1" "$2"
while :; do
info_n "[K]eep [U]pgrade [D]iff [S]kip? "
port_read CMD
echo
case "$CMD" in
k|K)
$SUDO rm -f "$2"
break 2
;;
u|U)
$SUDO sh -c "$2 > $1"
break 2
;;
d|D)
break 1
;;
s|S)
break 2
;;
esac
done
done
}
print_help()
{
cat << EOF
usage: $REJMERGE_COMMAND [options]
options:
-r, --root <path> specify alternative root
-v, --version print version and exit
-h, --help print help and exit
EOF
}
parse_options()
{
while [ "$1" ]; do
case $1 in
-r|--root)
if [ ! "$2" ]; then
echo "$REJMERGE_COMMAND: option $1 requires an argument"
exit 1
fi
REJMERGE_ROOT="$2"
REJMERGE_CONF="$2$REJMERGE_CONF"
REJECTED_DIR="$2$REJECTED_DIR"
shift ;;
-v|--version)
echo "$REJMERGE_COMMAND (pkgutils) $REJMERGE_VERSION"
exit 0 ;;
-h|--help)
print_help
exit 0 ;;
*)
echo "$REJMERGE_COMMAND: invalid option $1"
exit 1 ;;
esac
shift
done
if [ ! -d "$REJECTED_DIR" ]; then
echo "$REJMERGE_COMMAND: $REJECTED_DIR not found"
exit 1
fi
}
main()
{
parse_options "$@"
if [ "$UID" -eq 0 ]; then
echo "$REJMERGE_COMMAND: don't merge rejected files as root"
exit 1
fi
# Read configuration
if [ -f "$REJMERGE_CONF" ]; then
source "$REJMERGE_CONF"
fi
REJECTED_FILES_FOUND=no
# Check regular files
for REJECTED_FILE in $(find $REJECTED_DIR -type f); do
INSTALLED_FILE="$REJMERGE_ROOT${REJECTED_FILE##$REJECTED_DIR}"
if [ ! -e "$INSTALLED_FILE" ] || cmp -s "$INSTALLED_FILE" "$REJECTED_FILE"; then
$SUDO rm -f "$REJECTED_FILE"
else
REJECTED_FILES_FOUND=yes
diff_menu "$INSTALLED_FILE" "$REJECTED_FILE"
fi
done
# Check non-regular files
for REJECTED_FILE in $(find $REJECTED_DIR ! -type d ! -type f); do
INSTALLED_FILE="$REJMERGE_ROOT${REJECTED_FILE##$REJECTED_DIR}"
if [ ! -e "$INSTALLED_FILE" ]; then
$SUDO rm -f "$REJECTED_FILE"
else
REJECTED_FILES_FOUND=yes
file_menu "$INSTALLED_FILE" "$REJECTED_FILE"
fi
done
# Remove empty directories
$SUDO find $REJECTED_DIR -mindepth 1 -depth -empty -exec rmdir {} \;
if [ "$REJECTED_FILES_FOUND" = no ]; then
echo "Nothing to merge"
fi
exit 0
}
trap "interrupted" HUP INT QUIT TERM
trap "atexit" EXIT
export LC_ALL=POSIX
readonly REJMERGE_VERSION="5.18"
readonly REJMERGE_COMMAND="${0##*/}"
unset REJMERGE_ROOT
REJMERGE_CONF="/etc/rejmerge.conf"
REJECTED_DIR="/var/lib/pkg/rejected"
PAGER=more
SUDO=/usr/bin/sudo
EDITOR=${EDITOR:-vi}
TMPFILE=$(mktemp) || exit 1
main "$@"