#!/usr/bin/perl -w

=head1 NAME

dh_golang - Generates Built-Using substvar

=cut

use strict;
use Debian::Debhelper::Dh_Lib; # not in core
use Dpkg; # not in core
use Dpkg::Control; # not in core
use Dpkg::Control::Info; # not in core
use Dpkg::Deps; # not in core
use Dpkg::Gettext; # not in core
use Scalar::Util qw(blessed); # in core since v5.7.3
use List::Util qw(first); # in core since v5.7.3

=head1 SYNOPSIS

B<dh_golang> [S<I<debhelper options>>]

=head1 DESCRIPTION

B<dh_golang> is a debhelper program which adds the misc:Built-Using substvar
based on the Build-Dependencies of your packages. Every package starting with
golang is queried for the precise version number.

As an example, if you Build-Depend on golang-pq-dev, the resulting
misc:Built-Using value (aside from the precise version number) will look like
this:

golang (= 2:1.1.1-1), golang-pq-dev (= 0.0~git20130606-1),

=head1 NOTES

The best way to invoke B<dh_golang> is by using B<dh --with=golang>.

=cut

init();

# This code was copied from dpkg-checkbuilddeps, see
# http://sources.debian.net/src/dpkg/1.18.1/scripts/dpkg-checkbuilddeps.pl/?hl=140#L140
sub parse_status {
    my $status = shift;

    my $facts = Dpkg::Deps::KnownFacts->new();
    local $/ = '';
    open(my $status_fh, '<', $status)
        or syserr(g_('cannot open %s'), $status);
    while (<$status_fh>) {
        next unless /^Status: .*ok installed$/m;

        my ($package) = /^Package: (.*)$/m;
        my ($version) = /^Version: (.*)$/m;
        my ($arch) = /^Architecture: (.*)$/m;
        my ($multiarch) = /^Multi-Arch: (.*)$/m;
        $facts->add_installed_package($package, $version, $arch,
                                      $multiarch);

        if (/^Provides: (.*)$/m) {
            my $provides = deps_parse($1, reduce_arch => 1, union => 1);
            next if not defined $provides;
            foreach (grep { $_->isa('Dpkg::Deps::Simple') }
                                 $provides->get_deps())
            {
                $facts->add_provided_package($_->{package},
                                    $_->{relation}, $_->{version},
                                    $package);
            }
        }
    }
    close $status_fh;

    return $facts;
}

############################################################################
# Generate misc:Built-Using substvar with the versions of all golang-*
# build-dependency packages.
############################################################################

my $built_using;

my $control = Dpkg::Control::Info->new();
my $source = $control->get_source();
my $build_depends = $source->{"Build-Depends"};
if (defined($build_depends) && $build_depends ne '') {
    my $facts;
    if ($Dpkg::VERSION >= 1.01) {
        $facts = parse_status($Dpkg::ADMINDIR . "/status");
    } else {
        $facts = parse_status($Dpkg::admindir . "/status");
    }

    sub flatten {
        my ($dep) = @_;
        if (blessed($dep) eq 'Dpkg::Deps::Simple') {
            return $dep->get_evaluation($facts) ? $dep->{package} : undef;
        }
        if (blessed($dep) eq 'Dpkg::Deps::OR') {
            # Return the first installed package.
            return first { defined($_) } map { flatten($_) } $dep->get_deps();
        }
        die 'Unexpected object (of type ' . blessed($dep) . '), has the Dpkg::Deps API changed?';
    }

    my $deps = deps_parse($build_depends, reduce_restrictions => 1, build_dep => 1);
    my $golang_deps = join(' ', grep { /^golang-/ }
                                map { flatten($_) }
                                $deps->get_deps());
    if ($golang_deps ne '') {
        $built_using = `dpkg-query -f='\${source:Package} (= \${source:Version}), ' -W $golang_deps`;
    }
}

# If there is an easier way to have a universal misc:Built-Using on all binary
# packages, I am happy to merge your patch :).
foreach my $package (@{$dh{DOPACKAGES}}) {
    addsubstvar($package, "misc:Built-Using", $built_using);
}

=head1 SEE ALSO

dh(1)

=head1 AUTHORS

Michael Stapelberg <stapelberg@debian.org>

=cut

# vim:ts=4:sw=4:et
