xonotic/misc/tools/zipdiff
2012-03-13 13:05:26 +01:00

185 lines
2.7 KiB
Bash
Executable File

#!/bin/sh
set -e
usage()
{
cat <<EOF
Usage:
$0 -o difference.zip -f from.zip -t to.zip
$0 -f from.zip -t to.zip
EOF
exit 1
}
output=
from=
to=
excludes=
ziptool="mkzip"
mkzip()
{
archive=$1; shift
zipflags=-1ry
zip $zipflags "$archive" "$@" || true
advzip -z -4 "$archive"
}
while [ $# -gt 0 ]; do
o=$1
shift
case "$o" in
-o)
output=$1
shift
;;
-f)
from=$1
shift
;;
-t)
to=$1
shift
;;
-x)
excludes="$excludes $1"
shift
;;
-z)
ziptool=$1
shift
;;
*)
usage
;;
esac
done
[ -n "$from" ] || usage
[ -n "$to" ] || usage
case "$output" in '') ;; /*) ;; *) output=`pwd`/$output ;; esac
case "$from" in /*) ;; *) from=`pwd`/$from ;; esac
case "$to" in /*) ;; *) to=`pwd`/$to ;; esac
found()
{
type=$1
source=$2
echo >&2 "$type: $source"
case "$type" in
new|changed|deleted)
echo "$source"
;;
excluded)
;;
deleted|*)
echo >&2 " * Sorry, can't handle deletion of $source."
;;
esac
}
tempdir=`mktemp -d -t zipdiff.XXXXXX`
newline="
"
fromlist="$(zipinfo -1 "$from" | grep -v /\$)"
tolist="$(zipinfo -1 "$to" | grep -v /\$)"
diffit()
{
echo "$fromlist" | while IFS= read -r line; do
case "$newline$tolist$newline" in
*$newline$line$newline*)
;;
*)
isexcluded=false
for P in $excludes; do
case "$line" in
$P)
found excluded "$line"
isexcluded=true
break
;;
esac
done
if ! $isexcluded; then
found deleted "$line"
fi
;;
esac
done
echo "$tolist" | while IFS= read -r line; do
case "$newline$fromlist$newline" in
*$newline$line$newline*)
# check if equal
isexcluded=false
for P in $excludes; do
case "$line" in
$P)
found excluded "$line"
isexcluded=true
break
;;
esac
done
if ! $isexcluded; then
unzip -p "$from" "$line" > "$tempdir/v1"
unzip -p "$to" "$line" > "$tempdir/v2"
if ! diff --brief "$tempdir/v1" "$tempdir/v2" >/dev/null 2>&1; then
found changed "$line"
fi
rm "$tempdir/v1"
rm "$tempdir/v2"
fi
;;
*)
# check if equal
isexcluded=false
for P in $excludes; do
case "$line" in
$P)
found excluded "$line"
isexcluded=true
break
;;
esac
done
if ! $isexcluded; then
found new "$line"
fi
;;
esac
done
}
result=`diffit`
case "$output" in
'')
;;
*)
rm -f "$output"
if [ -n "$result" ]; then
cd "$tempdir"
echo "$result" | while IFS= read -r line; do
echo >&2 "extracting $line..."
dline=./$line
mkdir -p "$tempdir/${dline%/*}"
unzip "$to" "$line"
done
$ziptool "$output" *
cd ..
fi
;;
esac
rm -rf "$tempdir"