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

Reply via email to