This is an automated email from the git hooks/post-receive script. guillem pushed a commit to branch main in repository dpkg.
View the commit online: https://git.dpkg.org/cgit/dpkg/dpkg.git/commit/?id=39decc4c215a2839f5d7964cfb0624d71aab878b commit 39decc4c215a2839f5d7964cfb0624d71aab878b Author: Guillem Jover <[email protected]> AuthorDate: Mon Feb 17 19:46:41 2020 +0100 Dpkg::BuildAPI: New module This module implements the new dpkg-build-api interface that will be used to control gradual default changes avoiding disruption, where the specific packages can opt-in at their convenience. --- debian/control | 2 + debian/dpkg-dev.manpages | 1 + man/Makefile.am | 2 + man/dpkg-build-api.pod | 58 ++++++++++++ man/po/po4a.cfg | 1 + scripts/Dpkg/BuildAPI.pm | 142 ++++++++++++++++++++++++++++++ scripts/Makefile.am | 9 ++ scripts/po/POTFILES.in | 1 + scripts/t/Dpkg_BuildAPI.t | 93 +++++++++++++++++++ scripts/t/Dpkg_BuildAPI/ctrl-api-default | 4 + scripts/t/Dpkg_BuildAPI/ctrl-api-desync | 10 +++ scripts/t/Dpkg_BuildAPI/ctrl-api-explicit | 6 ++ scripts/t/Dpkg_BuildAPI/ctrl-api-gt-max | 6 ++ scripts/t/Dpkg_BuildAPI/ctrl-api-no-int | 6 ++ scripts/t/Dpkg_BuildAPI/ctrl-api-no-ver | 6 ++ scripts/t/Dpkg_BuildAPI/ctrl-api-rel-noeq | 6 ++ 16 files changed, 353 insertions(+) diff --git a/debian/control b/debian/control index 3aad60a7c..f166b3d05 100644 --- a/debian/control +++ b/debian/control @@ -138,6 +138,8 @@ Breaks: # Uses required SOP feautres, w/o requiring a hard dependency on pgpainless. pgpainless-cli (<< 1.3.13~), libsop-java-java (<< 4.0.7~), +Provides: + dpkg-build-api (= 0), Description: Debian package development tools This package provides the development tools (including dpkg-source) required to unpack, build and upload Debian source packages. diff --git a/debian/dpkg-dev.manpages b/debian/dpkg-dev.manpages index bbd3d9787..fe2fe0dec 100644 --- a/debian/dpkg-dev.manpages +++ b/debian/dpkg-dev.manpages @@ -25,6 +25,7 @@ usr/share/man/{*,*/*}/deb-version.7 usr/share/man/{*,*/*}/deb.5 usr/share/man/{*,*/*}/deb822.5 usr/share/man/{*,*/*}/dpkg-architecture.1 +usr/share/man/{*,*/*}/dpkg-build-api.7 usr/share/man/{*,*/*}/dpkg-buildflags.1 usr/share/man/{*,*/*}/dpkg-buildpackage.1 usr/share/man/{*,*/*}/dpkg-checkbuilddeps.1 diff --git a/man/Makefile.am b/man/Makefile.am index 126a4b26c..d9e9a2a4c 100644 --- a/man/Makefile.am +++ b/man/Makefile.am @@ -28,6 +28,7 @@ man_MANS = \ deb.5 \ deb822.5 \ dpkg-architecture.1 \ + dpkg-build-api.7 \ dpkg-buildflags.1 \ dpkg-buildpackage.1 \ dpkg-checkbuilddeps.1 \ @@ -115,6 +116,7 @@ EXTRA_DIST += \ deb.pod \ deb822.pod \ dpkg-architecture.pod \ + dpkg-build-api.pod \ dpkg-buildflags.pod \ dpkg-buildpackage.pod \ dpkg-checkbuilddeps.pod \ diff --git a/man/dpkg-build-api.pod b/man/dpkg-build-api.pod new file mode 100644 index 000000000..d2a56d8a9 --- /dev/null +++ b/man/dpkg-build-api.pod @@ -0,0 +1,58 @@ +# dpkg manual page - dpkg-build-api(7) +# +# Copyright © 2021 Guillem Jover <[email protected]> +# +# This 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 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, see <https://www.gnu.org/licenses/>. + +=encoding utf8 + +=head1 NAME + +dpkg-build-api - source package dpkg build API level + +=head1 SYNOPSIS + + Build-Depends: + dpkg-build-api (= 0), + +=head1 DESCRIPTION + +The source package dpkg build API level, defines a versioned interface for +source packages, where each API level provides specific behaviors and +guarantees. + +These interfaces can then be adopted by packages in a gradual way, +and phased out more easily than with global behavior changes. + +The declaration of this API level is done through build-dependencies, in +one of B<Build-Depends>, B<Build-Depends-Indep> or B<Build-Depends-Arch>, +or via the environment variable B<DPKG_BUILD_API>, which will override these +if both are present, and might emit a warning in case they are different. + +=head1 API LEVELS + +=over + +=item v0 + +This is the current global level, equivalent to not specifying one. +The interfaces and behaviors provided are subject to the normal global +interface updates, which tend to require longer deprecation cycles and/or +coordinated transitions. + +=back + +=head1 SEE ALSO + +B<deb-src-control>(5). diff --git a/man/po/po4a.cfg b/man/po/po4a.cfg index 72ff72ad9..49477b553 100644 --- a/man/po/po4a.cfg +++ b/man/po/po4a.cfg @@ -31,6 +31,7 @@ [type:pod] deb.pod $lang:$lang/deb.pod [type:pod] deb822.pod $lang:$lang/deb822.pod [type:pod] dpkg-architecture.pod $lang:$lang/dpkg-architecture.pod +[type:pod] dpkg-build-api.pod $lang:$lang/dpkg-build-api.pod [type:pod] dpkg-buildflags.pod $lang:$lang/dpkg-buildflags.pod [type:pod] dpkg-buildpackage.pod $lang:$lang/dpkg-buildpackage.pod [type:pod] dpkg-checkbuilddeps.pod $lang:$lang/dpkg-checkbuilddeps.pod diff --git a/scripts/Dpkg/BuildAPI.pm b/scripts/Dpkg/BuildAPI.pm new file mode 100644 index 000000000..2e2f05f3b --- /dev/null +++ b/scripts/Dpkg/BuildAPI.pm @@ -0,0 +1,142 @@ +# Copyright © 2020-2022 Guillem Jover <[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 +# (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, see <https://www.gnu.org/licenses/>. + +package Dpkg::BuildAPI 0.01; + +use strict; +use warnings; + +our @EXPORT_OK = qw( + get_build_api + reset_build_api +); + +use Exporter qw(import); + +use Dpkg::Gettext; +use Dpkg::ErrorHandling; +use Dpkg::BuildEnv; +use Dpkg::Version; +use Dpkg::Deps; + +use constant { + DEFAULT_BUILD_API => '0', + MAX_BUILD_API => '0', +}; + +my $build_api; + +=encoding utf8 + +=head1 NAME + +Dpkg::BuildAPI - handle build API versions + +=head1 DESCRIPTION + +The Dpkg::BuildAPI module provides functions to fetch the current dpkg +build API level. + +=head1 FUNCTIONS + +=over 4 + +=item $level = get_build_api([$ctrl]) + +Get the build API level, from the environment variable B<DPKG_BUILD_API>, +or if not defined and a $ctrl C<Dpkg::Control::Info> object passed as an +argument, from its build dependency fields. If no $ctrl object gets passed +the previous value obtained is returned. + +=cut + +sub get_build_api { + my $ctrl = shift; + + return $build_api if defined $build_api && ! defined $ctrl; + + if (Dpkg::BuildEnv::has('DPKG_BUILD_API')) { + $build_api = Dpkg::BuildEnv::get('DPKG_BUILD_API'); + } elsif (defined $ctrl) { + my $src = $ctrl->get_source(); + my @dep_list = deps_concat(map { + $src->{$_ } + } qw(Build-Depends Build-Depends-Indep Build-Depends-Arch)); + + my $deps = deps_parse(@dep_list, + build_dep => 1, + reduce_restrictions => 1, + ); + + if (not defined $deps) { + $build_api = DEFAULT_BUILD_API; + return $build_api; + } + + deps_iterate($deps, sub { + my $dep = shift; + + return 1 if $dep->{package} ne 'dpkg-build-api'; + + if (! defined $dep->{relation} || $dep->{relation} ne REL_EQ) { + error(g_('dpkg build API level needs an exact version')); + } + + if (defined $build_api and $build_api ne $dep->{version}) { + error(g_('dpkg build API level with conflicting versions: %s vs %s'), + $build_api, $dep->{version}); + } + + $build_api = $dep->{version}; + + return 1; + }); + } + + $build_api //= DEFAULT_BUILD_API; + + if ($build_api !~ m/^[0-9]+$/) { + error(g_("invalid dpkg build API level '%s'"), $build_api); + } + + if ($build_api > MAX_BUILD_API) { + error(g_("dpkg build API level '%s' greater than max '%s'"), + $build_api, MAX_BUILD_API); + } + + return $build_api; +} + +=item reset_build_api() + +Reset the cached build API level. + +=cut + +sub reset_build_api { + $build_api = undef; +} + +=back + +=head1 CHANGES + +=head2 Version 0.xx + +This is a private module. + +=cut + +1; diff --git a/scripts/Makefile.am b/scripts/Makefile.am index eb67108f8..3bb6e1df0 100644 --- a/scripts/Makefile.am +++ b/scripts/Makefile.am @@ -62,6 +62,7 @@ CLEANFILES = \ perllibdir = $(PERL_LIBDIR) nobase_dist_perllib_DATA = \ Dpkg/Arch.pm \ + Dpkg/BuildAPI.pm \ Dpkg/BuildEnv.pm \ Dpkg/BuildFlags.pm \ Dpkg/BuildInfo.pm \ @@ -225,6 +226,7 @@ test_scripts = \ t/Dpkg_Package.t \ t/Dpkg_Shlibs_Cppfilt.t \ t/Dpkg_Shlibs.t \ + t/Dpkg_BuildAPI.t \ t/Dpkg_BuildEnv.t \ t/Dpkg_BuildFlags.t \ t/Dpkg_BuildFlags_Ubuntu.t \ @@ -269,6 +271,13 @@ test_scripts = \ # EOL test_data = \ + t/Dpkg_BuildAPI/ctrl-api-default \ + t/Dpkg_BuildAPI/ctrl-api-desync \ + t/Dpkg_BuildAPI/ctrl-api-explicit \ + t/Dpkg_BuildAPI/ctrl-api-gt-max \ + t/Dpkg_BuildAPI/ctrl-api-no-int \ + t/Dpkg_BuildAPI/ctrl-api-no-ver \ + t/Dpkg_BuildAPI/ctrl-api-rel-noeq \ t/Dpkg_Changelog/countme \ t/Dpkg_Changelog/date-format \ t/Dpkg_Changelog/fields \ diff --git a/scripts/po/POTFILES.in b/scripts/po/POTFILES.in index aa9befa76..c535551fb 100644 --- a/scripts/po/POTFILES.in +++ b/scripts/po/POTFILES.in @@ -19,6 +19,7 @@ scripts/dpkg-source.pl scripts/dpkg-vendor.pl scripts/Dpkg.pm scripts/Dpkg/Arch.pm +scripts/Dpkg/BuildAPI.pm scripts/Dpkg/BuildEnv.pm scripts/Dpkg/BuildFlags.pm scripts/Dpkg/BuildInfo.pm diff --git a/scripts/t/Dpkg_BuildAPI.t b/scripts/t/Dpkg_BuildAPI.t new file mode 100644 index 000000000..c27b30357 --- /dev/null +++ b/scripts/t/Dpkg_BuildAPI.t @@ -0,0 +1,93 @@ +#!/usr/bin/perl +# +# 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, see <https://www.gnu.org/licenses/>. + +use strict; +use warnings; + +use Test::More tests => 17; +use Test::Dpkg qw(:paths); + +$ENV{DEB_HOST_ARCH} = 'amd64'; + +use Dpkg::Control; +use Dpkg::Control::Info; + +BEGIN { + use_ok('Dpkg::BuildAPI', qw(get_build_api reset_build_api)); +} + +my $datadir = test_get_data_path(); + +sub test_load_ctrl { + my $file = shift; + + my $ctrl = Dpkg::Control::Info->new(type => CTRL_INFO_SRC); + $ctrl->load("$datadir/$file"); + + return $ctrl; +} + +sub test_parse_env_invalid { + my ($value, $desc) = @_; + + my $api; + + eval { + local $ENV{DPKG_BUILD_API} = $value; + reset_build_api(); + $api = get_build_api(); + }; + + ok($@, "failed to parse build API $desc: $@"); + is($api, undef, "parsing invalid build API $desc returns undef"); +} + +sub test_parse_ctrl_invalid { + my ($file, $desc) = @_; + + my $ctrl = test_load_ctrl($file); + my $api; + + eval { + reset_build_api(); + $api = get_build_api($ctrl); + }; + ok($@, "failed to parse build API $desc from $file: $@"); + is($api, undef, "parsing invalid build API $desc from $file returns undef"); +} + +sub test_parse_ctrl { + my ($file, $exp_api, $desc) = @_; + + my $ctrl = test_load_ctrl($file); + + reset_build_api(); + my $api = get_build_api($ctrl); + is($api, $exp_api, "build API $desc matches"); +} + +test_parse_env_invalid('aa', 'text level'); +test_parse_env_invalid('999999999', 'out of range'); + +test_parse_ctrl_invalid('ctrl-api-desync', 'multiple build API levels out of sync'); +test_parse_ctrl_invalid('ctrl-api-no-ver', 'build API with no level'); +test_parse_ctrl_invalid('ctrl-api-rel-noeq', 'API level with non-eq operator'); +test_parse_ctrl_invalid('ctrl-api-gt-max', 'API level > max'); +test_parse_ctrl_invalid('ctrl-api-no-int', 'API level is not an integer'); + +test_parse_ctrl('ctrl-api-default', 0, 'default API level'); +test_parse_ctrl('ctrl-api-explicit', 0, 'explicit API level'); + +# TODO: Add more test cases. diff --git a/scripts/t/Dpkg_BuildAPI/ctrl-api-default b/scripts/t/Dpkg_BuildAPI/ctrl-api-default new file mode 100644 index 000000000..f83ca3862 --- /dev/null +++ b/scripts/t/Dpkg_BuildAPI/ctrl-api-default @@ -0,0 +1,4 @@ +Source: pkg-source + +Package: pkg-binary +Architecture: all diff --git a/scripts/t/Dpkg_BuildAPI/ctrl-api-desync b/scripts/t/Dpkg_BuildAPI/ctrl-api-desync new file mode 100644 index 000000000..dd959ac50 --- /dev/null +++ b/scripts/t/Dpkg_BuildAPI/ctrl-api-desync @@ -0,0 +1,10 @@ +Source: pkg-source +Build-Depends: + dpkg-build-api (= 0), +Build-Depends-Arch: + dpkg-build-api (= 1), +Build-Depends-Indep: + dpkg-build-api (= 2), + +Package: pkg-binary +Architecture: all diff --git a/scripts/t/Dpkg_BuildAPI/ctrl-api-explicit b/scripts/t/Dpkg_BuildAPI/ctrl-api-explicit new file mode 100644 index 000000000..1efb10681 --- /dev/null +++ b/scripts/t/Dpkg_BuildAPI/ctrl-api-explicit @@ -0,0 +1,6 @@ +Source: pkg-source +Build-Depends: + dpkg-build-api (= 0), + +Package: pkg-binary +Architecture: all diff --git a/scripts/t/Dpkg_BuildAPI/ctrl-api-gt-max b/scripts/t/Dpkg_BuildAPI/ctrl-api-gt-max new file mode 100644 index 000000000..f3ed403ea --- /dev/null +++ b/scripts/t/Dpkg_BuildAPI/ctrl-api-gt-max @@ -0,0 +1,6 @@ +Source: pkg-source +Build-Depends: + dpkg-build-api (= 999999999), + +Package: pkg-binary +Architecture: all diff --git a/scripts/t/Dpkg_BuildAPI/ctrl-api-no-int b/scripts/t/Dpkg_BuildAPI/ctrl-api-no-int new file mode 100644 index 000000000..82d3cff59 --- /dev/null +++ b/scripts/t/Dpkg_BuildAPI/ctrl-api-no-int @@ -0,0 +1,6 @@ +Source: pkg-source +Build-Depends: + dpkg-build-api (= 1.0), + +Package: pkg-binary +Architecture: all diff --git a/scripts/t/Dpkg_BuildAPI/ctrl-api-no-ver b/scripts/t/Dpkg_BuildAPI/ctrl-api-no-ver new file mode 100644 index 000000000..9fce73131 --- /dev/null +++ b/scripts/t/Dpkg_BuildAPI/ctrl-api-no-ver @@ -0,0 +1,6 @@ +Source: pkg-source +Build-Depends: + dpkg-build-api, + +Package: pkg-binary +Architecture: all diff --git a/scripts/t/Dpkg_BuildAPI/ctrl-api-rel-noeq b/scripts/t/Dpkg_BuildAPI/ctrl-api-rel-noeq new file mode 100644 index 000000000..3b2e0f87d --- /dev/null +++ b/scripts/t/Dpkg_BuildAPI/ctrl-api-rel-noeq @@ -0,0 +1,6 @@ +Source: pkg-source +Build-Depends: + dpkg-build-api (>= 1), + +Package: pkg-binary +Architecture: all -- Dpkg.Org's dpkg

