summaryrefslogtreecommitdiff
path: root/scripts/Dpkg/Deps.pm
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/Dpkg/Deps.pm')
-rw-r--r--scripts/Dpkg/Deps.pm98
1 files changed, 98 insertions, 0 deletions
diff --git a/scripts/Dpkg/Deps.pm b/scripts/Dpkg/Deps.pm
index 356ea8301..7fefd109b 100644
--- a/scripts/Dpkg/Deps.pm
+++ b/scripts/Dpkg/Deps.pm
@@ -53,6 +53,7 @@ our $VERSION = '1.02';
use Dpkg::Version;
use Dpkg::Arch qw(get_host_arch get_build_arch);
+use Dpkg::BuildProfiles qw(get_build_profiles);
use Dpkg::ErrorHandling;
use Dpkg::Gettext;
@@ -195,6 +196,30 @@ architecture. This implicitely strips off the architecture restriction
list so that the resulting dependencies are directly applicable to the
current architecture.
+=item use_profiles (defaults to 1)
+
+Take into account the profile restriction part of the dependencies. Set
+to 0 to completely ignore that information.
+
+=item build_profiles (defaults to no profile)
+
+Define the active build profiles. By default no profile is defined.
+
+=item reduce_profiles (defaults to 0)
+
+If set to 1, ignore dependencies that do not concern the current build
+profile. This implicitly strips off the profile restriction list so
+that the resulting dependencies are directly applicable to the current
+profiles.
+
+=item reduce_restrictions (defaults to 0)
+
+If set to 1, ignore dependencies that do not concern the current set of
+restrictions. This implicitly strips off any restriction list so that the
+resulting dependencies are directly applicable to the current restriction.
+This currently implies C<reduce_arch> and C<reduce_profiles>, and overrides
+them if set.
+
=item union (defaults to 0)
If set to 1, returns a Dpkg::Deps::Union instead of a Dpkg::Deps::AND. Use
@@ -216,9 +241,19 @@ sub deps_parse {
$options{reduce_arch} = 0 if not exists $options{reduce_arch};
$options{host_arch} = get_host_arch() if not exists $options{host_arch};
$options{build_arch} = get_build_arch() if not exists $options{build_arch};
+ $options{use_profiles} = 1 if not exists $options{use_profiles};
+ $options{reduce_profiles} = 0 if not exists $options{reduce_profiles};
+ $options{build_profiles} = [ get_build_profiles() ]
+ if not exists $options{build_profiles};
+ $options{reduce_restrictions} = 0 if not exists $options{reduce_restrictions};
$options{union} = 0 if not exists $options{union};
$options{build_dep} = 0 if not exists $options{build_dep};
+ if ($options{reduce_restrictions}) {
+ $options{reduce_arch} = 1;
+ $options{reduce_profiles} = 1;
+ }
+
# Strip trailing/leading spaces
$dep_line =~ s/^\s+//;
$dep_line =~ s/\s+$//;
@@ -242,6 +277,11 @@ sub deps_parse {
$dep_simple->reduce_arch($options{host_arch});
next if not $dep_simple->arch_is_concerned($options{host_arch});
}
+ $dep_simple->{restrictions} = undef if not $options{use_profiles};
+ if ($options{reduce_profiles}) {
+ $dep_simple->reduce_profiles($options{build_profiles});
+ next if not $dep_simple->profile_is_concerned($options{build_profiles});
+ }
push @or_list, $dep_simple;
}
next if not @or_list;
@@ -470,6 +510,7 @@ use Dpkg::Arch qw(debarch_is);
use Dpkg::Version;
use Dpkg::ErrorHandling;
use Dpkg::Gettext;
+use Dpkg::Util qw(:list);
use parent qw(Dpkg::Interface::Storable);
@@ -493,6 +534,7 @@ sub reset {
$self->{version} = undef;
$self->{arches} = undef;
$self->{archqual} = undef;
+ $self->{restrictions} = undef;
}
sub parse {
@@ -522,6 +564,11 @@ sub parse_string {
\s* (.*?) # don't parse architectures now
\s* \] # closing bracket
)? # end of optional architecture
+ (?: # start of optional restriction
+ \s* < # open bracket for restriction
+ \s* (.*?) # don't parse restrictions now
+ \s* > # closing bracket
+ )? # end of optional restriction
\s*$ # trailing spaces at end
}x;
if (defined($2)) {
@@ -536,6 +583,9 @@ sub parse_string {
if (defined($5)) {
$self->{arches} = [ split(/\s+/, $5) ];
}
+ if (defined($6)) {
+ $self->{restrictions} = [ map { lc } split /\s+/, $6 ];
+ }
}
sub output {
@@ -550,6 +600,9 @@ sub output {
if (defined($self->{arches})) {
$res .= ' [' . join(' ', @{$self->{arches}}) . ']';
}
+ if (defined($self->{restrictions})) {
+ $res .= ' <' . join(' ', @{$self->{restrictions}}) . '>';
+ }
if (defined($fh)) {
print { $fh } $res;
}
@@ -764,6 +817,51 @@ sub has_arch_restriction {
}
}
+sub profile_is_concerned {
+ my ($self, $build_profiles) = @_;
+
+ return 0 if not defined $self->{package}; # Empty dep
+ return 1 if not defined $self->{restrictions}; # Dep without restrictions
+
+ my $seen_profile = 0;
+ foreach my $restriction (@{$self->{restrictions}}) {
+ # Determine if this restriction is negated, and within the "profile"
+ # namespace, otherwise it does not concern this check.
+ next if $restriction !~ m/^(!)?profile\.(.*)/;
+
+ my $negated = defined $1 && $1 eq '!';
+ my $profile = $2;
+
+ # Determine if the restriction matches any of the specified profiles.
+ my $found = any { $_ eq $profile } @{$build_profiles};
+
+ if ($negated) {
+ if ($found) {
+ $seen_profile = 0;
+ last;
+ } else {
+ # "!profile.this" includes by default all other profiles
+ # unless they also appear in a "!profile.other".
+ $seen_profile = 1;
+ }
+ } elsif ($found) {
+ $seen_profile = 1;
+ last;
+ }
+ }
+ return $seen_profile;
+}
+
+sub reduce_profiles {
+ my ($self, $build_profiles) = @_;
+
+ if (not $self->profile_is_concerned($build_profiles)) {
+ $self->reset();
+ } else {
+ $self->{restrictions} = undef;
+ }
+}
+
sub get_evaluation {
my ($self, $facts) = @_;
return if not defined $self->{package};