# version-substvars -- lintian check script -*- perl -*-
#
# Copyright (C) 2006 Adeodato Simó
#
# This program 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 2 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, you can find it on the World Wide
# Web at http://www.gnu.org/copyleft/gpl.html, or write to the Free
# Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
# MA 02110-1301, USA.

# SUMMARY
# =======
#
# What breaks
# -----------
#
# (b1) any -> any (= ${source:Version})		 -> use b:V
# (b2) any -> all (= ${Source-Version}) [or b:V] -> use s:V
# (b3) all -> any (= ${either-of-them})		 -> use (>= ${s:V}),
#						    optionally (<< ${s:V}.1~)
#
# Always warn on ${Source-Version} even if it doesn't break since the substvar
# is now considered deprecated.

package Lintian::version_substvars;
use strict;

use Util;
use Tags;

sub run {

my $pkg = shift;
my $type = shift;
my $info = shift;

my $binpkgs = $info->binaries;

my @dep_fields = qw(depends pre-depends recommends suggests conflicts replaces);

foreach (keys %$binpkgs) {
	my ($pkg1, $pkg1_is_any, $pkg2, $pkg2_is_any, $substvar_strips_binNMU);

	$pkg1 = $_;
	$pkg1_is_any = ($info->binary_field($pkg1, 'architecture') ne 'all');

	foreach my $field (@dep_fields) {
		next unless $info->binary_field($pkg1, $field);
		if ($info->binary_field($pkg1, $field) =~ m/\${Source-Version}/) {
			tag "substvar-source-version-is-deprecated", $pkg1;
		}
	}

	foreach (split(m/,/, $info->binary_field($pkg1, 'pre-depends').", ".
		       $info->binary_field($pkg1, 'depends'))) {
		next unless m/(\S+)\s*\(\s*=\s*\${((?:Source-|source:|binary:)Version)}/x;

		$pkg2 = $1;
		$substvar_strips_binNMU = ($2 eq 'source:Version');

		# We can't test dependencies on packages whose names are
		# formed via substvars expanded during the build.  Assume
		# those maintainers know what they're doing.
		if (not $info->binary_field($pkg2, 'architecture')) {
			tag "version-substvar-for-external-package", "$pkg1 -> $pkg2"
				unless ($pkg2 =~ /\$\{\S+\}/);
			next;
		}
		$pkg2_is_any = ($info->binary_field($pkg2, 'architecture') !~ m/^all$/);

		if ($pkg1_is_any) {
			if ($pkg2_is_any and $substvar_strips_binNMU) {
				# (b1) any -> any (= ${source:Version})
				tag "not-binnmuable-any-depends-any", "$pkg1 -> $pkg2";
			} elsif (not $pkg2_is_any and not $substvar_strips_binNMU) {
				# (b2) any -> all (= ${Source-Version}) [or b:V]
				tag "not-binnmuable-any-depends-all", "$pkg1 -> $pkg2";
			}
		} elsif ($pkg2_is_any) {
			# (b3) all -> any (= ${either-of-them})
			tag "not-binnmuable-all-depends-any", "$pkg1 -> $pkg2";
		}
	}
}

}

1;

# Local Variables:
# indent-tabs-mode: t
# cperl-indent-level: 8
# End:
# vim: syntax=perl sw=4 ts=4 noet shiftround
