#!/usr/bin/perl -w
# -*- Mode: Perl; perl-indent-level: 8; indent-tabs-mode: t -*-

=head1 NAME

eos-metapackage - create metapackages from depends files

=cut

use strict;

use Debian::Debhelper::Dh_Lib;
use Dpkg::Deps qw( deps_parse deps_iterate );

=head1 SYNOPSIS

B<eos-metapackage> [S<B<debhelper options>>]

B<eos-metapackage --check-params>

=head1 DESCRIPTION

eos-metapackage is a debhelper program that generates ${eos:Depends}
substitutions and adds them to substvars files.

The program reads dependency files for each package. The dependency
files are named after the package with -depends and -recommends
suffixes. They generate "${eos:Depends}" and "${eos:Recommends}"
variables to be substitued in the package's control file. Both files are
optional, so eos-metapackage can be called for all packages.

The format of the dependency files is one package per line. Lines
beginning with "#" are skipped. Lines beginning with "include" will read
in the referenced file.

If run with C<--check-params>, rather than populating substvar files, the
program will check whether all external packages for the current
architecture listed in dependency files are installable.

=head1 EXAMPLES

eos-metapackage must be called before C<dh_installdeb>.

	override_dh_installdeb:
		./eos-metapackage
		dh_installdeb

=cut

my $CheckDeps = 0;
init(options => {
	"check-deps" => \$CheckDeps,
});

sub get_depends {
	my $name=shift;
	my @deps;

	open(my $depends, "<", $name) or die "Can't open $name: $!";
	while (<$depends>) {
		chomp;
		s/^\s*//; s/\s*$//;

		# Skip comments
		next if /^#/;

		# Skip blank lines
		next if /^$/;

		if (/^include\s/) {
			# Read in included file
			my $include = (split())[1];
			push @deps, (get_depends("$include"));
		} else {
			# Add to the deps list
			push @deps, $_;
		}
	}
	close($depends);

	return @deps;
}

sub check_installable {
	my ($depfile, $deps) = @_;
	my @cmd;
	my %options = (
		# ignore packages for foreign architectures; they may not be
		# installable on this architecture, and that's OK.
		reduce_restrictions => 1,
	);

	verbose_print("checking all packages in $depfile are installable");
	deps_iterate(deps_parse($deps, %options), sub {
		my ($d) = @_;
		my $package = $d->{package};

		if (grep { $package eq $_ } @{$dh{DOPACKAGES}}) {
			verbose_print("skipping '$package' which comes from this project");
		} else {
			push @cmd, $package;
		}

		return 1; # keep iteratin'
	});

	if (@cmd > 0) {
		unshift(@cmd, ("apt-get", "install", "--no-install-recommends", "--download-only", "--dry-run", "--quiet"));
		doit(@cmd);
	}
}

sub subst_depends {
	my $package=shift;
	my $type=shift;
	my $var=shift;
	my $depfile="$package-$type";
	my @deps;
	my $deps;

	# Allow the toplevel file to be missing (e.g., -recommends)
	@deps = get_depends("$depfile") if -e "$depfile";
	$deps = join(', ', @deps);

	if ($CheckDeps) {
		check_installable($depfile, $deps);
	} else {
		addsubstvar($package, $var, $deps);
	}
}

foreach my $package (@{$dh{DOPACKAGES}}) {
	subst_depends($package, "depends", "eos:Depends");
	subst_depends($package, "recommends", "eos:Recommends");
	subst_depends($package, "suggests", "eos:Suggests");
}

=head1 SEE ALSO

L<debhelper(7)>

=head1 AUTHOR

Colin Watson <cjwatson@ubuntu.com>

Copyright (C) 2009 Canonical Ltd., licensed under the GNU GPL v2 or later.

=cut
