#!/bin/bash

# rpm-build-compare.sh
#
# Written by Charles R. Anderson <cra@wpi.edu>

pkgA=$1
pkgB=$2

if [ "$1" == "" -o "$2" == "" -o "$1" == "-h" -o "$1" == "--help" ]; then
  # --long looks into tarballs
  echo "usage: $0 file1.rpm file2.rpm [--long]"
  exit 1
fi

# get provides
rm -f $pkgA-provides $pkgB-provides
rpm -qp --provides $pkgA | sort > $pkgA-provides
rpm -qp --provides $pkgB | sort > $pkgB-provides
# get requires
rm -f $pkgA-requires $pkgB-requires
rpm -qp --requires $pkgA | sort > $pkgA-requires
rpm -qp --requires $pkgB | sort > $pkgB-requires
# get filelists (cut timestamps and linkcounts out)
rm -f $pkgA-filelist $pkgB-filelist
rpm -qpvl $pkgA | cut -c1-11,17-46,60- | sort -t/ -k2 > $pkgA-filelist
rpm -qpvl $pkgB | cut -c1-11,17-46,60- | sort -t/ -k2 > $pkgB-filelist
# extract package to separate roots
rm -rf $pkgA-root $pkgB-root
mkdir $pkgA-root $pkgB-root
rpm2cpio $pkgA | (cd $pkgA-root; cpio -id) 2> /dev/null > /dev/null
rpm2cpio $pkgB | (cd $pkgB-root; cpio -id) 2> /dev/null > /dev/null
# get "file" output
rm -f $pkgA-file $pkgB-file
(cd $pkgA-root; find . -type f -exec file {} \; | sort -u) 2> /dev/null > $pkgA-file
(cd $pkgB-root; find . -type f -exec file {} \; | sort -u) 2> /dev/null > $pkgB-file
# get "sha1sum" output
rm -f $pkgA-sha1sum $pkgB-sha1sum
(cd $pkgA-root; find . -type f -exec sha1sum {} \; | sort -u) 2> /dev/null > $pkgA-sha1sum
(cd $pkgB-root; find . -type f -exec sha1sum {} \; | sort -u) 2> /dev/null > $pkgB-sha1sum
# get ldd output
rm -f $pkgA-ldd $pkgB-ldd
(cd $pkgA-root; cat ../$pkgA-file | grep ELF | cut -d: -f1 | xargs ldd | sort -u) 2> /dev/null > $pkgA-ldd
(cd $pkgB-root; cat ../$pkgB-file | grep ELF | cut -d: -f1 | xargs ldd | sort -u) 2> /dev/null > $pkgB-ldd
# get nm output (cut addresses out)
rm -f $pkgA-nm $pkgB-nm
(cd $pkgA-root; cat ../$pkgA-file | grep ELF | cut -d: -f1 | xargs nm | cut -c10- | sort -u) 2> /dev/null > $pkgA-nm
(cd $pkgB-root; cat ../$pkgB-file | grep ELF | cut -d: -f1 | xargs nm | cut -c10- | sort -u) 2> /dev/null > $pkgB-nm

# print report
(echo ===============================================================================
echo Differences between:
echo
echo $pkgA
echo $pkgB
echo
if ! diff -q $pkgA-provides $pkgB-provides 2> /dev/null > /dev/null; then
    echo -------------------------------------------------------------------------------
    echo RPM Provides:
    echo
    diff -ub $pkgA-provides $pkgB-provides
    echo
fi
if ! diff -q $pkgA-requires $pkgB-requires 2> /dev/null > /dev/null; then
    echo -------------------------------------------------------------------------------
    echo RPM Requires:
    echo
    diff -ub $pkgA-requires $pkgB-requires
    echo
fi
if ! diff -q $pkgA-file $pkgB-file 2> /dev/null > /dev/null; then
    echo -------------------------------------------------------------------------------
    echo 'File Types (file):'
    echo
    diff -ub $pkgA-file $pkgB-file
    echo
fi
if ! diff -q $pkgA-sha1sum $pkgB-sha1sum 2> /dev/null > /dev/null; then
    echo -------------------------------------------------------------------------------
    echo 'File checksums (check if the checksums for the tarballs have changed):'
    echo
    diff -ub $pkgA-sha1sum $pkgB-sha1sum
    echo
fi
if ! diff -q $pkgA-ldd $pkgB-ldd 2> /dev/null > /dev/null; then
    echo -------------------------------------------------------------------------------
    echo 'Dynamic Link Libraries (ldd):'
    echo
    diff -ub $pkgA-ldd $pkgB-ldd
    echo
fi
if ! diff -q $pkgA-nm $pkgB-nm 2> /dev/null > /dev/null; then
    echo -------------------------------------------------------------------------------
    echo 'Symbol Tables (nm):'
    echo
    diff -ub $pkgA-nm $pkgB-nm
    echo
fi
if ! diff -q $pkgA-filelist $pkgB-filelist 2> /dev/null > /dev/null; then
    echo -------------------------------------------------------------------------------
    echo RPM File Lists:
    echo
    diff -ub $pkgA-filelist $pkgB-filelist 2> /dev/null
    echo
fi
if ! diff -qr $pkgA-root $pkgB-root 2> /dev/null > /dev/null; then
  if [ "$3" = "--long" ]; then
    # 20041214 hack by pekkas@netcore.fi to look inside tarballs and compare them as well if any changes
    # XXX: could also check only if new sha1sums for binaries 
    find . -name '*gz*' | xargs gunzip 2> /dev/null
    find . -name '*bz2*' | xargs bunzip2 2> /dev/null
    tarballs=`find . -name '*.tar'`
    cdir=`pwd`
    if [ -n "$tarballs" ]; then
	for i in $tarballs; do
		cd `dirname $i`
		tar xf `basename $i`
		cd $cdir
	done
    fi
  fi
    echo -------------------------------------------------------------------------------
    echo "RPM Packaged Files (including inside the tarballs):"
    echo
    diff -urNb $pkgA-root $pkgB-root 2> /dev/null
    echo
fi
echo ===============================================================================
) > $pkgB-diff.txt

rm -f $pkgA-provides $pkgB-provides
rm -f $pkgA-requires $pkgB-requires
rm -f $pkgA-filelist $pkgB-filelist
rm -rf $pkgA-root $pkgB-root
rm -f $pkgA-file $pkgB-file
rm -f $pkgA-sha1sum $pkgB-sha1sum
rm -f $pkgA-ldd $pkgB-ldd
rm -f $pkgA-nm $pkgB-nm

