#!/bin/sh
# Compare the list of packages provided in two distribution.
#
# Copyright (C) 2008 Frank Lin PIAT <fpiat@klabs.be>
# latest version is available from:
#     http://www.klabs.be/~fpiat/linux/comp-dist/
#
# 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, see <http://www.gnu.org/licenses/>.

# Credits:
#  - based on an idea from:
#    http://tablets-dev.nokia.com/changes/23-14_vs_50-2_comparison.html
# TODO:
#  - Process non-free, especially to list packages moved from main
#    to contrib or non-free
#  - For removed packages, add link to the RM's hint.
#  - For new packages, add link to ITP(?).
# Changelog:
#  0.01 - Add $Arch in html_header
#  0.00 - Initial release
set -e

if [ "$1" = "" -o "$2" = "" -o "$3" != "" ]; then
	echo "You must specify 2 distribution to compare, like " >&2
	echo "$0 etch lenny"
	exit 1
fi

P=$1
C=$2
arch=${arch:-i386}

# ### Declare some funcations ###
colorize_table_lines() {
	while read l ; do
		if [ "$u" = "#fff" ]; then
			u="#eee"
		else u="#fff"
		fi
		echo $l | sed -e "s/@TRSTYLE@/style=\"background-color:$u\"/"
	done
}

