Package: lintian Version: 2.5.27 Severity: wishlist Tags: patch Dear lintian maintainers,
the syntax for the Build-Profiles field was changed during the bootstrap sprint in paris [1,2]. I wanted to file my patch for lintian once dpkg with the new syntax was released but since that release did not happen during the past month and at the same time the freeze draws dangerously close, I decided to file this bug with the patch anyways. In contrast to apt, it is (as far as I know) not necessary that lintian in Jessie understands the syntax though. Only the tools which are directly invoked by the buildd machinery must be able to understand build profiles. Nevertheless, in case you do another release before the freeze, consider the attached patch. Maybe you want to wait until dpkg implements the new syntax for better testing [3]. Otherwise, maybe you should remove the existing support for the old build profile syntax because it is not compatible with what will end up in dpkg and apt in Jessie. Thanks a lot and sorry for the confusion and late submission. cheers, josch [1] https://wiki.debian.org/Sprints/2014/BootstrapSprint [2] https://wiki.debian.org/BuildProfileSpec [3] https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=760158
>From 037e9e04b67042d7610da36c57419281eac6988f Mon Sep 17 00:00:00 2001 From: josch <[email protected]> Date: Mon, 1 Sep 2014 11:16:58 +0200 Subject: [PATCH] implement new build profile syntax --- checks/control-file.desc | 12 ---- checks/control-file.pm | 70 ++++++++++---------- checks/fields.desc | 64 +++++++++--------- checks/fields.pm | 77 +++++++--------------- data/fields/build-profiles | 6 ++ data/fields/dependency-restrictions | 4 -- .../debian/debian/control.in | 26 ++++++-- t/tests/fields-build-profiles-general/desc | 19 +++--- t/tests/fields-build-profiles-general/tags | 19 +++--- 9 files changed, 139 insertions(+), 158 deletions(-) create mode 100644 data/fields/build-profiles delete mode 100644 data/fields/dependency-restrictions diff --git a/checks/control-file.desc b/checks/control-file.desc index b5b8223..fbfb4a2 100644 --- a/checks/control-file.desc +++ b/checks/control-file.desc @@ -210,18 +210,6 @@ Info: The control file contains commented-out VCS-* lines, most probably a result of dh_make. These URLs should either be valid and uncommented, or removed. -Tag: stageX-profile-used-but-no-binary-package-dropped -Severity: normal -Certainty: certain -Info: You used a stage1 or stage2 build profile restriction in the build - dependencies but you did not mark any binary packages as not being built with - the used profile activated. Using a stage1 or stage2 build profile restriction - means that you intend to change the build process in a way such that some of - the build results will be different or not generated at all. All binary - packages which would provide different functionality, would be empty or not be - built at all under the stage1 or stage2 profiles must be marked as not being - generated with the Build-Profiles field. - Tag: pre-depends-directly-on-multiarch-support Severity: pedantic Certainty: possible diff --git a/checks/control-file.pm b/checks/control-file.pm index 52c308f..f604b74 100644 --- a/checks/control-file.pm +++ b/checks/control-file.pm @@ -37,6 +37,7 @@ use Lintian::Util qw(file_is_encoded_in_non_utf8 read_dpkg_control my @LIBCS = qw(libc6 libc6.1 libc0.1 libc0.3); my $LIBCS = Lintian::Relation->new(join(' | ', @LIBCS)); my $src_fields = Lintian::Data->new('common/source-fields'); +my $KNOWN_BUILD_PROFILES = Lintian::Data->new('fields/build-profiles'); sub run { my ($pkg, undef, $info) = @_; @@ -298,48 +299,49 @@ sub run { # packages might never be built in the first place because of build # profiles - # check which profile names are supposedly supported according to the build - # dependencies - my %used_profiles; - for my $field ( - qw(build-depends build-depends-indep build-conflicts build-conflicts-indep) - ) { - if (my $value = $info->source_field($field)) { - # If the field does not contain "profile." then skip this - # part. They rarely do, so this is just a little - # "common-case" optimisation. - next if index($value, 'profile.') < 0; - for my $dep (split /\s*,\s*/, $value) { - for my $alt (split /\s*\|\s*/, $dep) { - while ($alt =~ /<([^>]+)>/g) { - for my $restr (split /\s+/, $1) { - if ($restr =~ m/^!?profile\.(.*)/) { - $used_profiles{$1} = 0; - } - } - } - } - } - } - } + my $profiles_used = 0; - # find those packages that do not get built because of a certain build - # profile + # check the syntax of the Build-Profiles field for my $bin (@package_names) { my $raw = $info->binary_field($bin, 'build-profiles'); next unless $raw; - for my $prof (split /\s+/, $raw) { - if ($prof =~ s/^!//) { - $used_profiles{$prof} = 1; + $profiles_used = 1; + if ($raw !~ m/^\s*<!?[a-z0-9]+(\s+!?[a-z0-9]+)*>(\s+<!?[a-z0-9]+(\s+!?[a-z0-9]+)*>)*\s*$/) { + tag 'invalid-restriction-formula-in-build-profiles-field', $raw, $bin; + } else { + # parse the field and check the profile names + $raw =~ s/^\s*<(.*)>\s*$/$1/; + for my $restrlist (split />\s+</, $raw) { + for my $profile (split /\s+/, $restrlist) { + $profile =~ s/^!//; + tag 'invalid-profile-name-in-build-profiles-field', $profile, $bin + unless $KNOWN_BUILD_PROFILES->known($profile); + } } } } - # find out if the developer forgot to mark binary packages as not being - # built - while (my ($k, $v) = each(%used_profiles)) { - tag 'stageX-profile-used-but-no-binary-package-dropped' - if (($k eq 'stage1' || $k eq 'stage2') && $v == 0); + # if a Build-Profiles field was used, then the package must depend on the + # correct dpkg (and optionally debhelper) versions + if ($profiles_used) { + my $build_all = $info->relation('build-depends-all'); + my $build_conflicts_all = $info->relation('build-conflicts-all'); + tag 'restriction-formula-without-versioned-dpkg-dev-dependency' + unless ($build_all->implies('dpkg-dev (>= 1.17.XXX)')); + tag 'restriction-formula-with-versioned-dpkg-dev-conflict' + if ( + $build_conflicts_all->implies_inverse('dpkg-dev (<< 1.17.XXX)')); + # if the package uses debhelper then it must require and not + # conflict with version >= 9.XXX + if ($build_all->implies('debhelper')) { + tag 'restriction-formula-with-debhelper-without-debhelper-version' + unless ($build_all->implies('debhelper (>= 9.XXX)')); + #<<< no tidy, tag name too long + tag 'restriction-formula-with-debhelper-with-conflicting-debhelper-version' + #>>> + if ($build_conflicts_all->implies_inverse( + 'debhelper (<< 9.XXX)')); + } } # find binary packages that Pre-Depend on multiarch-support without going diff --git a/checks/fields.desc b/checks/fields.desc index 85c4bdd..1b59675 100644 --- a/checks/fields.desc +++ b/checks/fields.desc @@ -637,55 +637,57 @@ Info: The architecture string in this source relation has some negated. This is not permitted by Policy. Either all architectures must be negated or none of them may be. -Tag: invalid-restriction-term-in-source-relation +Tag: invalid-profile-name-in-source-relation Severity: important -Certainty: certain -Info: The restriction list in the source relation includes a term which - does not contain exactly one dot separating restriction namespace and label. - A term in a restriction list is of the form "namespace.label" (without the - quotes). +Certainty: possible +Info: The restriction formula in the source relation includes an unknown build + profile. The only allowed build profiles are "stage1", "stage2", "nocheck", + "nodoc", "nobiarch" and "cross". -Tag: invalid-restriction-namespace-in-source-relation +Tag: invalid-restriction-formula-in-build-profiles-field Severity: important -Certainty: possible -Info: The restriction list in the source relation includes a term with - an unknown namespace. The only allowed namespace is "profile" (without the - quotes). +Certainty: certain +Info: The restriction formula in the Build-Profiles field must have the same + format as the restriction formula in the Build-Depends field with angle + brackets. -Tag: invalid-restriction-label-in-source-relation +Tag: invalid-profile-name-in-build-profiles-field Severity: important Certainty: possible -Info: The restriction list in the source relation includes a term with - an unknown label. The only allowed labels are "stage1", "stage2", "nocheck" - and "cross". +Info: The restriction formula in Build-Profiles field includes an unknown build + profile. The only allowed build profiles are "stage1", "stage2", "nocheck", + "nodoc", "nobiarch" and "cross". -Tag: restriction-list-without-versioned-dpkg-dev-dependency +Tag: restriction-formula-without-versioned-dpkg-dev-dependency Severity: normal Certainty: certain -Info: If a restriction list appears in the build dependencies, then the - source package has to build depend on dpkg-dev (>= 1.17.2) for minimal - restriction list support. +Info: If a restriction formula appears in the source relation or if the + Build-Profiles field is used in a binary package stanza then the source + package has to build depend on dpkg-dev (>= 1.17.XXX) for minimal + restriction formula support. -Tag: restriction-list-with-versioned-dpkg-dev-conflict +Tag: restriction-formula-with-versioned-dpkg-dev-conflict Severity: normal Certainty: certain -Info: If a restriction list appears in the build dependencies, then the - source package has to build depend on dpkg-dev (>= 1.17.2) for minimal - restriction list support. It must not conflict with version 1.17.2. +Info: If a restriction formula appears in the build dependencies or if the + Build-Profiles field is used in a binary package stanza then the source + package has to build depend on dpkg-dev (>= 1.17.XXX) for minimal + restriction formula support. It must not conflict with version 1.17.XXX. -Tag: restriction-list-with-debhelper-without-debhelper-version +Tag: restriction-formula-with-debhelper-without-debhelper-version Severity: normal Certainty: certain -Info: If a restriction list appears in the build dependencies and the - package uses debhelper, then the source package has to depend on at least - debhelper 9.20140227. +Info: If a restriction formula appears in the build dependencies or if the + Build-Profiles field is used in a binary package stanza and the package uses + debhelper, then the source package has to depend on at least debhelper 9.XXX. -Tag: restriction-list-with-debhelper-with-conflicting-debhelper-version +Tag: restriction-formula-with-debhelper-with-conflicting-debhelper-version Severity: normal Certainty: certain -Info: If a restriction list appears in the build dependencies and the - package uses debhelper, then the source package has to depend on at least - debhelper 9.20140227. It must not conflict with version 9.20140227. +Info: If a restriction formula appears in the build dependencies or if the + Build-Profiles field is used in a binary package stanza and the package uses + debhelper, then the source package has to depend on at least debhelper 9.XXX. + It must not conflict with version 9.XXX. Tag: depends-on-build-essential-package-without-using-version Severity: important diff --git a/checks/fields.pm b/checks/fields.pm index 67beb86..b063fec 100644 --- a/checks/fields.pm +++ b/checks/fields.pm @@ -46,9 +46,7 @@ our $known_build_essential = Lintian::Data->new('fields/build-essential-packages'); our $KNOWN_BINARY_FIELDS = Lintian::Data->new('fields/binary-fields'); our $KNOWN_UDEB_FIELDS = Lintian::Data->new('fields/udeb-fields'); -our $KNOWN_DEPENDENCY_RESTRICTIONS - = Lintian::Data->new('fields/dependency-restrictions', - qr/\./, \&_load_dependency_restrictions); +our $KNOWN_BUILD_PROFILES = Lintian::Data->new('fields/build-profiles'); our %KNOWN_ARCHIVE_PARTS = map { $_ => 1 } ('non-free', 'contrib'); @@ -990,29 +988,12 @@ sub run { $restrictions_used = 1; } - for my $restr (@{$d_restr}) { - my $dotcount = $restr =~ tr/.//; - if ($dotcount != 1) { - #<<< no tidy, tag name too long - tag 'invalid-restriction-term-in-source-relation', - #>>> - "$restr [$field: $part_d_orig]"; - next; - } - $restr =~ s/^!//; - my ($ns, $label) = split(/\./, $restr, 2); - if ($KNOWN_DEPENDENCY_RESTRICTIONS->known($ns)) { - #<<< no tidy, tag name too long - tag 'invalid-restriction-label-in-source-relation', - #>>> - "$label [$field: $part_d_orig]" - unless any { $_ eq $label } - @{$KNOWN_DEPENDENCY_RESTRICTIONS->value($ns)}; - } else { - #<<< no tidy, tag name too long - tag 'invalid-restriction-namespace-in-source-relation', - #>>> - "$ns [$field: $part_d_orig]"; + for my $restrlist (@{$d_restr}) { + for my $prof (@{$restrlist}) { + $prof =~ s/^!//; + tag 'invalid-profile-name-in-source-relation', + "$prof [$field: $part_d_orig]" + unless $KNOWN_BUILD_PROFILES->known($prof); } } @@ -1131,25 +1112,25 @@ sub run { } # if restrictions are found in the build-depends/conflicts, then - # package must build-depend on dpkg (>= 1.17.2) + # package must build-depend on dpkg (>= 1.17.XXX) if ($restrictions_used) { my $build_conflicts_all = $info->relation('build-conflicts-all'); - tag 'restriction-list-without-versioned-dpkg-dev-dependency' - unless ($build_all->implies('dpkg-dev (>= 1.17.2)')); - tag 'restriction-list-with-versioned-dpkg-dev-conflict' + tag 'restriction-formula-without-versioned-dpkg-dev-dependency' + unless ($build_all->implies('dpkg-dev (>= 1.17.XXX)')); + tag 'restriction-formula-with-versioned-dpkg-dev-conflict' if ( - $build_conflicts_all->implies_inverse('dpkg-dev (<< 1.17.2)')); + $build_conflicts_all->implies_inverse('dpkg-dev (<< 1.17.XXX)')); # if the package uses debhelper then it must require and not - # conflict with version >= 9.20140227 + # conflict with version >= 9.XXX if ($build_all->implies('debhelper')) { - tag 'restriction-list-with-debhelper-without-debhelper-version' - unless ($build_all->implies('debhelper (>= 9.20140227)')); + tag 'restriction-formula-with-debhelper-without-debhelper-version' + unless ($build_all->implies('debhelper (>= 9.XXX)')); #<<< no tidy, tag name too long - tag 'restriction-list-with-debhelper-with-conflicting-debhelper-version' + tag 'restriction-formula-with-debhelper-with-conflicting-debhelper-version' #>>> if ( $build_conflicts_all->implies_inverse( - 'debhelper (<< 9.20140227)')); + 'debhelper (<< 9.XXX)')); } } @@ -1314,11 +1295,11 @@ sub run { return; } -# splits "foo:bar (>= 1.2.3) [!i386 ia64] <!profile.stage1 !profile.nocheck>" into -# ( "foo", "bar", [ ">=", "1.2.3" ], [ [ "i386", "ia64" ], 1 ], [ "!profile.stage1" "!profile.nocheck" ], "" ) -# ^^^ ^^ -# count of negated arches, if ! was given || -# rest (should always be "" for valid dependencies) +# splits "foo:bar (>= 1.2.3) [!i386 ia64] <stage1 !nocheck> <cross>" into +# ( "foo", "bar", [ ">=", "1.2.3" ], [ [ "i386", "ia64" ], 1 ], [ [ "stage1", "!nocheck" ] , [ "cross" ] ], "" ) +# ^^^ ^^ +# count of negated arches, if ! was given || +# rest (should always be "" for valid dependencies) sub _split_dep { my $dep = shift; my ($pkg, $dmarch, $version, $darch, $restr) @@ -1344,25 +1325,15 @@ sub _split_dep { } $darch->[1] = $negated; } - if ($dep && $dep =~ s/\s*<([^>]+)>\s*//) { + while ($dep && $dep =~ s/\s*<([^>]+)>\s*//) { my $t = $1; - $restr = [split /\s+/, $t]; + push @$restr, [ split /\s+/, $t ]; } } return ($pkg, $dmarch, $version, $darch, $restr, $dep); } -sub _load_dependency_restrictions { - my ($key, $value, $pval) = @_; - my $ret = undef; - if (not defined $pval) { - $ret = $pval = []; - } - push @{$pval}, $value; - return $ret; -} - sub perl_core_has_version { my ($package, $op, $version) = @_; my $core_version = $PERL_CORE_PROVIDES->value($package); diff --git a/data/fields/build-profiles b/data/fields/build-profiles new file mode 100644 index 0000000..7156bf1 --- /dev/null +++ b/data/fields/build-profiles @@ -0,0 +1,6 @@ +nocheck +stage1 +stage2 +cross +nodoc +nobiarch diff --git a/data/fields/dependency-restrictions b/data/fields/dependency-restrictions deleted file mode 100644 index f107b0c..0000000 --- a/data/fields/dependency-restrictions +++ /dev/null @@ -1,4 +0,0 @@ -profile.nocheck -profile.stage1 -profile.stage2 -profile.cross diff --git a/t/tests/fields-build-profiles-general/debian/debian/control.in b/t/tests/fields-build-profiles-general/debian/debian/control.in index 5c232a2..c0f2fe3 100644 --- a/t/tests/fields-build-profiles-general/debian/debian/control.in +++ b/t/tests/fields-build-profiles-general/debian/debian/control.in @@ -4,16 +4,30 @@ Section: devel Maintainer: {$author} Standards-Version: {$standards_version} Build-Depends: debhelper (>= 9), - big <profile.stage1>, bpfail1 <foobar>, - bpfail2 <foo.bar>, bpfail3 <profile.bar>, + big <stage1>, bpfail1 <foobar>, bpcomplicated <stage1 nocheck> <cross> Build-Conflicts: - dpkg-dev (>= 1.17.2), - debhelper (>= 9.20140227) + dpkg-dev (>= 1.17.XXX), + debhelper (>= 9.XXX) -Package: {$source} +Package: {$source}-wrong-syntax Architecture: {$architecture} Depends: $\{shlibs:Depends\}, $\{misc:Depends\} -Description: {$description} +Build-Profiles: !stage1 +Description: {$description} (wrong syntax) + Check the syntax of the Build-Profiles field + . + This is a test package designed to exercise some feature or tag of + Lintian. It is part of the Lintian test suite and may do very odd + things. It should not be installed like a regular package. It may + be an empty package. + +Package: {$source}-unknown-profile +Architecture: {$architecture} +Depends: $\{shlibs:Depends\}, $\{misc:Depends\} +Build-Profiles: <!stage1 !nocheck> <!unknown> +Description: {$description} (unknown profile) + Check for unknown profile names + . This is a test package designed to exercise some feature or tag of Lintian. It is part of the Lintian test suite and may do very odd things. It should not be installed like a regular package. It may diff --git a/t/tests/fields-build-profiles-general/desc b/t/tests/fields-build-profiles-general/desc index 25117a5..7996e5a 100644 --- a/t/tests/fields-build-profiles-general/desc +++ b/t/tests/fields-build-profiles-general/desc @@ -2,15 +2,14 @@ Testname: fields-build-profiles-general Sequence: 6000 Version: 1.0 Description: General tests for build profiles -# Build-profiles requires dpkg 1.17.2 -Test-Depends: dpkg (>= 1.17.2~) +# Build-profiles requires dpkg 1.17.XXX and debhelper 9.XXX +Test-Depends: dpkg (>= 1.17.2~), debhelper (>= 9.20140227) Test-For: - invalid-restriction-label-in-source-relation - invalid-restriction-namespace-in-source-relation - invalid-restriction-term-in-source-relation - restriction-list-with-debhelper-with-conflicting-debhelper-version - restriction-list-with-debhelper-without-debhelper-version - restriction-list-with-versioned-dpkg-dev-conflict - restriction-list-without-versioned-dpkg-dev-dependency - stageX-profile-used-but-no-binary-package-dropped + invalid-profile-name-in-source-relation + invalid-profile-name-in-build-profiles-field + invalid-restriction-formula-in-build-profiles-field + restriction-formula-with-debhelper-with-conflicting-debhelper-version + restriction-formula-with-debhelper-without-debhelper-version + restriction-formula-with-versioned-dpkg-dev-conflict + restriction-formula-without-versioned-dpkg-dev-dependency References: Debian Bug#540594, Debian Bug#551793 diff --git a/t/tests/fields-build-profiles-general/tags b/t/tests/fields-build-profiles-general/tags index b66cdfd..29b6921 100644 --- a/t/tests/fields-build-profiles-general/tags +++ b/t/tests/fields-build-profiles-general/tags @@ -1,8 +1,11 @@ -E: fields-build-profiles-general source: invalid-restriction-label-in-source-relation bar [build-depends: bpfail3 <profile.bar>] -E: fields-build-profiles-general source: invalid-restriction-namespace-in-source-relation foo [build-depends: bpfail2 <foo.bar>] -E: fields-build-profiles-general source: invalid-restriction-term-in-source-relation foobar [build-depends: bpfail1 <foobar>] -W: fields-build-profiles-general source: restriction-list-with-debhelper-with-conflicting-debhelper-version -W: fields-build-profiles-general source: restriction-list-with-debhelper-without-debhelper-version -W: fields-build-profiles-general source: restriction-list-with-versioned-dpkg-dev-conflict -W: fields-build-profiles-general source: restriction-list-without-versioned-dpkg-dev-dependency -W: fields-build-profiles-general source: stageX-profile-used-but-no-binary-package-dropped +E: fields-build-profiles-general source: invalid-profile-name-in-build-profiles-field unknown fields-build-profiles-general-unknown-profile +E: fields-build-profiles-general source: invalid-profile-name-in-source-relation foobar [build-depends: bpfail1 <foobar>] +E: fields-build-profiles-general source: invalid-restriction-formula-in-build-profiles-field !stage1 fields-build-profiles-general-wrong-syntax +W: fields-build-profiles-general source: restriction-formula-with-debhelper-with-conflicting-debhelper-version +W: fields-build-profiles-general source: restriction-formula-with-debhelper-with-conflicting-debhelper-version +W: fields-build-profiles-general source: restriction-formula-with-debhelper-without-debhelper-version +W: fields-build-profiles-general source: restriction-formula-with-debhelper-without-debhelper-version +W: fields-build-profiles-general source: restriction-formula-with-versioned-dpkg-dev-conflict +W: fields-build-profiles-general source: restriction-formula-with-versioned-dpkg-dev-conflict +W: fields-build-profiles-general source: restriction-formula-without-versioned-dpkg-dev-dependency +W: fields-build-profiles-general source: restriction-formula-without-versioned-dpkg-dev-dependency -- 2.0.1

