The following commit has been merged in the master branch:
commit d33fa8f197221c8422ee14dc36955e58febfa3d4
Author: Raphaël Hertzog <[email protected]>
Date: Wed Feb 24 17:26:36 2010 +0100
Dpkg::BuildOptions: provide an object oriented interface
Also update the test-suite and dpkg-buildpackage to match the new API.
Increase $VERSION to 1.00 since it's supposed to be a stable API now.
diff --git a/debian/changelog b/debian/changelog
index bac243c..b6861ba 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -15,6 +15,7 @@ dpkg (1.15.6) UNRELEASED; urgency=low
there management of default compression
- introduce Dpkg::Interface::Storable and update many modules
to make use of it
+ - update Dpkg::BuildOptions to provide an object-oriented interface
* Drop debian-maintainers from Suggests since it's obsolete, the
corresponding keyring is in debian-keyring.
* Merge support of symbol patterns in dpkg-gensymbols. Thanks to
diff --git a/scripts/Dpkg/BuildOptions.pm b/scripts/Dpkg/BuildOptions.pm
index ff9c3f0..b515282 100644
--- a/scripts/Dpkg/BuildOptions.pm
+++ b/scripts/Dpkg/BuildOptions.pm
@@ -1,3 +1,6 @@
+# Copyright © 2007 Frank Lichtenheld <[email protected]>
+# Copyright © 2010 Raphaël Hertzog <[email protected]>
+#
# 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
@@ -16,56 +19,172 @@ package Dpkg::BuildOptions;
use strict;
use warnings;
-our $VERSION = "0.01";
+our $VERSION = "1.00";
use Dpkg::Gettext;
use Dpkg::ErrorHandling;
-sub parse {
- my ($env) = @_;
+=head1 NAME
+
+Dpkg::BuildOptions - parse and update build options
+
+=head1 DESCRIPTION
+
+The Dpkg::BuildOptions object can be used to manipulate options stored
+in the DEB_BUILD_OPTIONS environment variable.
+
+=head1 FUNCTIONS
+
+=over 4
+
+=item my $bo = Dpkg::BuildOptions->new()
+
+Create a new Dpkg::BuildOptions object. It will be initialized based
+on the value of the DEB_BUILD_OPTIONS environment variable.
+
+=cut
+
+sub new {
+ my ($this, %opts) = @_;
+ my $class = ref($this) || $this;
+
+ my $self = {
+ options => {},
+ source => {},
+ };
+ bless $self, $class;
+ $self->merge($ENV{DEB_BUILD_OPTIONS}, "DEB_BUILD_OPTIONS");
+ return $self;
+}
- $env ||= $ENV{DEB_BUILD_OPTIONS};
+=item $bo->reset()
- unless ($env) { return {}; }
+Reset the object to not have any option (it's empty).
- my %opts;
+=cut
- foreach (split(/\s+/, $env)) {
- unless (/^([a-z][a-z0-9_-]*)(=(\S*))?$/) {
- warning(_g("invalid flag in DEB_BUILD_OPTIONS: %s"), $_);
+sub reset {
+ my ($self) = @_;
+ $self->{'options'} = {};
+ $self->{'source'} = {};
+}
+
+=item $bo->merge($content, $source)
+
+Merge the options set in $content and record that they come from the
+source $source. $source is mainly used in warning messages currently
+to indicate where invalid options have been detected.
+
+$content is a space separated list of options with optional assigned
+values like "nocheck parallel=2".
+
+=cut
+
+sub merge {
+ my ($self, $content, $source) = @_;
+ my $count = 0;
+ foreach (split(/\s+/, $content)) {
+ unless (/^([a-z][a-z0-9_-]*)(?:=(\S*))?$/) {
+ warning(_g("invalid flag in %s: %s"), $source, $_);
next;
}
+ $count += $self->set($1, $2, $source);
+ }
+ return $count;
+}
+
+=item $bo->set($option, $value, [$source])
- my ($k, $v) = ($1, $3);
+Store the given option in the objet with the given value. It's legitimate
+for a value to be undefined if the option is a simple boolean (its
+presence means true, its absence means false). The $source is optional
+and indicates where the option comes from.
- # Sanity checks
- if ($k =~ /^(noopt|nostrip|nocheck)$/ && defined($v)) {
- $v = undef;
- } elsif ($k eq 'parallel') {
- $v = "" if not defined($v);
- next if $v !~ /^\d*$/;
- }
+The known options have their values checked for sanity. Options without
+values have their value removed and options with invalid values are
+discarded.
- $opts{$k} = $v;
+=cut
+
+sub set {
+ my ($self, $key, $value, $source) = @_;
+
+ # Sanity checks
+ if ($key =~ /^(noopt|nostrip|nocheck)$/ && defined($value)) {
+ $value = undef;
+ } elsif ($key eq 'parallel') {
+ $value = "" if not defined($value);
+ return 0 if $value !~ /^\d*$/;
}
- return \%opts;
+ $self->{'options'}{$key} = $value;
+ $self->{'source'}{$key} = $source;
+
+ return 1;
}
-sub set {
- my ($opts, $overwrite) = @_;
- $overwrite = 1 if not defined($overwrite);
+=item $bo->get($option)
- my $new = {};
- $new = parse() unless $overwrite;
- while (my ($k, $v) = each %$opts) {
- $new->{$k} = $v;
- }
+Return the value associated to the option. It might be undef even if the
+option exists. You might want to check with $bo->has($option) to verify if
+the option is stored in the object.
+
+=cut
+
+sub get {
+ my ($self, $key) = @_;
+ return $self->{'options'}{$key};
+}
+
+=item $bo->has($option)
+
+Returns a boolean indicating whether the option is stored in the object.
+
+=cut
+
+sub has {
+ my ($self, $key) = @_;
+ return exists $self->{'options'}{$key};
+}
- my $env = join(" ", map { defined($new->{$_}) ? $_ . "=" . $new->{$_} : $_
} sort keys %$new);
+=item $string = $bo->output($fh)
- $ENV{DEB_BUILD_OPTIONS} = $env;
- return $env;
+Return a string representation of the build options suitable to be
+assigned to an environment variable. Can optionnaly output that string to
+the given filehandle.
+
+=cut
+
+sub output {
+ my ($self, $fh) = @_;
+ my $o = $self->{'options'};
+ my $res = join(" ", map { defined($o->{$_}) ? $_ . "=" . $o->{$_} : $_ }
sort keys %$o);
+ print $fh $res if defined $fh;
+ return $res;
}
+=item $bo->export([$var])
+
+Export the build options to the given environment variable. If omitted,
+DEB_BUILD_OPTIONS is assumed. The value set to the variable is also
+returned.
+
+=cut
+
+sub export {
+ my ($self, $var) = @_;
+ $var = "DEB_BUILD_OPTIONS" unless defined $var;
+ my $content = $self->output();
+ $ENV{$var} = $content;
+ return $content;
+}
+
+=back
+
+=head1 AUTHOR
+
+Raphaël Hertzog <[email protected]>
+
+=cut
+
1;
diff --git a/scripts/dpkg-buildpackage.pl b/scripts/dpkg-buildpackage.pl
index dfa2e74..5230da1 100755
--- a/scripts/dpkg-buildpackage.pl
+++ b/scripts/dpkg-buildpackage.pl
@@ -259,16 +259,16 @@ if ($signcommand) {
}
}
-my $build_opts = Dpkg::BuildOptions::parse();
+my $build_opts = Dpkg::BuildOptions->new();
if (defined $parallel) {
- $parallel = $build_opts->{parallel} if exists $build_opts->{parallel};
+ $parallel = $build_opts->get("parallel") if $build_opts->has("parallel");
$ENV{MAKEFLAGS} ||= '';
$ENV{MAKEFLAGS} .= " -j$parallel";
- $build_opts->{parallel} = $parallel;
- Dpkg::BuildOptions::set($build_opts);
+ $build_opts->set("parallel", $parallel);
+ $build_opts->export();
}
-my $default_flags = exists $build_opts->{noopt} ? "-g -O0" : "-g -O2";
+my $default_flags = $build_opts->has("noopt") ? "-g -O0" : "-g -O2";
my %flags = ( CPPFLAGS => '',
CFLAGS => $default_flags,
CXXFLAGS => $default_flags,
diff --git a/scripts/t/300_Dpkg_BuildOptions.t
b/scripts/t/300_Dpkg_BuildOptions.t
index f73b7e4..d5979e4 100644
--- a/scripts/t/300_Dpkg_BuildOptions.t
+++ b/scripts/t/300_Dpkg_BuildOptions.t
@@ -13,7 +13,7 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
-use Test::More tests => 6;
+use Test::More tests => 22;
use Dpkg::ErrorHandling;
use strict;
@@ -30,37 +30,39 @@ use_ok('Dpkg::BuildOptions');
$ENV{DEB_BUILD_OPTIONS} = 'noopt foonostripbar parallel=3 bazNOCHECK';
-my $dbo = Dpkg::BuildOptions::parse();
+my $dbo = Dpkg::BuildOptions->new();
+ok($dbo->has("noopt"), "has noopt");
+is($dbo->get("noopt"), undef, "noopt value");
+ok($dbo->has("foonostripbar"), "has foonostripbar");
+is($dbo->get("foonostripbar"), undef, "foonostripbar value");
+ok($dbo->has("parallel"), "has parallel");
+is($dbo->get("parallel"), 3, "parallel value");
+ok(!$dbo->has("bazNOCHECK"), "not has bazNOCHECK");
-my %dbo = (
- noopt => undef,
- foonostripbar => undef,
- parallel => 3,
- );
-my %dbo2 = (
- no => undef,
- opt => undef,
- 'no-strip' => undef,
- nocheck => undef,
- parallel => '',
- );
+$dbo->reset();
+$dbo->merge('no opt no-strip parallel = 5 nocheck', 'test');
+ok($dbo->has('no'), "has no");
+is($dbo->get('no'), undef, "no value");
+ok($dbo->has('opt'), "has opt");
+is($dbo->get('opt'), undef, "opt value");
+ok($dbo->has('no-strip'), "has no-strip");
+is($dbo->get('no-strip'), undef, "no-strip value");
+ok($dbo->has('parallel'), "has parallel");
+is($dbo->get('parallel'), '', "parallel value");
+ok($dbo->has('nocheck'), "has nocheck");
+is($dbo->get('nocheck'), undef, "nocheck value");
+$dbo->reset();
+$dbo->set('parallel', 5);
+$dbo->set('noopt', undef);
-is_deeply($dbo, \%dbo, 'parse');
-
-$dbo = Dpkg::BuildOptions::parse('no opt no-strip parallel = 5 nocheck');
-
-is_deeply($dbo, \%dbo2, 'parse (param)');
-
-$dbo->{parallel} = 5;
-$dbo->{noopt} = undef;
-
-my $env = Dpkg::BuildOptions::set($dbo, 1);
-
-is($ENV{DEB_BUILD_OPTIONS}, $env, 'set (return value)');
-is_deeply(Dpkg::BuildOptions::parse(), $dbo, 'set (env)');
+my $env = $dbo->export();
+is($env, "noopt parallel=5", "value of export");
+is($ENV{DEB_BUILD_OPTIONS}, $env, 'env match return value of export');
+$env = $dbo->export("OTHER_VARIABLE");
+is($ENV{OTHER_VARIABLE}, $env, 'export to other variable');
$ENV{DEB_BUILD_OPTIONS} = 'foobar';
-$dbo = { noopt => undef };
-$env = Dpkg::BuildOptions::set($dbo, 0);
-is($env, "foobar noopt", 'set (append)');
+$dbo = Dpkg::BuildOptions->new();
+$dbo->set("noopt", 1);
+is($dbo->output(), "foobar noopt", "output");
--
dpkg's main repository
--
To UNSUBSCRIBE, email to [email protected]
with a subject of "unsubscribe". Trouble? Contact [email protected]