html_header() {
cat <<XXX
<html><head>
<title>$1</title>
<style>
/* <!-- */
.removed	{background-color:#ff0000}
.upgraded	{background-color:#00ff00}
.newbinpkg 	{background-color:#8888ff; color:#ffffff}
.newsrcpkg 	{background-color:#0000ff; color:#ffffff}
.replaced	{background-color:#ff8888}
th      	{background-color:#000000; border-bottom:2pt solid #ffcc00; font-size:12pt; color:#ffcc00}
th font		{color:inherit}
table.legend	{border-collapse:collapse; border: 2px solid #444444; font-size:smaller}
h1		{font-size:16pt}
/* --> */
</style>
</head>
<body>
<h1>$1</h1>
<table class="legend" border="1" align="right">
<tr><td valign="top" colspan="2"><b>The use of colour coding in tables:</b><div style="display:none;visiblility:hidden">(requires CSS compatible web browser)</div></td></tr>
<tr><td class="newsrcpkg">&nbsp;&nbsp;</td><td><a href="new-src.html"><b>New Source packages</b></a></td></tr>
<tr><td class="newbinpkg">&nbsp;&nbsp;</td><td><a href="new-bin.html" title="New package from a source package that was present in $P">New Binary packages</a></td></tr>
<tr><td class="upgraded">&nbsp;&nbsp;</td><td rowspan="2"><a href="upgraded.html">Upgraded packages and unchanged</a></td></tr>
<tr><td>&nbsp;&nbsp;</td></tr> 
<tr><td class="replaced">&nbsp;&nbsp;</td><td><a href="replaced.html">Replaced packages</a></td></tr>
<tr><td class="removed">&nbsp;&nbsp;</td><td><a href="removed.html"><b>Removed Packages</b></a></td></tr>
<tr><td colspan="2"><a href="full-list.html">Full list (heavy page)</a></td></tr>
</table>
<p><br/>
</p>
<table width="100%" style="table-layout:fixed; width:100%; margin:0">
<caption><b>Comparison of packages in <i>$P</i> and <i>$C</i></b></caption>
<tr>
	<th width="40%"><font color="#ff6644">Package</font></th>
	<th width="30%"><font color="#ff6644">$P</font></th>
	<th width="30%"><font color="#ff6644">$C</font></th>
</tr>
XXX
}

html_footer() {
	echo "</table></body></html>"
}

#Fetch Packages list
for d in $C $P ; do
	case $d in
		sarge|woody|potato|slink|hamm|bo|rex|buzz)
			baseurl=http://archive.debian.org/debian/dists/$d
			;;
		*)
			baseurl=http://ftp.fr.debian.org/debian/dists/$d
	esac
	[ ! -f ${d}.Packages ] && \
		wget -q -O ${d}_DistRelease $baseurl/Release || true
		wget -q -O ${d}_Release $baseurl/main/binary-${arch}/Release || true
		wget -O ${d}.Packages.gz $baseurl/main/binary-${arch}/Packages.gz && \
		gzip -d ${d}.Packages.gz
	grep -E "^(Package|[Vv]ersion):" ${d}.Packages \
		| tr -d " "\
		| tr "\n" "/" \
		| sed -e 's/Package:/\n/g' -e 's/[Vv]ersion:/\t/g' -e 's/([^)]*)//' \
		| tr -d "/" \
		| sort -k 1b,1 > ${d}_ver

	grep -E "^(Package|[Ss]ource):" ${d}.Packages \
		| tr -d " "\
		| tr "\n" "/" \
		| sed -e 's/Package:/\n/g' -e 's/[Ss]ource:/\t/g' \
		| tr -d "/" \
		| sed -e 's/^[^\t]*$/\0\t\0/' \
		| sort -k 2b,2 > ${d}_pkg-to-source
done


grep -E "^[Ss]ource:" ${P}.Packages \
	| sed -e "s/^[^:]\+:[[:blank:]]*\([^ ]\+\).*$/\1/" \
	| sort -u > ${P}.source

join -1 1 -2 2 -o "2.1 2.2" ${P}_pkg-to-source ${C}_pkg-to-source \
	| tr " " "\t" \
	| sort -k 1b,1 > ${C}_source-to-pkg


#Build the list of "Provided" packages in the "New" distribution.
grep -E "^P(ackage|rovides):" ${C}.Packages | tr -d " " \
	| grep "Provides:" -B 1 \
	| while read l  ; do 
		[ "${l%:*}" = "Package" ] && pkg=${l#*:}
		[ "${l%:*}" = "Provides" ] && echo ${l#*:} | tr "," "\n" | sed -e "s/$/\t$pkg/"
	 done | sort -k 1b,1 > ${C}_Providedby

# Build a list of discountinued packages.
join -v 1 ${P}_ver ${C}_ver -j 1 > discontinued.lst

#Build a table of discontinued packages, that are Provided by another one.
p=""
new=""
join -v 1 ${P}_ver ${C}_ver -j 1 \
	| join -j 1 - ${C}_Providedby -o "1.1 2.2" \
	| tr " " ":" \
	| while read l ; do 
		s="${l%:*}"
		if [ "$p" != "$s" ] ; then
			echo "$p:$new" 
			p="$s"
			new="${l#*:}"
		else
			new="$new,${l#*:}"
		fi
	done | tr ":" "\t" > ${C}_Providedby2

join -j 1 discontinued.lst  ${C}_Providedby2 \
	| sed -e 's#^\(.*\) \(.*\) \(.*\)$#<tr @TRSTYLE@><td>\1</td><td>\2</td><td class=\"replaced\">Replaced,\&nbsp;see: \3</td></tr>#' \
	> replaced_pkg.htm

# Build a table of discontined packages
join -v 1 -j 1 discontinued.lst  ${C}_Providedby2 \
	| sed -e 's#^\(.*\) \(.*\)$#<tr @TRSTYLE@><td>\1</td><td>\2</td><td class=\"removed\">Removed</td></tr>#' \
	> removed_pkg.htm

# Build a table of upgraded (and unchanged) packages
join -j 1 ${P}_ver ${C}_ver \
	| while read pkg a b ; do
		if [ "$a" = "$b" ]; then
			u=""
		else
			u=" class=\"upgraded\""
		fi
		echo "<tr @TRSTYLE@><td>$pkg	</td><td>$a	</td><td$u>$b	</td></tr>"
	done > common_pkg.htm



# Build a list of New package.
join -j 1 -v 2 ${P}_ver ${C}_ver > new_pkg.lst

join -j 1 -o "1.1 1.2 2.2" new_pkg.lst ${C}_source-to-pkg \
	| while read pkg a b; do
		echo "<tr @TRSTYLE@><td>$pkg	</td><td>N/A	</td><td class=\"newbinpkg\">${a}	(src:${b})</td></tr>"
	done > new_binpkg.htm

join -v 1 -j 1 new_pkg.lst ${C}_source-to-pkg \
	| while read pkg a ; do
		echo "<tr @TRSTYLE@><td>$pkg	</td><td>N/A	</td><td class=\"newsrcpkg\">${a}	</td></tr>"
	done > new_srcpkg.htm


#Generate the output html files
html_header "New packages [source] ($P versus $C, for $arch)" > new-src.html
sort -k 1b,1 new_srcpkg.htm \
	| colorize_table_lines  >> new-src.html
html_footer >> new-src.html

html_header "New packages [binary] ($P versus $C, for $arch)" > new-bin.html
sort -k 1b,1 new_binpkg.htm \
	| colorize_table_lines  >> new-bin.html
html_footer >> new-bin.html

html_header "Upgraded and unchanged packages ($P versus $C, for $arch)" > upgraded.html
sort -k 1b,1 common_pkg.htm \
	| colorize_table_lines  >> upgraded.html
html_footer >> upgraded.html

html_header "Replaced  packages ($P versus $C, for $arch)" > replaced.html
sort -k 1b,1 replaced_pkg.htm \
	| colorize_table_lines  >> replaced.html
html_footer >> replaced.html


html_header "Removed packages ($P versus $C, for $arch)" > removed.html
sort -k 1b,1 removed_pkg.htm \
	| colorize_table_lines  >> removed.html
html_footer >> removed.html

html_header "Complete list ($P versus $C, for $arch)" > full-list.html
sort -k 1b,1 replaced_pkg.htm common_pkg.htm removed_pkg.htm new_srcpkg.htm new_binpkg.htm \
	| colorize_table_lines  >> full-list.html
html_footer >> full-list.html

rm discontinued.lst new_pkg.lst
rm ${C}_source-to-pkg ${C}_pkg-to-source ${P}_source-to-pkg ${P}_pkg-to-source
rm ${C}.Packages ${P}.Packages
rm ${C}_ver ${P}_ver
rm ${C}_Providedby ${C}_Providedby2
rm common_pkg.htm new_binpkg.htm new_srcpkg.htm removed_pkg.htm replaced_pkg.htm

