1 # debhelper format -- lintian check script -*- perl -*-
3 # Copyright (C) 1999 by Joey Hess
5 # This program is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 2 of the License, or
8 # (at your option) any later version.
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with this program. If not, you can find it on the World Wide
17 # Web at http://www.gnu.org/copyleft/gpl.html, or write to the Free
18 # Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
21 package Lintian::debhelper;
31 use lib "$ENV{'LINTIAN_ROOT'}/lib";
37 my $needbuilddepends = '';
38 my $needtomodifyscripts = '';
39 my $needversiondepends = '';
40 my $seenversiondepends = '0';
43 my $seendhpython = '';
44 my $usescdbspython = '';
46 # If there is no debian/compat file present but cdbs is being used, cdbs will
47 # create one automatically. Currently it always uses compatibility level 4.
48 # It may be better to look at what version of cdbs the package depends on and
49 # from that derive the compatibility level....
53 # Parse the debian/rules file, and try to figure out if debhelper commands
54 # are run in it that like to modify maintainer scripts. Those debhelper
55 # commands can be found by "grep -l autoscript /usr/bin/dh_*", but I'll
58 map { $commands{$_}=1 } qw(dh_desktop
85 # The version at which debhelper commands were introduced. Packages that use
86 # one of these commands must have a dependency on that version of debhelper or
89 = (dh_icons => '5.0.51~',
90 dh_installifupdown => '5.0.44~',
91 dh_lintian => '6.0.7~',
94 open(RULES, '<', "debfiles/rules") or fail("cannot read debian/rules: $!");
98 if (m/^\s+(dh_\w+)/) {
100 if ($dhcommand =~ /dh_testversion(?:\s+(.+))?/) {
101 $needversiondepends = $1 if ($1);
102 tag "dh_testversion-is-deprecated", "";
104 if ($dhcommand eq 'dh_dhelp') {
105 tag "dh_dhelp-is-deprecated", "";
107 if ($dhcommand eq 'dh_suidregister') {
108 tag "dh_suidregister-is-obsolete", "";
110 # if command is passed -n, it does not modify the scripts
111 if ($commands{$dhcommand} and not m/\s+\-n\s+/) {
112 $needtomodifyscripts = 1;
114 if ($versions{$dhcommand}) {
115 push (@versioncheck, $dhcommand);
118 $needbuilddepends = 1;
119 } elsif (m,^\s+dh\s+,) {
121 $needbuilddepends = 1;
122 push (@versioncheck, 'dh');
123 } elsif (m,^include\s+/usr/share/cdbs/1/rules/debhelper.mk,) {
125 $needbuilddepends = 1;
126 $needtomodifyscripts = 1;
128 # CDBS sets DH_COMPAT but doesn't export it. It does, however, create
129 # a debian/compat file if none was found; that logic is handled later.
130 $dhcompatvalue = $cdbscompat;
132 } elsif (/^\s*export\s+DH_COMPAT\s*:?=\s*(\d+)/) {
133 $needversiondepends = $1;
134 } elsif (/^\s*export\s+DH_COMPAT/) {
135 $needversiondepends = $dhcompatvalue if $dhcompatvalue;
136 } elsif (/^\s*DH_COMPAT\s*:?=\s*(\d+)/) {
139 if (/^\s+dh_python\s/) {
141 } elsif (m,^include\s+/usr/share/cdbs/1/class/python-distutils.mk,) {
147 return unless $seencommand;
149 # We may need to make a difference between deb and udeb packages
151 my (%pkgs, $single_pkg);
152 opendir(BINPKGS, 'control')
153 or fail("Can't open control directory.");
154 while(my $binpkg = readdir(BINPKGS)) {
155 next if $binpkg =~ /^\.\.?$/;
156 if (-d "control/$binpkg") {
157 if (open TYPE, "<", "control/$binpkg/xc-package-type") {
158 $pkgs{$binpkg} = <TYPE> || 'deb';
160 $pkgs{$binpkg} = 'deb';
162 $single_pkg = $pkgs{$binpkg};
165 $single_pkg = undef unless keys(%pkgs) == 1;
167 # If we got this far, they need to have #DEBHELPER# in their scripts. Search
168 # for scripts that look like maintainer scripts. Also collect dependency
169 # information from debian/control and check compatibility level.
171 opendir(DEBIAN, 'debfiles')
172 or fail("Can't open debfiles directory.");
173 while (defined(my $file=readdir(DEBIAN))) {
174 if ($file =~ m/^(?:(.*)\.)?(?:post|pre)(?:inst|rm)$/) {
175 my $binpkg = $1 || '';
176 open(IN, '<', "debfiles/$file")
177 or fail("Can't open debfiles/$file: $!");
180 if (m/\#DEBHELPER\#/) {
187 if ((! $seentag) and $needtomodifyscripts) {
188 unless (($binpkg && $pkgs{$binpkg} && ($pkgs{$binpkg} =~ /udeb/i))
189 or (!$binpkg && $single_pkg && ($single_pkg =~ /udeb/i))) {
190 tag "maintainer-script-lacks-debhelper-token", "debian/$file";
193 } elsif ($file =~ m/^compat$/) {
194 open (IN, '<', "debfiles/$file")
195 or fail("Can't open debfiles/$file: $!");
200 if ($needversiondepends) {
201 tag "declares-possibly-conflicting-debhelper-compat-versions", "rules=$needversiondepends compat=$compat";
203 $needversiondepends = $compat;
206 tag "debhelper-compat-file-is-empty", "";
208 } elsif ($file =~ m/^control$/) {
209 my ($control) = read_dpkg_control("debfiles/$file");
211 for my $field ('build-depends', 'build-depends-indep') {
212 next unless $control->{$field};
213 $depends .= ', ' if $depends;
214 $depends .= $control->{$field};
216 $depends = Dep::parse($depends);
217 if ($needbuilddepends && ! Dep::implies($depends, Dep::parse('debhelper'))) {
218 tag "package-uses-debhelper-but-lacks-build-depends", "";
220 } elsif ($file =~ m/^ex\.|\.ex$/i) {
221 tag "dh-make-template-in-source", "debian/$file";
226 # Check for Python policy usage and the required debhelper dependency for
227 # dh_python policy support. Assume people who intentionally set pycompat to
228 # something earlier than 2 know what they're doing. Skip CDBS packages since
229 # CDBS creates pycompat internally at build time.
230 if ($seendhpython && !$usescdbspython) {
231 if (open(PYCOMPAT, '<', "debfiles/pycompat")) {
233 my $pycompat = <PYCOMPAT>;
235 if ($pycompat >= 2 && ! Dep::implies($depends, Dep::parse('debhelper (>= 5.0.37.2)'))) {
236 tag "package-needs-python-policy-debhelper", "";
239 tag "uses-dh-python-with-no-pycompat", "";
243 if ($usescdbs and not $needversiondepends) {
244 $needversiondepends = $cdbscompat;
246 $needversiondepends ||= 1;
247 if ($needversiondepends < 4) {
248 tag "package-uses-deprecated-debhelper-compat-version", $needversiondepends;
249 } elsif ($needversiondepends > 4 and ! Dep::implies($depends, Dep::parse("debhelper (>= $needversiondepends)"))) {
250 tag "package-lacks-versioned-build-depends-on-debhelper", $needversiondepends;
251 } elsif (@versioncheck) {
252 for my $program (@versioncheck) {
253 my $required = $versions{$program};
254 tag 'debhelper-script-needs-versioned-build-depends', $program, "(>= $required)"
255 unless Dep::implies($depends, Dep::parse("debhelper (>= $required)"));