source: MondoRescue/branches/3.0-mindi-2.1/mindi/mindi-get-perl-modules

Last change on this file was 3143, checked in by Bruno Cornec, 11 years ago

r5349@localhost: bruno | 2013-06-14 01:23:53 +0200

  • Adds pod content to the perl scripts used, and generate man pages frmo it as part of the install process. This also fixes rpmlint and deblint issues
  • Property svn:executable set to *
File size: 8.0 KB
Line 
1#!/usr/bin/perl -w
2#
3# $Id$
4# Copyright B. Cornec 2005-2013
5# Provided under the GPL v2
6#
7# Get perl modules required by mindi and mondo and that should be on the restore media
8#
9use strict;
10
11use File::Find;
12use Cwd;
13
14
15=pod
16
17=head1 NAME
18
19mindi-get-perl-modules keeps track of the perl modules that should be on your restore media
20
21=head1 DESCRIPTION
22
23mindi-get-perl-modules keeps track of the perl modules that should be on your restore media by analyzing the references made to them in the scripts passed as parameters and returning all the modules needed to have them work correctly.
24
25=head1 SYNOPSIS
26
27mindi-get-perl-modules /path/to/perl-script ...
28
29=head1 ARGUMENTS
30
31=over 4
32
33=item B</path/to/perl-script>
34
35This is the path of the perl script to analyze and for which we want its perl modules in dependence to be included
36
37=back
38
39=head1 WEB SITES
40
41The main Web site of the project is available at L<http://www.mondorescue.org>. Bug reports should be filled using the trac instance of the project at L<http://trac.mondorescue.org/>.
42
43=head1 USER MAILING LIST
44
45For community exchanges around MondoRescue please use the list L<http://sourceforge.net/mailarchive/forum.php?forum_name=mondo-devel>
46
47=head1 AUTHORS
48
49The MondoRescue team lead by Bruno Cornec L<mailto:bruno@mondorescue.org>.
50
51=head1 COPYRIGHT
52
53MondoRescue is distributed under the GPL v2.0 license or later,
54described in the file C<COPYING> included with the distribution.
55
56=cut
57
58
59my $file = get_perl_modules(@ARGV) if (defined $ARGV[0]);
60
61foreach my $f (sort keys %$file) {
62 print "$f\n";
63}
64
65sub get_perl_modules {
66
67my %files;
68
69#print "Searching in ";
70#print join "\n", @INC;
71
72my $require = process_file(@_);
73
74my @includes;
75
76# Remove non exiting directories from @INC
77# and thus avoid perl warnings
78#
79foreach my $d (@INC) {
80 $d = read_all_link($d) if (-l $d);
81 push @includes,$d if (-d $d);
82}
83
84find(
85 sub {
86 if ((-f $File::Find::name)
87 && (/\.pm$/)
88 && (not defined $files{$File::Find::name})) {
89 foreach my $m (keys %$require,"warnings") {
90 (my $mod = $m) =~ s|::|/|g;
91 #print "Looking at $mod in $File::Find::name\n";
92 if (index($File::Find::name,"$mod.pm") ne -1) {
93 $files{$File::Find::name} = $mod;
94 #push @files, $File::Find::name;
95 #print "Found $mod in $File::Find::name\n";
96 last;
97 }
98 }
99 }
100 },
101 @includes);
102
103return(\%files);
104}
105
106# Cf: http://www.stonehenge.com/merlyn/UnixReview/col27.html
107sub read_all_link {
108
109my $dir = cwd;
110my $link;
111
112find sub {
113 return unless -l;
114 my @right = split /\//, $File::Find::name;
115 my @left = do {
116 @right && ($right[0] eq "") ?
117 shift @right : # quick way
118 split /\//, $dir;
119 }; # first element always null
120 while (@right) {
121 my $item = shift @right;
122 next if $item eq "." or $item eq "";
123 if ($item eq "..") {
124 pop @left if @left > 1;
125 next;
126 }
127 my $link = readlink (join "/", @left, $item);
128 if (defined $link) {
129 my @parts = split /\//, $link;
130 if (@parts && ($parts[0] eq "")) { # absolute
131 @left = shift @parts; # quick way
132 }
133 unshift @right, @parts;
134 next;
135 } else {
136 push @left, $item;
137 next;
138 }
139 }
140 #print "$File::Find::name is ", join("/", @left), "\n";
141 $link = join("/", @left);
142}, @_;
143return($link);
144}
145
146# Adapted From /usr/lib/rpm/mandriva/perl.req
147# by Ken Estes Mail.com kestes@staff.mail.com
148
149sub process_file {
150
151my %line;
152my %require;
153my $current_line;
154my $tag;
155
156foreach my $file (@_) {
157
158 open(FILE, "<$file") || return(\%require);
159 while (<FILE>) {
160
161 # skip the "= <<" block
162
163 if ( ( m/^\s*\$(.*)\s*=\s*<<\s*["'](.*)['"]/i) ||
164 ( m/^\s*\$(.*)\s*=\s*<<\s*(.*);/i) ) {
165 $tag = $2;
166 while (<FILE>) {
167 ( $_ =~ /^$tag/) && last;
168 }
169 }
170
171 # skip the documentation
172
173 # we should not need to have item in this if statement (it
174 # properly belongs in the over/back section) but people do not
175 # read the perldoc.
176
177 if ( (m/^=(head1|head2|pod|item)/) .. (m/^=(cut)/) ) {
178 next;
179 }
180
181 if ( (m/^=(over)/) .. (m/^=(back)/) ) {
182 next;
183 }
184
185 # skip the data section
186 if (m/^__(DATA|END)__$/) {
187 last;
188 }
189
190 # Each keyword can appear multiple times. Don't
191 # bother with datastructures to store these strings,
192 # if we need to print it print it now.
193
194 if ( m/^\s*\$RPM_Requires\s*=\s*["'](.*)['"]/i) {
195 foreach $_ (split(/\s+/, $1)) {
196 print "$_\n";
197 }
198 }
199
200 if (
201
202# ouch could be in a eval, perhaps we do not want these since we catch
203# an exception they must not be required
204
205# eval { require Term::ReadLine } or die $@;
206# eval "require Term::Rendezvous;" or die $@;
207# eval { require Carp } if defined $^S; # If error/warning during compilation,
208
209
210 (m/^(\s*) # we hope the inclusion starts the line
211 (require|use)\s+(?!\{) # do not want 'do bracket' loops
212 # quotes around name are always legal
213 [\'\"]?([^\;\ \'\"\t]*)[\'\"]?[\t\;\ ]
214 # the syntax for 'use' allows version requirements
215 \s*([.0-9]*)
216 /x)
217 ) {
218 my ($whitespace, $statement, $module, $version) = ($1, $2, $3,$4);
219 my $usebase;
220
221 # we only consider require statements that are flush against
222 # the left edge. any other require statements give too many
223 # false positives, as they are usually inside of an if statement
224 # as a fallback module or a rarely used option
225
226 ($whitespace ne "" && $statement eq "require") && next;
227
228 # if there is some interpolation of variables just skip this
229 # dependency, we do not want
230 # do "$ENV{LOGDIR}/$rcfile";
231
232 ($module =~ m/\$/) && next;
233
234 # skip if the phrase was "use of" -- shows up in gimp-perl, et al
235 next if $module eq 'of';
236
237 # if the module ends in a comma we probaly caught some
238 # documentation of the form 'check stuff,\n do stuff, clean
239 # stuff.' there are several of these in the perl distribution
240
241 ($module =~ m/[,>]$/) && next;
242
243 # if the module name starts in a dot it is not a module name.
244 # Is this necessary? Please give me an example if you turn this
245 # back on.
246
247 # ($module =~ m/^\./) && next;
248
249 # if the module ends with .pm strip it to leave only basename.
250 # starts with /, which means its an absolute path to a file
251 if ($module =~ m(^/)) {
252 print "$module\n";
253 next;
254 }
255
256 # as seen in some perl scripts
257 # use base qw(App::CLI Class::Accessor::Chained::Fast App::CLI::Command);
258 if ($module eq 'base') {
259 $require{$module} = $version;
260 $line{$module} = $current_line;
261 ($module = $_) =~ s/use\s*base\s*//;
262 $module =~ s/qw\((.*)\)\s*;/$1/;
263 $module =~ s/qw(.)(.*)\1\s*;/$2/;
264 $module =~ s/\s*;$//;
265 $module =~ s/#.*//;
266 $usebase = 1;
267 }
268 # sometimes people do use POSIX qw(foo), or use POSIX(qw(foo)) etc
269 # we can strip qw.*$, as well as (.*$:
270 $module =~ s/qw.*$//;
271 $module =~ s/\(.*$//;
272
273 $module =~ s/\.pm$//;
274
275 # some perl programmers write 'require URI/URL;' when
276 # they mean 'require URI::URL;'
277
278 $module =~ s/\//::/;
279
280 # trim off trailing parenthesis if any. Sometimes people pass
281 # the module an empty list.
282
283 $module =~ s/\(\s*\)$//;
284
285 # if module is a number then both require and use interpret that
286 # to mean that a particular version of perl is specified. Don't
287 # add a dependency, though, since the rpm will already require
288 # perl-base at the build version (via find-requires)
289 next if $module =~ /^v?\d/;
290
291 # ph files do not use the package name inside the file.
292 # perlmodlib documentation says:
293 # the .ph files made by h2ph will probably end up as
294 # extension modules made by h2xs.
295 # so do not spend much effort on these.
296
297 # there is no easy way to find out if a file named systeminfo.ph
298 # will be included with the name sys/systeminfo.ph so only use the
299 # basename of *.ph files
300
301 ($module =~ m/\.ph$/) && next;
302
303 # if the module was loaded trough base, we need to split the list
304 if ($usebase) {
305 my $current_line = $_;
306 foreach (split(/\s+/, $module)) {
307 next unless $_;
308 $require{$_} = $version;
309 $line{$_} = $current_line;
310 }
311 } else {
312 $require{$module}=$version;
313 $line{$module}=$current_line;
314 }
315 }
316 }
317
318close(FILE) || die("$0: Could not close file: '$file' : $!\n");
319}
320
321return(\%require);
322}
Note: See TracBrowser for help on using the repository browser.