Package: lintian Severity: wishlist Tags: patch X-Debbugs-Cc: de...@debian.org
Hi, I would like lintian to complain a bit more about Replaces. Correct uses of Replaces ======================== The most common way to use Replaces is matching it up with Breaks as this is recommeded by policy. Another use (also detailed by policy) is matching it up with Conflicts. A lesser known, but also frequent use (thanks to David Kalnischkies) is combining versioned Replaces with precluding Depends. I want lintian to not moan about any of these. Debatable uses of Replaces ========================== Sometimes, Replaces are used with a << version constraint but without matching them up with Breaks nor Conflicts. This can be useful for taking over non-essential files from a package (e.g. splitting documentation from a library). Such cases are still broken if you try to reinstall the replaced package, but that's not a frequent use and having less Breaks is beneficial to upgrade paths. I think it is best for lintian to not moan about any of these unless we grow consensus that we need to do something about it. Bad uses of Replaces ==================== The remaining Replaces are thus unversioned and not matched up with Breaks nor Conflicts. In these case, one could remove the replaced package and later install it again. While the janitor is able to eventually delete versioned Replaces, it cannot assist with cleaning up unversioned ones. Finally, Replaces pose a vital role in the /usr-merge transition as they can be broken when moving files from / to /usr, so we want to reduce the use of Replaces to the cases that really need them. For these reasons, I think that this third class of Replaces really is harmful enough to the project that it is worth fixing them. In a lot of cases, I expect that these Replaces are leftovers from the last decade and we can probably just drop them. In other cases, we can add a version restriction and improve reasoning about it. I hope you agree with this reasoning. I've discussed this with a number of participants on the Debian Reunion Hamburg 2023 and with some people on IRC. I think what I am presenting here is close to consensus. I'm also attaching a patch to implement the proposed check. Unfortunately, neither me nor gregoa nor carnil were able to please perlcritic (which for some reason is complaining about unrelated code and we couldn't understand what it is complaining about), so this patch currently fails one test. Would you be able to figure out why perlcritic is mad at this patch? Thanks in advance Helmut
diff -Nru lintian-2.116.3/debian/changelog lintian-2.116.3+nmu1/debian/changelog --- lintian-2.116.3/debian/changelog 2023-02-05 09:10:20.000000000 +0100 +++ lintian-2.116.3+nmu1/debian/changelog 2023-05-24 08:21:25.000000000 +0200 @@ -1,3 +1,10 @@ +lintian (2.116.3+nmu1) UNRELEASED; urgency=medium + + * Non-maintainer upload. + * New tag unguarded-replaces: Complain about unversiond Replaces that + are matched with neither Breaks nor Conflicts. (Closes: #-1) + + -- Helmut Grohne <hel...@subdivi.de> Wed, 24 May 2023 08:21:25 +0200 + lintian (2.116.3) unstable; urgency=medium The "FFP3 (Fixing False Positives, Three Small Changes)" Release. diff -Nru lintian-2.116.3/lib/Lintian/Check/Fields/PackageRelations.pm lintian-2.116.3+nmu1/lib/Lintian/Check/Fields/PackageRelations.pm --- lintian-2.116.3/lib/Lintian/Check/Fields/PackageRelations.pm 2022-07-02 15:47:11.000000000 +0200 +++ lintian-2.116.3+nmu1/lib/Lintian/Check/Fields/PackageRelations.pm 2023-05-24 08:13:03.000000000 +0200 @@ -219,6 +219,15 @@ && !$VIRTUAL_PACKAGES->recognizes($d_pkg) && !$replaces->satisfies($part_d_orig)); + $self->hint('unguarded-replaces', $part_d_orig) + if ( $field eq 'Replaces' + && !$d_version->[0] + && !any { + any { + $_->satisfies($part_d_orig) + } $processable->relation($_) + } qw(Breaks Conflicts)); + $self->hint('conflicts-with-version', $part_d_orig) if ($field eq 'Conflicts' && $d_version->[0]); diff -Nru lintian-2.116.3/t/recipes/checks/fields/package-relations/fields-depends-general/eval/hints lintian-2.116.3+nmu1/t/recipes/checks/fields/package-relations/fields-depends-general/eval/hints --- lintian-2.116.3/t/recipes/checks/fields/package-relations/fields-depends-general/eval/hints 2022-12-22 12:47:19.000000000 +0100 +++ lintian-2.116.3+nmu1/t/recipes/checks/fields/package-relations/fields-depends-general/eval/hints 2023-05-24 08:21:25.000000000 +0200 @@ -28,3 +28,4 @@ fields-depends-general (binary): conflicts-with-dependency Depends conflict-dep fields-depends-general (binary): breaks-without-version package-without-version fields-depends-general (binary): binary-package-depends-on-toolchain-package Depends: debhelper +fields-depends-general (binary): unguarded-replaces Replaces: replaced-wo-version diff -Nru lintian-2.116.3/tags/u/unguarded-replaces.tag lintian-2.116.3+nmu1/tags/u/unguarded-replaces.tag --- lintian-2.116.3/tags/u/unguarded-replaces.tag 1970-01-01 01:00:00.000000000 +0100 +++ lintian-2.116.3+nmu1/tags/u/unguarded-replaces.tag 2023-05-24 08:20:59.000000000 +0200 @@ -0,0 +1,10 @@ +Tag: unguarded-replaces +Severity: warning +Check: fields/package-relations +See-Also: debian-policy 7.6 +Explanation: This package declares that replaces another package without + further restrictions. If the package being replaced is supposed to go + away entirely, an unversioned Replaces declaration should be combined with + an unversioned Conflicts declaration. If files are being replaced in an old + version, the Replaces declaration should include a (<< ...) version + constraint.