Hi,

Quoting Joey Hess (2014-10-09 19:09:47)
> If you can do it without failing when debhelper is used with an older version
> of dpkg-dev, then that seems the right approach. Otherwise, it will make
> backporting debhelper harder.
> 
> Maybe just avoid loading Dpkg::BuildProfiles unless DEB_BUILD_PROFILES is
> set?

instead of checking DEB_BUILD_PROFILES, I check whether the package contains
the Build-Profiles field because even if the DEB_BUILD_PROFILES variable is
set, it has no effect (as far as debhelper is concerned) without a binary
package stanza with a non-empty Build-Profiles field.

Please see the attached patch. I tested in under Wheezy and it seems to do the
right thing and throw an error when encountering a package with a
Build-Profiles field and work as usual otherwise.

Thanks!

cheers, josch
From b2436f60d9d1e5e677b594e0d2bb7e9f2b635d36 Mon Sep 17 00:00:00 2001
From: josch <[email protected]>
Date: Fri, 10 Oct 2014 08:38:51 +0200
Subject: [PATCH] use libdpkg-perl to parse and evaluate build profiles

---
 Debian/Debhelper/Dh_Lib.pm | 60 ++++++++++++++++------------------------------
 debian/changelog           | 13 ++++++++++
 debian/control             |  2 +-
 3 files changed, 35 insertions(+), 40 deletions(-)

diff --git a/Debian/Debhelper/Dh_Lib.pm b/Debian/Debhelper/Dh_Lib.pm
index 6a79c9c..8627906 100644
--- a/Debian/Debhelper/Dh_Lib.pm
+++ b/Debian/Debhelper/Dh_Lib.pm
@@ -764,44 +764,6 @@ sub buildos {
 	}
 }
 
-# Passed a list of profiles to match against, returns true if
-# DEB_BUILD_PROFILES environment variable matched
-sub buildprofilesmatch {
-	my %debbuildprofiles = ();
-	if (exists $ENV{'DEB_BUILD_PROFILES'}) {
-		foreach my $profile (split(/\s+/, $ENV{'DEB_BUILD_PROFILES'})) {
-			$debbuildprofiles{$profile} = 1;
-		}
-	}
-
-	my $packageprofilesstr = shift;
-	my $package = shift;
-	my @packageprofiles = split(/\s+/, $packageprofilesstr);
-	my $err = sub { error("Build-Profiles field for package $package contains both positive and negative entries"); };
-	if ($#packageprofiles < 0 || $packageprofiles[0] =~ /^!/) {
-		# package profiles list is negative or empty
-		foreach my $packageprofile (@packageprofiles) {
-			$packageprofile =~ /^!(.*)$/ || &{$err}();
-			if ($debbuildprofiles{$1}) {
-				return 0;
-			}
-		}
-		return 1;
-	}
-	else {
-		# package profiles list is positive
-		foreach my $packageprofile (@packageprofiles) {
-			if ($packageprofile =~ /^!/) {
-				&{$err}();
-			}
-			if ($debbuildprofiles{$packageprofile}) {
-				return 1;
-			}
-		}
-		return 0;
-	}
-}
-
 # Returns source package name
 sub sourcepackage {
 	open (CONTROL, 'debian/control') ||
@@ -842,6 +804,12 @@ sub getpackages {
 	my $build_profiles;
 	my @list=();
 	my %seen;
+	my @profiles=();
+	my @restrictions=();
+	my $profile_is_concerned;
+	if ($ENV{'DEB_BUILD_PROFILES'}) {
+		@profiles=split /\s+/, $ENV{'DEB_BUILD_PROFILES'};
+	}
 	open (CONTROL, 'debian/control') ||
 		error("cannot read debian/control: $!\n");
 	while (<CONTROL>) {
@@ -858,6 +826,7 @@ sub getpackages {
 			}
 			$package_type="deb";
 			$build_profiles="";
+			$profile_is_concerned=1;
 		}
 		if (/^Architecture:\s*(.*)/) {
 			$arch=$1;
@@ -865,8 +834,21 @@ sub getpackages {
 		if (/^(?:X[BC]*-)?Package-Type:\s*(.*)/) {
 			$package_type=$1;
 		}
+		# rely on libdpkg-perl providing the parsing functions because
+		# if we work on a package with a Build-Profiles field, then a
+		# high enough version of dpkg-dev is needed anyways
 		if (/^Build-Profiles:\s*(.*)/) {
 		        $build_profiles=$1;
+			eval {
+				require Dpkg::BuildProfiles;
+				@restrictions=Dpkg::BuildProfiles::parse_build_profiles($build_profiles);
+				if (@restrictions) {
+					$profile_is_concerned=Dpkg::BuildProfiles::evaluate_restriction_formula(\@restrictions, \@profiles);
+				}
+			};
+			if ($@) {
+				error("The package $package has a Build-Profiles field. Require libdpkg-perl >= 1.17.14");
+			}
 		}
 
 		if (!$_ or eof) { # end of stanza.
@@ -882,7 +864,7 @@ sub getpackages {
 					     ($arch ne 'all' &&
 			                      samearch(buildarch(), $arch)))) ||
 			     ! $type) &&
-			    buildprofilesmatch($build_profiles, $package)) {
+			    $profile_is_concerned) {
 				push @list, $package;
 				$package="";
 				$arch="";
diff --git a/debian/changelog b/debian/changelog
index d1d37fc..08ada10 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,16 @@
+debhelper (9.20140817+nmu1) UNRELEASED; urgency=medium
+
+  * Non-maintainer upload.
+  * Depend on libdpkg-perl (>= 1.17.14) for build profiles support. Note to
+    backporters: If you remove that dependency, debhelper will throw an error
+    when a binary package stanza in debian/control has the Build-Profiles
+    field.
+  * Use libdpkg-perl functionality to parse the content of the Build-Profiles
+    field, if there is one. In that case, use libdpkg-perl to evaluate whether
+    the binary package should be built or not.
+
+ -- Johannes Schauer <[email protected]>  Thu, 09 Oct 2014 23:27:40 +0200
+
 debhelper (9.20140817) unstable; urgency=medium
 
   * Added Portuguese translation of the man pages, by Américo Monteiro.
diff --git a/debian/control b/debian/control
index 5a32032..c900556 100644
--- a/debian/control
+++ b/debian/control
@@ -11,7 +11,7 @@ Homepage: http://kitenet.net/~joey/code/debhelper/
 
 Package: debhelper
 Architecture: all
-Depends: ${perl:Depends}, ${misc:Depends}, file (>= 3.23), dpkg (>= 1.16.2), dpkg-dev (>= 1.17.0), binutils, po-debconf, man-db (>= 2.5.1-1)
+Depends: ${perl:Depends}, ${misc:Depends}, file (>= 3.23), dpkg (>= 1.16.2), dpkg-dev (>= 1.17.0), binutils, po-debconf, man-db (>= 2.5.1-1), libdpkg-perl (>= 1.17.14)
 Suggests: dh-make
 Conflicts: dpkg-cross (<< 1.18), python-support (<< 0.5.3), python-central (<< 0.5.6), automake (<< 1.11.2)
 Multi-Arch: foreign
-- 
2.0.1

Reply via email to