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=40cd7dd9d16c3bfaf090e15bea0a0f91360cdb68 commit 40cd7dd9d16c3bfaf090e15bea0a0f91360cdb68 (HEAD -> main) Author: Guillem Jover <[email protected]> AuthorDate: Wed May 28 00:48:38 2025 +0200 Add vendor specific support for fuzzy source vs version nativeness There's been an ongoing push to distort the native source package concept, where this is a source of both accidental source package construction, where even warnings have been shown to not be enough. It has been argued this is a requirement for mainly two broad cases, one is for native metapackages tracking non-native packages, where the desire is to use the same versioning scheme (but with no version remapping), and for either CI or VCS based workflows, where some of the people involved either consider none of the proposed alternative solutions acceptable, or consider that source packages are obsolete and should not even be used anymore anyway, and undermining them is clearly an acceptable price that others should pay. This sets us back into making the packaging and its concepts more difficult to grasp and handle, both for existing maintainers and newcomers, and also for tool maintainers. We need to add the notion of fuzzy nativeness, where a native source package does not have a coherent native source version, so that vendors that are forcing this sloppiness through, can have it without affecting the default non-vendor case. Unfortunately this affects Debian and derivatives. Which means using a method like Dpkg::Version->is_native() has unreliable and non-portable semantics, so we deprecate that now as well, and will be removed in the future. Closes: #737634 --- man/deb-buildinfo.pod | 5 +++++ man/deb-changes.pod | 5 +++++ man/deb-control.pod | 5 +++++ man/dpkg-source.pod | 10 ++++++++++ man/dsc.pod | 5 +++++ scripts/Dpkg/Source/Package/V1.pm | 17 +++++++++++------ scripts/Dpkg/Source/Package/V2.pm | 4 ++-- scripts/Dpkg/Source/Package/V3/Native.pm | 12 +++++++++--- scripts/Dpkg/Vendor/Debian.pm | 2 ++ scripts/Dpkg/Vendor/Default.pm | 9 +++++++++ scripts/Dpkg/Version.pm | 25 ++++++++++++++++++++++++- scripts/t/Dpkg_Version.t | 10 +++++----- t/pod-spell.t | 1 + 13 files changed, 93 insertions(+), 17 deletions(-) diff --git a/man/deb-buildinfo.pod b/man/deb-buildinfo.pod index 11e2a5f80..fe6e682db 100644 --- a/man/deb-buildinfo.pod +++ b/man/deb-buildinfo.pod @@ -116,6 +116,11 @@ It may also include a Debian revision number (for non-native packages). The exact format and sorting algorithm are described in L<deb-version(7)>. +B<Note>: On some vendors, +dpkg has been made to permit native sources with non-native versions, +making this incoherent and adding to the confusion of the concept, +where in addition this tends to be a trap for accidental mistakes. + =item B<Binary-Only-Changes:> =item S< >I<changelog-entry> diff --git a/man/deb-changes.pod b/man/deb-changes.pod index 8025ead82..335a8ffe9 100644 --- a/man/deb-changes.pod +++ b/man/deb-changes.pod @@ -103,6 +103,11 @@ It may also include a Debian revision number (for non-native packages). The exact format and sorting algorithm are described in L<deb-version(7)>. +B<Note>: On some vendors, +dpkg has been made to permit native sources with non-native versions, +making this incoherent and adding to the confusion of the concept, +where in addition this tends to be a trap for accidental mistakes. + =item B<Distribution:> I<distribution>s (required) Lists one or more space-separated distributions where this version should diff --git a/man/deb-control.pod b/man/deb-control.pod index 4ed148e02..bebf5cf4d 100644 --- a/man/deb-control.pod +++ b/man/deb-control.pod @@ -78,6 +78,11 @@ The exact format and sorting algorithm are described in L<deb-version(7)>. +B<Note>: On some vendors, +dpkg has been made to permit native sources with non-native versions, +making this incoherent and adding to the confusion of the concept, +where in addition this tends to be a trap for accidental mistakes. + =item B<Maintainer:> I<fullname-email> (recommended) Should be in the format “Joe Bloggs E<lt>[email protected]<gt>”, and is typically diff --git a/man/dpkg-source.pod b/man/dpkg-source.pod index 736f42fd2..72ff62555 100644 --- a/man/dpkg-source.pod +++ b/man/dpkg-source.pod @@ -371,6 +371,11 @@ Optionally the original tarball might be accompanied by a detached upstream signature B<.orig.tar.gz.asc>, extraction supported since dpkg 1.18.5. +B<Note>: On some vendors, +dpkg has been made to permit native sources with non-native versions, +making this incoherent and adding to the confusion of the concept, +where in addition this tends to be a trap for accidental mistakes. + B<Extracting> Extracting a native package is a simple extraction of the single @@ -574,6 +579,11 @@ will ignore by default any VCS specific files and directories as well as many temporary files (see default value associated to B<-I> option in the B<--help> output). +B<Note>: On some vendors, +dpkg has been made to permit native sources with non-native versions, +making this incoherent and adding to the confusion of the concept, +where in addition this tends to be a trap for accidental mistakes. + =head2 Format: 3.0 (quilt) Supported since dpkg 1.14.17. diff --git a/man/dsc.pod b/man/dsc.pod index dd454e4e4..0afe5f0ab 100644 --- a/man/dsc.pod +++ b/man/dsc.pod @@ -107,6 +107,11 @@ It may also include a Debian revision number (for non-native packages). The exact format and sorting algorithm are described in L<deb-version(7)>. +B<Note>: On some vendors, +dpkg has been made to permit native sources with non-native versions, +making this incoherent and adding to the confusion of the concept, +where in addition this tends to be a trap for accidental mistakes. + =item B<Origin:> I<name> The name of the distribution this package is originating from. diff --git a/scripts/Dpkg/Source/Package/V1.pm b/scripts/Dpkg/Source/Package/V1.pm index 34a4bdec2..aff7eb1c1 100644 --- a/scripts/Dpkg/Source/Package/V1.pm +++ b/scripts/Dpkg/Source/Package/V1.pm @@ -49,6 +49,7 @@ use Dpkg::Source::Patch; use Dpkg::Exit qw(push_exit_handler pop_exit_handler); use Dpkg::Source::Functions qw(erasedir); use Dpkg::Source::Package::V3::Native; +use Dpkg::Vendor qw(run_vendor_hook); use parent qw(Dpkg::Source::Package); @@ -205,7 +206,7 @@ sub do_extract { if ($tarfile =~ m/\.orig\.tar\.gz$/) { # We only need to warn on this branch, because of the $native reset # below, otherwise the V3::Native module will handle the warning. - if (!$v->is_native()) { + if (!$v->__is_native()) { warning(g_('native package version may not have a revision')); } @@ -214,7 +215,7 @@ sub do_extract { $native = 0; } } else { - if ($v->is_native()) { + if ($v->__is_native()) { warning(g_('non-native package version does not contain a revision')) } } @@ -377,11 +378,15 @@ sub do_build { my $v = Dpkg::Version->new($self->{fields}->{'Version'}); if ($sourcestyle =~ m/[kpursKPUR]/) { error(g_('non-native package version does not contain a revision')) - if $v->is_native(); + if $v->__is_native(); } else { - # TODO: This will become fatal in the near future. - warning(g_('native package version may not have a revision')) - unless $v->is_native(); + if (!$v->__is_native) { + if (run_vendor_hook('has-fuzzy-native-source')) { + warning(g_('native package version may not have a revision')); + } else { + error(g_('native package version may not have a revision')); + } + } } my ($dirname, $dirbase) = fileparse($dir); diff --git a/scripts/Dpkg/Source/Package/V2.pm b/scripts/Dpkg/Source/Package/V2.pm index 160847ed3..f6401c0c2 100644 --- a/scripts/Dpkg/Source/Package/V2.pm +++ b/scripts/Dpkg/Source/Package/V2.pm @@ -220,7 +220,7 @@ sub do_extract { } my $v = Dpkg::Version->new($fields->{'Version'}); - if ($v->is_native()) { + if ($v->__is_native()) { warning(g_('non-native package version does not contain a revision')) } @@ -353,7 +353,7 @@ sub can_build { my $v = Dpkg::Version->new($self->{fields}->{'Version'}); return (0, g_('non-native package version does not contain a revision')) - if $v->is_native(); + if $v->__is_native(); return 1 if $self->find_original_tarballs(include_supplementary => 0); return 1 if $self->{options}{create_empty_orig} and diff --git a/scripts/Dpkg/Source/Package/V3/Native.pm b/scripts/Dpkg/Source/Package/V3/Native.pm index 46f31efc5..8015893db 100644 --- a/scripts/Dpkg/Source/Package/V3/Native.pm +++ b/scripts/Dpkg/Source/Package/V3/Native.pm @@ -44,6 +44,7 @@ use Dpkg::Exit qw(push_exit_handler pop_exit_handler); use Dpkg::Version; use Dpkg::Source::Archive; use Dpkg::Source::Functions qw(erasedir); +use Dpkg::Vendor qw(run_vendor_hook); use parent qw(Dpkg::Source::Package); @@ -71,7 +72,7 @@ sub do_extract { error(g_('no tarfile in Files field')) unless $tarfile; my $v = Dpkg::Version->new($fields->{'Version'}); - if (!$v->is_native()) { + if (!$v->__is_native()) { warning(g_('native package version may not have a revision')); } @@ -92,8 +93,13 @@ sub can_build { my ($self, $dir) = @_; my $v = Dpkg::Version->new($self->{fields}->{'Version'}); - return (0, g_('native package version may not have a revision')) - unless $v->is_native(); + if (!$v->__is_native()) { + if (run_vendor_hook('has-fuzzy-native-source')) { + warning(g_('native package version may not have a revision')); + } else { + return (0, g_('native package version may not have a revision')); + } + } return 1; } diff --git a/scripts/Dpkg/Vendor/Debian.pm b/scripts/Dpkg/Vendor/Debian.pm index d12af16e5..d8ece057e 100644 --- a/scripts/Dpkg/Vendor/Debian.pm +++ b/scripts/Dpkg/Vendor/Debian.pm @@ -106,6 +106,8 @@ sub run_hook { $ENV{LC_CTYPE} = 'C.UTF-8'; } elsif ($hook eq 'backport-version-regex') { return qr/~(bpo|deb)/; + } elsif ($hook eq 'has-fuzzy-native-source') { + return 1; } else { return $self->SUPER::run_hook($hook, @params); } diff --git a/scripts/Dpkg/Vendor/Default.pm b/scripts/Dpkg/Vendor/Default.pm index 934953f44..7399cd522 100644 --- a/scripts/Dpkg/Vendor/Default.pm +++ b/scripts/Dpkg/Vendor/Default.pm @@ -164,6 +164,13 @@ than version or remapped so that it does not get considered as a pre-release The returned string is a regex with one capture group for the backport delimiter string, or undef if there is no regex. +=item has-fuzzy-native-source () + +The hook is called by dpkg-source when trying to determine whether native +source packages should be handled as proper native ones, or as incoherent +and confused native ones, where the source format does not match the source +version (since dpkg 1.23.0). + =back =cut @@ -199,6 +206,8 @@ sub run_hook { return; } elsif ($hook eq 'backport-version-regex') { return; + } elsif ($hook eq 'has-fuzzy-native-source') { + return 0; } # Default return value for unknown/unimplemented hooks diff --git a/scripts/Dpkg/Version.pm b/scripts/Dpkg/Version.pm index 091a8bccd..e362fb3c2 100644 --- a/scripts/Dpkg/Version.pm +++ b/scripts/Dpkg/Version.pm @@ -32,7 +32,7 @@ them. =cut -package Dpkg::Version 1.03; +package Dpkg::Version 1.04; use strict; use warnings; @@ -186,9 +186,28 @@ sub revision { Returns true if the version is native, false if it has a revision. +B<Note>: On some vendors, dpkg has been made incoherent, and a native +source package format can end up having a non-native version, adding +to the confusion of the whole concept. And while this method would +be fine to be used on vendors that have a coherent native source concept, +this is not a pattern that will be portably relied on. Thus this method +is being deprecated. + =cut sub is_native { + my $self = shift; + warnings::warning('deprecated', + 'using Dpkg::Version->is_native() has been made incoherent and ' . + 'confusing on some dpkg vendors; it is deprecated as not having ' . + 'portable semantics anymore'); + return $self->__is_native(); +} + +# Internal symbol for dpkg project use only, no API guarantees provided. +# While a new method could be provided such as has_revision() (and +# has_epoch()), the intent and semantics would be similar. +sub __is_native { my $self = shift; return $self->{no_revision}; } @@ -481,6 +500,10 @@ sub version_check { =head1 CHANGES +=head2 Version 1.04 (dpkg 1.23.0) + +Deprecated method: $v->is_native(). + =head2 Version 1.03 (dpkg 1.20.0) Remove deprecation warning from semantic change in 1.02. diff --git a/scripts/t/Dpkg_Version.t b/scripts/t/Dpkg_Version.t index 1de7968ff..a3deda4f4 100644 --- a/scripts/t/Dpkg_Version.t +++ b/scripts/t/Dpkg_Version.t @@ -123,15 +123,15 @@ ok(!$ver->is_valid(), 'version does not start with digit 2/2'); # Native and non-native versions $ver = Dpkg::Version->new('1.0'); -ok($ver->is_native(), 'upstream version is native'); +ok($ver->__is_native(), 'upstream version is native'); $ver = Dpkg::Version->new('1:1.0'); -ok($ver->is_native(), 'upstream version w/ epoch is native'); +ok($ver->__is_native(), 'upstream version w/ epoch is native'); $ver = Dpkg::Version->new('1:1.0:1.0'); -ok($ver->is_native(), 'upstream version w/ epoch and colon is native'); +ok($ver->__is_native(), 'upstream version w/ epoch and colon is native'); $ver = Dpkg::Version->new('1.0-1'); -ok(!$ver->is_native(), 'upstream version w/ revision is not native'); +ok(!$ver->__is_native(), 'upstream version w/ revision is not native'); $ver = Dpkg::Version->new('1.0-1.0-1'); -ok(!$ver->is_native(), 'upstream version w/ dash and revision is not native'); +ok(!$ver->__is_native(), 'upstream version w/ dash and revision is not native'); # Comparisons foreach my $case (@tests) { diff --git a/t/pod-spell.t b/t/pod-spell.t index 34a6f4c9f..b36f97f95 100644 --- a/t/pod-spell.t +++ b/t/pod-spell.t @@ -100,6 +100,7 @@ modelines multiarch nocheck objdump +portably qa quiesced reportfile -- Dpkg.Org's dpkg

