#!/bin/csh -f
# $NetBSD: pkgconflict,v 1.2 2001/04/10 14:16:08 wennmach Exp $
# 
# pkgconflict: A script to find conflicting packages in pkgsrc
# Author: Lex Wennmacher <wennmach@netbsd.org>
#

set PREFIX=@PREFIX@

if ($#argv > 1) then
    echo Usage: pkgconflict [BASEDIR]
    exit -1
endif

# BASEDIR is the directory where the packages databases live
# The default location in /var/db/pkg, but can be changed to
# a different directory, e. g. to the place where the bulk builds
# saved the packages databases
if ($#argv == 1) then
    set BASEDIR=$1
else
    set BASEDIR="/var/db/pkg"
endif

if (! -d $BASEDIR) then
    echo pkgconflict: error: BASEDIR, $BASEDIR, does not exist.
    exit -1
endif

psql -l >& /dev/null
if ($status != 0) then
    echo pkgconflict: error: PostgreSQL must be installed and configured."
    exit -1
endif

if (! -x $PREFIX/lib/dewey_cmp.so) then
    echo pkgconflict: error: no executable $PREFIX/lib/dewey_cmp.so
    exit -1
endif

set testfile=.test.$$
rm -f $testfile
touch $testfile
if (! -e $testfile) then
# XXX if (! -w .) should be simpler, but I'm not sure if it really works
    echo pkgconflict: error: local directory must be writable.
    exit -1
endif
rm -f $testfile

echo pkgconflict: started `date`
echo " "

if (! -d RCS) mkdir RCS

rm -f pkgfiles
touch pkgfiles

rm -f registered_conflicts
touch registered_conflicts

foreach dir ($BASEDIR/*)
    if (-d $dir) then
        set basename=$dir:t
	echo processig $basename
        set contents=$dir/+CONTENTS
        if (-e $contents) then
            awk '/^@cwd/	{cwd=$2} \
                 /^@name/	{name=$2} \
                 /^@ignore/	{skip=1} \
                 /^[^@].*$/	{if (skip==1) skip=0; else print name "\t" cwd "/" $1}' \
                $contents >> pkgfiles
            awk '/^@name/	{name=$2} \
                 /^@pkgcfl/	{print name "\t" $2} \
                 END {print name "\t" substr(name, 0, match(name, "-[^-]*$")) "*"}' \
                $contents >> registered_conflicts
        endif
    endif
end

echo " "

if (-e CFL-files) ci -l -t-version0 -m"script-based checkin" CFL-files
rm -f CFL-files

if (-e CFL-count) ci -l -t-version0 -m"script-based checkin" CFL-count
rm -f CFL-count

echo " "
echo pkgconflict: Done processing packages `date`
echo pkgconflict: Invoking PostgreSQL to generate database summaries.
echo " "

set DATABASE=tmp.$$
createdb $DATABASE
psql $DATABASE << --EOI--
create function
    pkg_cmp(text, text)
    returns bool
    as '$PREFIX/lib/dewey_cmp.so'
    language 'C';
create operator ~~~ (
    leftarg = text,
    rightarg = text,
    procedure = pkg_cmp); 
create table pkgfiles (
    pkg text, file text);
copy pkgfiles from '`pwd`/pkgfiles';
create table registered_conflicts (
    pkg text, pattern text);
copy registered_conflicts from '`pwd`/registered_conflicts';
\o CFL-files
\qecho 'CFL-files table generated `date`'
\qecho 'This table contains:'
\qecho '    a pair of conflicting packages (first 2 columns)'
\qecho '    name of the common file        (third column)'
\qecho ' '
select
    p1.pkg as pkg1, p2.pkg as pkg2, p1.file
    from pkgfiles p1, pkgfiles p2
    where (p1.file = p2.file)
        and (not exists (
            select
                r.pkg
                from registered_conflicts r
                where (p1.pkg = r.pkg) and (p2.pkg ~~~ r.pattern)))
    order by 1 asc;
\o CFL-count
\qecho 'CFL-count table generated `date`'
\qecho 'This table contains:'
\qecho '    a pair of conflicting packages (unique) (first 2 columns)'
\qecho '    the count of conflicting files          (third column)'
\qecho ' '
select
    distinct on (p1.pkg, p2.pkg)
    p1.pkg, p2.pkg, count(p1.file)
    from pkgfiles p1, pkgfiles p2
    where (p1.file = p2.file)
        and not exists (
            select r.pkg from
            registered_conflicts r
            where (p1.pkg = r.pkg) and (p2.pkg ~~~ r.pattern))
    group by p1.pkg, p2.pkg
    order by 1 asc;    
\o null
drop table pkgfiles;
drop table registered_conflicts;
\q
--EOI--
dropdb $DATABASE
rm -f null pkgfiles registered_conflicts

echo " "
echo pkgconflict: Done `date`.
exit
