Added some code to peer into a data structure in Maemian/Schedule.pm. Also added the
[maemian] / nokia-lintian / checks / debhelper
1 # debhelper format -- lintian check script -*- perl -*-
2
3 # Copyright (C) 1999 by Joey Hess
4 #
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.
9 #
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.
14 #
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,
19 # MA 02110-1301, USA.
20
21 package Lintian::debhelper;
22 use strict;
23 use Tags;
24 use Util;
25
26 sub run {
27
28 my $pkg = shift;
29 my $type = shift;
30
31 use lib "$ENV{'LINTIAN_ROOT'}/lib";
32 use Dep;
33
34 my %commands;
35
36 my $seencommand = '';
37 my $needbuilddepends = '';
38 my $needtomodifyscripts = '';
39 my $needversiondepends = '';
40 my $seenversiondepends = '0';
41 my $compat = '';
42 my $usescdbs = '';
43 my $seendhpython = '';
44 my $usescdbspython = '';
45
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....
50
51 my $cdbscompat = 5;
52
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
56 # hardcode them here.
57
58 map { $commands{$_}=1 } qw(dh_desktop
59                            dh_gconf
60                            dh_icons
61                            dh_installcatalogs
62                            dh_installdebconf
63                            dh_installdefoma
64                            dh_installdocs
65                            dh_installemacsen
66                            dh_installinfo
67                            dh_installinit
68                            dh_installmenu
69                            dh_installmime
70                            dh_installmodules
71                            dh_installtex
72                            dh_installudev
73                            dh_installwm
74                            dh_installxfonts
75                            dh_installxmlcatalogs
76                            dh_makeshlibs
77                            dh_pycentral
78                            dh_pysupport
79                            dh_python
80                            dh_scrollkeeper
81                            dh_suidregister
82                            dh_usrlocal
83                            );
84
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
87 # newer.
88 my %versions
89     = (dh_icons           => '5.0.51~',
90        dh_installifupdown => '5.0.44~',
91        dh_lintian         => '6.0.7~',
92        dh                 => '7');
93
94 open(RULES, '<', "debfiles/rules") or fail("cannot read debian/rules: $!");
95 my $dhcompatvalue;
96 my @versioncheck;
97 while (<RULES>) {
98     if (m/^\s+(dh_\w+)/) {
99         my $dhcommand = $1;
100         if ($dhcommand =~ /dh_testversion(?:\s+(.+))?/) {
101             $needversiondepends = $1 if ($1);
102             tag "dh_testversion-is-deprecated", "";
103         }
104         if ($dhcommand eq 'dh_dhelp') {
105             tag "dh_dhelp-is-deprecated", "";
106         }
107         if ($dhcommand eq 'dh_suidregister') {
108             tag "dh_suidregister-is-obsolete", "";
109         }
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;
113         }
114         if ($versions{$dhcommand}) {
115             push (@versioncheck, $dhcommand);
116         }
117         $seencommand = 1;
118         $needbuilddepends = 1;
119     } elsif (m,^\s+dh\s+,) {
120         $seencommand = 1;
121         $needbuilddepends = 1;
122         push (@versioncheck, 'dh');
123     } elsif (m,^include\s+/usr/share/cdbs/1/rules/debhelper.mk,) {
124         $seencommand = 1;
125         $needbuilddepends = 1;
126         $needtomodifyscripts = 1;
127
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;
131         $usescdbs = 1;
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+)/) {
137         $dhcompatvalue = $1;
138     }
139     if (/^\s+dh_python\s/) {
140         $seendhpython = 1;
141     } elsif (m,^include\s+/usr/share/cdbs/1/class/python-distutils.mk,) {
142         $usescdbspython = 1;
143     }
144 }
145 close RULES;
146
147 return unless $seencommand;
148
149 # We may need to make a difference between deb and udeb packages
150 # so try to find out
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';
159         } else {
160             $pkgs{$binpkg} = 'deb';
161         }
162         $single_pkg = $pkgs{$binpkg};
163     }
164 }
165 $single_pkg = undef unless keys(%pkgs) == 1;
166
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.
170 my $depends;
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: $!");
178         my $seentag = '';
179         while (<IN>) {
180             if (m/\#DEBHELPER\#/) {
181                 $seentag = 1;
182                 last;
183             }
184         }
185         close IN;
186
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";
191             }
192         }
193     } elsif ($file =~ m/^compat$/) {
194         open (IN, '<', "debfiles/$file")
195             or fail("Can't open debfiles/$file: $!");
196         $compat = <IN>;
197         close IN;
198         if ($compat) {
199             chomp $compat;
200             if ($needversiondepends) {
201                 tag "declares-possibly-conflicting-debhelper-compat-versions", "rules=$needversiondepends compat=$compat";
202             } else {
203                 $needversiondepends = $compat;
204             }
205         } else {
206             tag "debhelper-compat-file-is-empty", "";
207         }
208     } elsif ($file =~ m/^control$/) {
209         my ($control) = read_dpkg_control("debfiles/$file");
210         $depends = '';
211         for my $field ('build-depends', 'build-depends-indep') {
212             next unless $control->{$field};
213             $depends .= ', ' if $depends;
214             $depends .= $control->{$field};
215         }
216         $depends = Dep::parse($depends);
217         if ($needbuilddepends && ! Dep::implies($depends, Dep::parse('debhelper'))) {
218             tag "package-uses-debhelper-but-lacks-build-depends", "";
219         }
220     } elsif ($file =~ m/^ex\.|\.ex$/i) {
221         tag "dh-make-template-in-source", "debian/$file";
222     }
223 }
224 closedir(DEBIAN);
225
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")) {
232         local $/;
233         my $pycompat = <PYCOMPAT>;
234         close PYCOMPAT;
235         if ($pycompat >= 2 && ! Dep::implies($depends, Dep::parse('debhelper (>= 5.0.37.2)'))) {
236             tag "package-needs-python-policy-debhelper", "";
237         }
238     } else {
239         tag "uses-dh-python-with-no-pycompat", "";
240     }
241 }
242
243 if ($usescdbs and not $needversiondepends) {
244     $needversiondepends = $cdbscompat;
245 }
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)"));
256     }
257 }
258
259 }
260
261 1;
262
263 # vim: syntax=perl