#!/usr/bin/perl

$ENV{'PATH'} = '/usr/local/bin:'.$ENV{'PATH'};
$ENV{'ACLOCAL_FLAGS'} = '-I /usr/local/share/aclocal';
# list in order of dependencies
$config_opts = '--enable-debug';
$module_opts{'gtk+'} = '--with-threads=posix --with-xinput=xfree --disable-static';
$module_opts{'gnome-libs'} = '--disable-static';
$module_opts{'gnome-print'} = '--disable-static';
$module_opts{'imlib'} = '--disable-static';
$module_opts{'bonobo'} = '--enable-oaf=yes';

$| = 1;

sub cvsclean {
    my ($dir) = @_;
    my (%files);
    my (@subdirs);

    if (!-e "$dir/CVS/Entries") {
	return;
    }
    open ENTRIES, "$dir/CVS/Entries";
    while (<ENTRIES>) {
	if (/^\/([^\/]+)\//) {
#	    print "File $dir/$1\n";
	    $files{$1} = 1;
	} elsif (/^D\/([^\/]+)\//) {
#	    print "Dir $dir/$1\n";
	    $files{$1} = 1;
	    push @subdirs, $1;
	}
    }
    close ENTRIES;
    opendir DIR, $dir;
    foreach $f (readdir DIR) {
	if ($f eq 'CVS' || $f eq '.' || $f eq '..') {
	    # skip
	} elsif ($files{$f}) {
#	    print "File $dir/$f in repo\n";
	} else {
	    print "Deleting $dir/$f\n";
	    if (-d "$dir/$f") {
		system "rm -rf $dir/$f";
	    } else {
		unlink "$dir/$f";
	    }
	}
    }
    closedir DIR;
    foreach $subdir (@subdirs) {
	cvsclean ("$dir/$subdir");
    }
#   print "$module cvsclean failed, status $status\n" if $status != 0;
}

sub update_cvs {
    my ($module) = @_;

    print "CVS updating $module\n";
    chdir "$ENV{'HOME'}/cvs";
    system "cvs -z3 co $module";
    if (!-s "$ENV{'HOME'}/cvs/$module") {
	print "$module doesn't exist!";
	return;
    }
    chdir "$ENV{'HOME'}/cvs/$module";
    system "cvs -z3 update -d";
}

sub try_build {
    my ($module) = @_;

    chdir "$ENV{'HOME'}/cvs/$module";
    $status = system "./autogen.sh $config_opts $module_opts{$module}";
    print "$module autogen failed, status $status\n" if $status != 0;
    return -1 if $status != 0;
    $status = system "make -k -j 3";
    $status = system "make -j 3";
    print "$module make failed, status $status\n" if $status != 0;
    return -1 if $status != 0;
# Now is a good time to try to uninstall
    $status = system "make install";
# I have ldconfig as a suid root wrapper around /sbin/ldconfig
    print "$module install failed, status $status\n" if $status != 0;
    return -1 if $status != 0;
    system "/sbin/ldconfig -n /usr/local/lib";
    return 0;
}

foreach $arg (@ARGV) {
    if ($arg eq '--build-only') {
	$build_only = 1;
    } elsif ($arg eq '--update-only') {
	$update_only = 1;
    } elsif ($arg =~ /^\-\-/) {
	die "Unrecognized option $arg\n";
    } else {
	push @modules, $arg;
    }
}

if (!@modules) {
    opendir CVS, "$ENV{'HOME'}/cvs";
    foreach $subdir (readdir CVS) {
	if ($subdir !~ /^\./ &&
	    -e "$ENV{'HOME'}/cvs/$subdir/CVS") {
	    push @modules, $subdir;
	}
    }
    closedir CVS;
}

# topo sort the modules in order of dependencies

@new_modules = ();
%modules = ();

foreach $module (@modules) {
    $modules{$module} = 1;
}

foreach $module ('glib', 'gtk+',
		 'gcmm', 'imlib',
		 'ORBit',
		 'audiofile',
		 'esound',
		 'gdk-pixbuf',
		 'gnome-libs',
		 'libgtop',
		 'control-center',
		 'libsigc++', 'gtk--',
		 'gnome-xml',
		 'libunicode',
		 'gnome-print',
		 'gtkhtml',
		 'gnome-core',
		 'gdome',
		 'oaf',
		 'gconf',
		 'gnome-vfs',
		 'bonobo',
		 'gob',
		 'medusa') {
    if ($modules{$module}) {
	push @new_modules, $module;
	$modules{$module} = 0;
    }
}

foreach $module (keys %modules) {
    if ($modules{$module}) {
	push @new_modules, $module;
    }
}

@modules = @new_modules;

if (!$build_only) {
    foreach $module (@modules) {
	update_cvs ($module);
    }
    print "\n";
}
# Now try to build.

if (!$update_only) {
    foreach $module (@modules) {
	chdir "$ENV{'HOME'}/cvs";
	cvsclean ($module);
	if (try_build ($module)) {
	    push @modules_error, $module;
	} else {
	    push @modules_ok, $module;
	}
    }
    print "Successfully installed: ".join (', ', @modules_ok)."\n";
    if (@modules_error) {
	print "Error installing: ".join (', ', @modules_error)."\n";
    }
    print "\n";
}

