#!/usr/bin/perl

=pod

=head1 NAME

grip-override.pl - apply the Debian override file to Emdebian Grip

=cut

use strict;
use warnings;
use LWP::Simple;
use LWP::Simple qw($ua);
use File::Basename;
use IO::Uncompress::Gunzip qw(gunzip $GunzipError) ;

use vars qw/ %tasks $override $uri $deb $z @list $suite_name 
 $prog $our_version $base $grip_name $mirror $skip /;
 
=head1 Synopsis

 grip-override.pl -c|--codename STRING -b|--base-path PATH [--grip-name STRING] [-m|--mirror MIRROR]
 grip-override.pl -?|-h|--help|--version

 Commands:
 -c|--codename STRING:     Codename of the distribution to override [required]
 -b|--base-path PATH:      path to the top level repository directory [required]

 -?|-h|--help|--version:   print this help message and exit

 Options:
   --grip-name STRING:     alternative name for the grip repository
 -m|--mirror MIRROR:       use a different Debian mirror for updates
                            [default: http://ftp.uk.debian.org/debian]

grip-override.pl downloads, parses and writes out the Debian ftp-master
override file for the specified codename for use by Emdebian Grip.
(Essentially, it removes all non-Tasks content.)

The codename is etch, lenny, squeeze, sid - not stable, testing or
unstable.

For the overrides to be used, the reprepro configuration for the Grip
repository must include a line for the override file:
e.g. for lenny
DebOverride: override.lenny.extra.main

Override files provide support for Tasks in the debian-installer
when using the Grip pre-seeding.

Other override functionality may be included in future versions.

=head1 Example

 $ grip-override.pl -c lenny -b /opt/reprepro/

Writes out /opt/reprepro/grip/conf/override.lenny.extra.main

 $ grip-override.pl -c sid -b /srv/repo/ --grip-name foo

Writes out /srv/repo/foo/conf/override.sid.extra.main

=cut

$prog = basename ($0);
$our_version = &scripts_version();
$grip_name = "grip";
$mirror='http://ftp.uk.debian.org/debian'; # default only

if (not @ARGV)
{
	&usageversion();
	exit 0;
}

while( @ARGV ) {
	$_= shift( @ARGV );
	last if m/^--$/;
	if (!/^-/) {
		unshift(@ARGV,$_);
		last;
	}
	elsif (/^(-\?|-h|--help|--version)$/) {
		&usageversion();
		exit (0);
	}
	elsif (/^(-b|--base-path)$/) {
		$base = shift;
	}
	elsif (/^(-c|--codename)$/) {
		$suite_name = shift;
	}
	elsif (/^(--grip-name)$/) {
		$grip_name = shift;
	}
	elsif (/^(-m|--mirror)$/) {
		$mirror = shift;
	}
	elsif (/^(--skip-export)$/) {
		$skip++;
	}
	else {
		die "$prog: Unknown option $_.\n";
	}
}

die "$prog: ERR: Please specify an existing directory for the base-path.\n"
	if (not defined $base);

$base .= '/' if ("$base" !~ m:/$:);
die "$prog: ERR: Please specify an existing directory for the base-path: $base\n"
	if (not -d $base);

die ("$prog: ERR: Specify a codename, not a distribution name. e.g. lenny, not testing.\n")
	if ((not defined $suite_name) or 
	($suite_name =~ /unstable|testing|stable/));

die ("$prog: ERR: Cannot find Grip configuration directory.\n")
	if (not -d "${base}${grip_name}/conf/");

$override = "override.${suite_name}.extra.main";

die ("$prog: ERR: Override file exists: ${base}${grip_name}/conf/$override.\n".
	"Remove the file and run $prog again.\n")
	if (-f "${base}${grip_name}/conf/$override");

my $dir = `mktemp -t -d "grip-override.XXXXXX"`;
chomp ($dir);
chdir ($dir);

$uri = "${mirror}/indices/${override}.gz";
$deb = lwpprogress($uri);
if (is_error($deb))
{
	chdir ("../");
	rmdir ($dir);
	die "Error. Failed to locate $uri.\n";
}

$z = new IO::Uncompress::Gunzip "${override}.gz"
	or die "IO::Uncompress::Gunzip failed: $GunzipError\n";
@list=<$z>;
# DebOverride: override.${suite_name}.extra.main
open (OVR, ">${base}${grip_name}/conf/$override")
	or die ("Unable to write to ${base}${grip_name}/conf/$override :$!\n");
foreach my $override (@list)
{
	next if ($override !~ /Task/);
	chomp ($override);
	$override =~ s/^ +//;
	if ($override =~ /^[\w\-\.\+]+\s+Task\s+.+$/)
	{
		print OVR "$override\n";
	}
}
close (OVR);

unlink ("${override}.gz");
chdir ("../");
rmdir ($dir);

# export
system ("reprepro -v -b ${base}${grip_name} export")
	if (not defined $skip);

=head1 Copyright and Licence

 Copyright (C) 2007-2009  Neil Williams <codehelp@debian.org>

 This package 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 3 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/>.

=cut

sub lwpprogress
{
	my $url = shift;
	my $errcode;
	my $uri = URI->new($url);
	my $path = $uri->path;
	my $output = 0;
	my $target_is_set = 0;
	my $next_so_far = 0;
	$path =~ s{.*/}{};
	return unless length $path;
	unlink ($path) if -e $path;
	open my $outhandle, ">", $path or die "Cannot create $path: $!";
	$errcode = $ua->get ($url,":content_cb" => sub {
		my ($chunk, $response, $protocol) = @_;
		print {$outhandle} $chunk;});
}

sub scripts_version {
	my $query = `dpkg-query -W -f='\${Version}' emdebian-grip-server`;
	(defined $query) ? return $query : return "";
}

sub usageversion
{
	print(STDERR <<END)
$prog - apply the Debian override file to Emdebian Grip
version $our_version

Syntax: $prog -c|--codename STRING -b|--base-path PATH [--grip-name STRING]
        $prog -?|-h|--help|--version

Commands:
-c|--codename STRING:     Codename of the distribution to override [required]
-b|--base-path PATH:      path to the top level grip directory [required]

-?|-h|--help|--version:   print this help message and exit

Options:
   --grip-name STRING:    alternative name for the grip repository
-m|--mirror MIRROR:       use a different Debian mirror for updates
                           [default: http://ftp.uk.debian.org/debian]
   --skip-export:         create the override file but do not call
                            'reprepro export'

$prog downloads, parses and writes out the Debian ftp-master
override file for the specified codename for use by Emdebian Grip.

The codename is etch, lenny, squeeze, sid - not stable, testing or
unstable.

For the overrides to be used, the reprepro configuration for the Grip
repository must include a line for the override file:
e.g. for lenny
DebOverride: override.lenny.extra.main

END
	or die "$0: failed to write usage: $!\n";
}
