]> git.pld-linux.org Git - packages/pldcpan.git/blame - pldcpan.pl
- avoid perl(perl) requires
[packages/pldcpan.git] / pldcpan.pl
CommitLineData
6f720ca8 1#!/usr/bin/perl -w
fa776f89
AG
2# Requirements:
3# perl-Pod-Tree perl-Archive-Any perl-Template-Toolkit perl-YAML perl-IO-String
4# perl-File-Iterator perl-Module-CoreList
6f720ca8 5use strict;
0a7642e7 6
7use Cwd qw( getcwd );
8use Getopt::Long qw( GetOptions );
9use IPC::Run qw( run timeout );
10use Pod::Select qw( podselect );
11
12use Pod::Tree ();
13use Archive::Any ();
14use Template ();
15use YAML ();
16use Digest::MD5 ();
17use IO::String ();
18use File::Iterator ();
19use Module::CoreList ();
20use LWP::Simple ();
857f480b 21
6bc1e5d3
ER
22=cut
23TODO/Wishlist
24
6bc1e5d3
ER
25- use poldek to search if dir should be packaged:
26$ poldek -q --cmd search -f /usr/share/perl5/vendor_perl/Text
27perl-base-5.8.7-4
28- first could be checked if the dir is contained by perl-base (will be faster
29than querying poldek)
6bc1e5d3
ER
30
31=cut
6f720ca8 32
093f435f 33our $VERSION = sprintf "%d.%02d", q$Revision$ =~ /(\d+)/g;
0a7642e7 34our %opts;
157e61cd 35GetOptions(\%opts, 'verbose|v', 'modulebuild|B', 'makemaker|M', 'force');
6f720ca8 36eval "use Data::Dump qw(pp);" if $opts{verbose};
7ad57c63 37die $@ if $@;
6f720ca8 38
7c639a18 39unless (@ARGV) {
40 die <<'EOF';
41usage:
dbdc4dab 42 pldcpan.pl [ OPTIONS ] DIST [ DIST2 DIST3 ... ]
7c639a18 43
44options:
45 -v|--verbose shout, and shout loud
e208a9ad 46 -B|--modulebuild prefer Module::Build (default)
47 -M|--makemaker prefer ExtUtils::MakeMaker
157e61cd 48 --force overwrite existing *.spec files
7c639a18 49
50This program uncompresses given archives in the current directory
51and -- more or less successfully -- attempts to write corresponding
52perl-*.spec files.
53
dbdc4dab 54DIST can be a directory, a compressed archive, URL to fetch or module
55name (Foo::Bar) to be found on search.cpan.org.
56
7c639a18 57$Id$
58EOF
59}
60
d0f6eca7 61# get maximum information from directory name
6f720ca8 62sub test_directory {
63 my $fooball = shift;
64 my $info = shift;
65 return $info->{_tests}->{directory}
66 if defined $info->{_tests}->{directory};
67
d0f6eca7 68 # FIXME: use -v (hmm, what did I meant?)
6f720ca8 69 unless (
70 $fooball =~ m#^
71 (?:.*/)?
72 (
73 [a-z][a-z\d]*
74 (?:
75 ([-_])[a-z][a-z\d]*
76 (?: \2[a-z][a-z\d]*)*
77 )?
78 )
79 -
157e61cd 80 (\d[\d._-]*[a-z]?\d*)
7c639a18 81 /*$ #ix
6f720ca8 82 )
83 {
84 warn " -- cannot resolve name and version: '$fooball'\n";
85 return $info->{_tests}->{directory} = 0;
86 }
87
88 $info->{ballname} = $1;
89 $info->{namme} = $1;
90 $info->{version} = $3;
91 {
92 my $separ = $2;
93 @{$info}{qw(pdir pnam)} = $separ
94 ? (split /$separ/, $info->{ballname}, 2)
95 : ($info->{ballname}, undef);
96 $info->{parts} =
97 [$separ ? (split /$separ/, $info->{ballname}) : ($info->{ballname})];
98 }
581ece85 99 $info->{parts_joined} = join '::', @{ $info->{parts} };
6f720ca8 100 $info->{_tests}->{directory} = 1;
101}
102
103sub test_archive_name {
104 my (undef, $info) = @_;
105 return $info->{_tests}->{archive_name}
106 if defined $info->{_tests}->{archive_name};
107 (my $d = shift) =~
108 s/\.(?:(?:tar\.)?(?:gz|bz2|Z)|tar|tgz|zip|rar|arj|lha)$//;
109 $info->{_tests}->{archive_name} = test_directory($d, @_);
110}
111
112sub test_has_tests {
113 my $info = shift;
114 return $info->{_tests}->{has_tests}
115 if defined $info->{_tests}->{has_tests};
116 die "not a directory ($info->{dir})!" unless -d $info->{dir};
117
118 if (-d "$info->{dir}/t" || -f "$info->{dir}/test.pl") {
119 $info->{tests}++;
120 return $info->{_tests}->{has_tests} = 1;
121 }
122 $info->{_tests}->{has_tests} = 0;
123}
124
125sub test_has_examples {
126 my $info = shift;
127 return $info->{_tests}->{has_examples}
128 if defined $info->{_tests}->{has_examples};
129 die "not a directory ($info->{dir})!" unless -d $info->{dir};
130
131 $info->{examples} =
7ad57c63 132 [grep -e,
133 map { $_, lc $_, uc $_ } qw(Example Examples Eg Sample Samples)];
6f720ca8 134 $info->{_tests}->{has_examples} = @{ $info->{examples} } ? 1 : 0;
135}
136
137sub test_has_doc_files {
138 my $info = shift;
139 return $info->{_tests}->{has_doc_files}
140 if defined $info->{_tests}->{has_doc_files};
141 die "not a directory ($info->{dir})!" unless -d $info->{dir};
142 my %tmp;
143 $info->{doc_files} = [
144 grep -e,
145 grep !$tmp{$_}++,
146 map { $_, lc $_, uc $_ }
147 map { $_, "$_.txt", "$_.TXT" }
148 qw(AUTHORS BUGS ChangeLog Changes CREDITS doc docs documentation EXTRAS
1c2120f3 149 GOALS HACKING HISTORY INSTALL NEW NEWS NOTES PATCHING README DISCLAIMER
150 ToDo)
6f720ca8 151 ];
152 $info->{_tests}->{has_doc_files} = @{ $info->{doc_files} } ? 1 : 0;
153}
154
155sub test_license {
156 my $info = shift;
157 return $info->{_tests}->{license}
158 if defined $info->{_tests}->{license};
159 if (load_META_yml($info) && $info->{META_yml}->{license}) {
160 $info->{license} =
161 $info->{META_yml}->{license} =~ /^l?gpl$/
162 ? uc $info->{META_yml}->{license}
163 : $info->{META_yml}->{license};
3524180a 164 # This depends on test_find_summ_descr2
165 } elsif (my $license = $info->{pod_license}) {
166 $info->{license} = 'perl' if $license =~ /same terms as perl/i;
6f720ca8 167 }
168 $info->{_tests}->{license} = $info->{license} ? 1 : 0;
169}
170
171sub load_META_yml {
172 my $info = shift;
173 return $info->{_tests}->{license}
174 if defined $info->{_tests}->{license};
175 if (-f 'META.yml') {
176 $info->{META_yml} = YAML::LoadFile('META.yml');
177 }
4981c549 178
179 _remove_core_meta_requires($info, 'requires');
180 _remove_core_meta_requires($info, 'build_requires');
181
6f720ca8 182 $info->{_tests}->{license} = $info->{META_yml} ? 1 : 0;
183}
184
4981c549 185sub _remove_core_meta_requires {
186 my ($info, $key) = @_;
187
188 return if ref($info->{META_yml}->{$key}) ne 'HASH';
189
889889ac 190 # avoid perl(perl) >= 5.6... requires
191 delete $info->{META_yml}->{$key}->{perl};
192
4981c549 193 while (my ($module, $version) = each %{ $info->{META_yml}->{$key} }) {
194 my $result;
195 print "Checking dependency: $module $version\n" if $opts{verbose};
196 if ($version) {
197 $result = Module::CoreList->first_release($module, $version);
198 } else {
199 $result = Module::CoreList->first_release($module);
200 }
201 # $] - perl version
202 if ( $result and $result < $] ) {
203 if ($opts{verbose}) {
204 print "Module $module availablie in core since $result, skipping\n"
205 }
206 delete $info->{META_yml}->{$key}->{$module};
207 }
208 }
209}
210
6f720ca8 211sub test_find_pod_file {
212 my $info = shift;
213 return $info->{_tests}->{find_pod_file}
214 if defined $info->{_tests}->{find_pod_file};
215 die "not a directory ($info->{dir})!" unless -d $info->{dir};
216
217 my $pod_file;
6f720ca8 218
3524180a 219 my $mfile = @{ $info->{parts} }[-1];
af079f8a 220 if (!defined $mfile) {
221 warn " .. unable to search for \$pod_file without parts\n";
222 return $info->{_tests}->{find_pod_file} = 0;
223 }
224 my $it = File::Iterator->new(
6f720ca8 225 DIR => $info->{dir},
226 RECURSE => 1,
6f870f0f 227 FILTER =>
228 sub { $_[0] =~ m#(?:^|/)\Q$mfile\E\.(?:pod|pm)$# && $_[0] !~ m#/t/# }
6f720ca8 229 );
230 my ($pm, $pod);
6f870f0f 231 while (my $f = $it->next()) {
232 $pod = $f if $f =~ /\.pod$/;
233 $pm = $f if $f =~ /\.pm$/;
6f720ca8 234 }
235 $pod_file = $pod ? $pod : $pm;
236 if ( !$pod_file
237 && load_META_yml($info)
238 && exists $info->{META_yml}->{version_from})
239 {
240 $pod_file = $info->{META_yml}->{version_from};
241 }
d0f6eca7 242
243 unless ($pod_file) {
244 warn " -- no \$pod_file <@{$info->{parts}}>\n";
245 return $info->{_tests}->{find_pod_file} = 0;
246 }
247
248 my $tree = new Pod::Tree;
249 $tree->load_file($pod_file);
250 unless ($tree->has_pod) {
251 warn " ,, no POD in $pod_file\n";
252 return $info->{_tests}->{find_pod_file} = 0;
253 }
254
af079f8a 255 $info->{_podtree} = $tree;
256 $info->{pod_file} = $pod_file;
d0f6eca7 257 $info->{_tests}->{find_pod_file} = 1;
258}
6f720ca8 259
d0f6eca7 260# workaround for Pod::Parser not supporting "\r\n" line endings
261{
016e2ea6 262 no warnings 'redefine';
d0f6eca7 263
264 sub Pod::Parser::preprocess_line {
265 (my $text = $_[1]) =~ y/\r//d;
266 $text;
267 }
6f720ca8 268}
269
98a3ea33 270sub test_find_summ_descr2 {
271 my $info = shift;
272
273 return $info->{_tests}->{find_summ_descr} = 0
274 unless test_find_pod_file($info);
275
276 my $tree = $info->{_podtree};
277 my $handler = _get_node_handler();
278 $tree->walk( $handler );
279 ($info->{summary}, $info->{descr}, $info->{pod_license}) = $handler->('data');
280}
281
282# This subroutine return closure to be used as a node handler in Pod::Tree walk() method
283sub _get_node_handler {
284 # state informaion
285 my $next_is_summary;
286 my $we_are_in_license;
287 my $we_are_in_description;
288 my $nodes_since_description_start;
289 # data we will return
290 my ($summary, $description, $license);
291
292 return sub {
293 my $node = shift;
294
295 # If not called with a node, then return collected data
296 if (!ref $node) {
297 $summary =~ s/^ \s* (.*?) \s* $/$1/gxm;
98a3ea33 298 return ($summary, $description, $license);
299 }
300
301 # We want to dive into root node. Note that this is the only
302 # place we ever descend into tree
303 return 1 if $node->is_root;
304
305 # If we have encountered any head command then abort collecting
306 # summary and description
307 my $command = $node->get_command;
ef80ea17 308 if ($node->is_command and $command =~ /head/) {
98a3ea33 309 if ($command eq 'head1' or $nodes_since_description_start > 3) {
310 $we_are_in_description = 0;
311 }
312 $next_is_summary = 0;
313 $we_are_in_license = 0;
314 }
315
316 # If previous element started an summary section, then treat
317 # this one as summary text.
318 if ($next_is_summary) {
157e61cd 319 ($summary = $node->get_deep_text) =~ y/\r//d;
98a3ea33 320 $summary =~ s/^\s+(.*?)\s+$/$1/;
321 $next_is_summary = 0;
322 return;
323 }
324 if ($we_are_in_license) {
157e61cd 325 ($license .= $node->get_text) =~ y/\r//d;
98a3ea33 326 return;
327 }
328
329 # If we started collecting description then add any ordinary
330 # node to collected description
331 if ($we_are_in_description) {
332 if ($nodes_since_description_start > 5) {
333 $we_are_in_description = 0;
334 }
335 elsif ($node->is_ordinary or $node->is_verbatim) {
157e61cd 336 ($description .= $node->get_deep_text) =~ y/\r//d;
98a3ea33 337 $nodes_since_description_start++;
338 }
339 else {
340 return;
341 }
342 }
343
344 # OK, next will be sumary text
345 if ($node->is_c_head1 and $node->get_text =~ /^\s*NAME\s*$/) {
346 $next_is_summary = 1;
347 }
348 # OK, description nodes will proceeed (until another head command)
349 if ($node->is_c_head1 and $node->get_text =~ /DESCRIPTION/) {
350 $we_are_in_description = 1;
351 $nodes_since_description_start = 1;
352 }
353 if ($node->is_c_head1 and $node->get_text =~ /LICENSE|COPYRIGHT/) {
354 $we_are_in_license = 1;
355 }
356 return;
357 }
358}
359
6f720ca8 360sub test_find_summ_descr {
361 my $info = shift;
362 return $info->{_tests}->{find_summ_descr}
363 if defined $info->{_tests}->{find_summ_descr};
d0f6eca7 364 return $info->{_tests}->{find_summ_descr} = 0
365 unless test_find_pod_file($info);
366
367 # my $parser = new Pod::Select;
368 # $parser->parse_from_file($info->{pod_file});
369 for my $sec ({ h => 'summary', s => 'NAME' },
370 { h => 'descr', s => 'DESCRIPTION' })
371 {
372 my $H = new IO::String \$info->{ $sec->{h} };
373 podselect({ -output => $H, -sections => [$sec->{s}] },
374 $info->{pod_file});
375 $H->close;
376 $info->{ $sec->{h} } =~ s/^\s*=head.*//;
377 }
6f720ca8 378
d0f6eca7 379=pod
857f480b 380 my $tree = new Pod::Tree;
381 $tree->load_file($info->{pod_file});
857f480b 382 unless ($tree->has_pod) {
383 warn " ,, no POD in $info->{pod_file}\n";
384 return $info->{_tests}->{find_summ_descr} = 0;
385 }
386
387 my $root = $tree->get_root;
388 $info->{$_} = '' for qw/summary descr/;
389
390 my $state;
391 for my $n (@{ $root->get_children }) {
392 if ($n->is_c_head1) {
393 undef $state;
394 $state = 'summary'
395 if $n->get_text =~ /^\s*NAME\b/ && !$info->{summary};
396 $state = 'descr'
397 if $n->get_text =~ /^\s*DESCRIPTION\b/ && !$info->{descr};
398 next;
399 }
400 $info->{$state} .= $n->get_text if $state;
401 }
d0f6eca7 402=cut
403
857f480b 404 $info->{summary} =~ y/\r\n\t / /s;
405 $info->{$_} =~ s/^\s+|\s+$//g for qw/summary descr/;
857f480b 406
407 warn " ,, no summary in $info->{pod_file}\n" unless $info->{summary};
408 warn " ,, no description in $info->{pod_file}\n" unless $info->{descr};
409
410=pod
7ad57c63 411 my $file < io($info->{pod_file});
412 $file =~ y/\r//d;
6f720ca8 413 if ($file =~ /(?:^|\n)=head\d\s+NAME[\t ]*\n\s*(.+)\n+(?:=|$)/) {
414 $info->{summary} = $1;
415 $info->{summary} =~ s/\s+$//g;
416 }
417 else {
418 warn " ,, no summary: $_\n";
419 $info->{summary} = '';
420 }
421 if ($file =~ /\n=head\d DESCRIPTION\s*\n\s*((?:(?<!=head).+\n){1,15})/) {
422 $info->{descr} = $1;
6f720ca8 423 my $tmp;
7ad57c63 424 run ['fmt'], \$info->{descr}, \$tmp;
6f720ca8 425 $info->{descr} = $tmp if length $tmp;
426 $info->{descr} =~ s/\s+$//g;
427 }
428 else {
429 warn " ,, no description: $_\n";
430 $info->{descr} = '';
431 }
857f480b 432=cut
6f720ca8 433
434 $info->{_tests}->{find_summ_descr} =
435 ($info->{summary} || $info->{descr}) ? 1 : 0;
436}
437
438sub test_build_style {
439 my $info = shift;
440 return $info->{_tests}->{build_style}
441 if defined $info->{_tests}->{build_style};
442 $info->{uses_makemaker} = -e 'Makefile.PL';
443 $info->{uses_module_build} = -e 'Build.PL';
444 $info->{uses_makemaker} = 0
445 if $opts{modulebuild} && $info->{uses_module_build};
446 $info->{uses_module_build} = 0
447 if $opts{makemaker} && $info->{uses_makemaker};
448 $info->{_tests}->{build_style} =
449 ($info->{uses_module_build} || $info->{uses_makemaker}) ? 1 : 0;
450}
451
452sub gen_tarname_unexp {
453 my $info = shift;
454 return
455 unless exists $info->{tarname} && test_directory($info->{dir}, $info);
456 (my $tmp = $info->{tarname}) =~ s#.*/##;
457 $info->{tarname_unexp} = unexpand_macros($info, $tmp);
458}
459
460sub unexpand_macros {
581ece85 461 my $info = shift;
6f720ca8 462 my $value = shift;
463 $value =~ s/\Q$info->{pdir}\E/%{pdir}/;
464 $value =~ s/\Q$info->{pnam}\E/%{pnam}/ if $info->{pnam};
465 $value =~ s/\Q$info->{version}\E/%{version}/;
466 $value;
467}
468
469sub test_is_xs {
470 my $info = shift;
471 return $info->{_tests}->{is_xs}
472 if defined $info->{_tests}->{is_xs};
473
474 # Ugly bitch.
0a7642e7 475 $info->{_tests}->{is_xs} = ( <*.c> || <*.xs> || <*/*.c> || <*/*.xs> || <*/*/*.c> || <*/*/*.xs> ) ? 1 : 0;
6f720ca8 476}
477
581ece85 478sub run_configure {
7ad57c63 479 my $info = shift;
581ece85 480 test_build_style($info);
481 return $info->{_tests}->{run_configure}
482 if defined $info->{_tests}->{run_configure};
483
484 $info->{tmp_destdir} = getcwd() . "/pldcpan_destdir_$$";
485 system(qw(rm -rf), $info->{tmp_destdir}) if -e $info->{tmp_destdir};
486 my @cmd;
487 if ($info->{_tests}->{build_style}) {
488 @cmd =
489 $info->{uses_makemaker}
490 ? qw(perl Makefile.PL INSTALLDIRS=vendor)
491 : (
492 qw(perl Build.PL installdirs=vendor config="optimize='%{rpmcflags}'"),
493 qw(destdir='$info->{tmp_destdir}')
494 );
495 }
496 else {
497 @cmd = (
498 qw(perl -MExtUtils::MakeMaker -wle),
499 qq#WriteMakefile(NAME=>"$info->{parts_joined}")#,
500 qw(INSTALLDIRS=>vendor)
501 );
502 }
503 $info->{_tests}->{run_configure} = run \@cmd, \undef, \my $out, \my $err,
504 timeout(20);
7ad57c63 505}
506
581ece85 507sub run_build {
7ad57c63 508 my $info = shift;
581ece85 509 return $info->{_tests}->{run_build} if defined $info->{_tests}->{run_build};
510 return $info->{_tests}->{run_build} = 0 unless run_configure($info);
511
512 my @cmd;
513 if ($info->{_tests}->{build_style}) {
514 @cmd =
515 $info->{uses_makemaker}
516 ? qw(make)
517 : qw(perl ./Build);
518 }
519 else {
520 @cmd = qw(make);
521 }
522 $info->{_tests}->{run_build} = run \@cmd, \undef, \my $out, \my $err,
523 timeout(60);
7ad57c63 524}
525
581ece85 526sub run_test {
7ad57c63 527 my $info = shift;
581ece85 528 return $info->{_tests}->{run_test} if defined $info->{_tests}->{run_test};
529 return $info->{_tests}->{run_test} = 0 unless run_build($info);
530
531 my @cmd;
532 if ($info->{_tests}->{build_style}) {
533 @cmd =
534 $info->{uses_makemaker}
535 ? qw(make test)
536 : qw(perl ./Build test);
537 }
538 else {
539 @cmd = qw(make test);
540 }
541 $info->{_tests}->{run_test} = run \@cmd, \undef, \my $out, \my $err,
542 timeout(360);
543}
544
545sub run_install {
546 my $info = shift;
547 return $info->{_tests}->{run_install}
548 if defined $info->{_tests}->{run_install};
549 return $info->{_tests}->{run_install} = 0 unless run_build($info);
550
551 my @cmd;
552 if ($info->{_tests}->{build_style}) {
553 @cmd =
554 $info->{uses_makemaker}
555 ? (qw(make install), "DESTDIR='$info->{tmp_destdir}'")
556 : qw(perl ./Build install);
557 }
558 else {
d0f6eca7 559 @cmd = (qw(make install), "DESTDIR='$info->{tmp_destdir}'");
581ece85 560 }
d0f6eca7 561 die "nfy";
7ad57c63 562}
563
581ece85 564sub find_files {
7ad57c63 565 my $info = shift;
581ece85 566 return $info->{_tests}->{find_files}
567 if defined $info->{_tests}->{find_files};
568 return $info->{_tests}->{find_files} = 0 unless run_install($info);
d0f6eca7 569 die "nfy";
7ad57c63 570}
571
0a7642e7 572sub build_reqs_list {
573 my $info = shift;
574 my $rr = $info->{META_yml}->{requires};
575 my $br = $info->{META_yml}->{build_requires};
576 my %RR = map format_r_or_br( $_, $rr->{$_} ), keys %$rr;
577 my %BR = map format_r_or_br( $_, $br->{$_} ), keys %$br;
578 $info->{requires} = \%RR;
579 $info->{build_requires} = \%BR;
580}
581
582sub format_r_or_br {
583 my ( $package, $version ) = @_;
584 my $rpmreq = "perl($package)";
585 ( my $possible = "perl-$package" ) =~ s/::/-/g;
586 if ( run( [ 'rpm', '-q', $possible ], \my ( undef, $out, $err ) )
587 or run( [ 'rpm', '-q', '--whatprovides', $possible ], \my ( undef, $out2, $err2 ) ) )
588 {
589 return $possible => $version; # we have this package or it is provided by something else
590 }
591 elsif ( run( [ 'rpm', '-q', '--qf', '%{NAME}\n', '--whatprovides', $rpmreq ], \my ( undef, $out3, $err3 ) ) ) {
592 my @providers = grep !/^perl-(?:base|modules|devel)$/, split /\s+/, $out3; # might be more than one
593 return unless @providers; # core, ignore
594 return $providers[0] => $version if @providers == 1;
595 }
596 return $rpmreq => $version; # fallback
597}
598
6f720ca8 599for my $arg (@ARGV) {
600 my $info = { _tests => {} };
601
dbdc4dab 602 if (-e $arg) {
603 ## local file; otherwise... hackish trash code :-]
604 ## TODO: %pdir / %pnam in %URL
605 }
606 elsif (my ($tarname) =
607 $arg =~ m#^(?:https?|ftp)://[^/]+/(?:[^/]+/)*([^/]+)$#)
608 {
609 $info->{url} = $arg;
610 warn " -- fetching '$tarname'\n";
dbdc4dab 611 my $response = LWP::Simple::mirror($info->{url}, $tarname);
612 if (HTTP::Status::is_error($response)) {
613 warn " !! fetching '$tarname' failed: code $response. omiting.\n";
614 next;
615 }
616 $arg = $tarname;
617 }
157e61cd 618 elsif ($arg =~ /^[a-z\d_]+(?:(?:::|-)[a-z\d_]+)*$/i) {
dbdc4dab 619 (my $dist = $arg) =~ s/::/-/g;
620 warn " -- searching for '$dist' on search.cpan.org\n";
621 my $scpan = LWP::Simple::get("http://search.cpan.org/dist/$dist/");
622 if ( !defined $scpan
623 || $scpan =~ /cannot be found, did you mean one of these/
624 || $scpan !~ m#<a href="/CPAN/authors/id/([^"]+/([^/"]+))">Download</a>#)
625 {
626 warn " !! searching for '$dist' on search.cpan.org failed\n";
627 next;
628 }
629 $info->{url} = "http://www.cpan.org/modules/by-authors/id/$1";
630 my ($tarname) = $2;
631 warn " .. found $info->{url}\n";
632 my $response = LWP::Simple::mirror($info->{url}, $tarname);
633 if (HTTP::Status::is_error($response)) {
634 warn " !! fetching '$tarname' failed: code $response. omiting.\n";
635 next;
636 }
637 $arg = $tarname;
638 }
639 else {
157e61cd 640 warn " !! omiting '$arg': !-e or bad URL\n";
6f720ca8 641 next;
642 }
643
644 if (-d $arg) {
645 $info->{dir} = $arg =~ m#^/# ? $arg : getcwd() . "/$arg";
646 test_directory($arg, $info);
647 }
648 else {
649 open my $fh, $arg or die "can't open <$arg>: $!";
650 $info->{source0md5} = Digest::MD5->new->addfile($fh)->hexdigest;
651 close $fh or die "close <$arg>: $!";
652
653 $info->{tarname} = $arg;
654 my $arch = Archive::Any->new($arg);
655 unless ($arch) {
656 warn " -- unpacking failed, omiting $arg";
657 next;
658 }
659 if ($arch->is_naughty) {
660 warn " !! Archive::Any says, that $arg is_naughty. omiting.\n";
661 next;
662 }
663 test_archive_name($arg, $info);
664 if ($info->{is_impolite} = $arch->is_impolite) {
665 if (!$info->{_tests}->{archive_name}) {
666 warn
667 "test_archive_name failed and $arg is_impolite; giving up\n";
668 next;
669 }
670 $info->{dir} = getcwd() . "/$info->{ballname}-$info->{version}";
671 mkdir $info->{dir} or die "can't mkdir <$info->{dir}>, $arg!";
672 $arch->extract($info->{dir}) or die "Ni! $arg\n";
673 }
674 else {
675 ($arch->files)[0] =~ m#^(?:\.?/)?([^/]+)(?:/|$)#
676 or die "can't resolve dir from content of $arg";
677 $info->{dir} = getcwd() . "/$1";
678 $arch->extract or die "Nii! $arg\n";
679 }
680 }
681
682 test_find_pod_file($info);
683
684 my $basedir = getcwd;
685
686 $info->{dir} =~ s#/*$##;
687 die " !! not a directory: $info->{dir}" unless -d $info->{dir};
688 warn " .. processing $info->{dir}\n";
689 chdir $info->{dir};
690
98a3ea33 691# test_find_summ_descr($info);
692 test_find_summ_descr2($info);
6f720ca8 693 test_license($info);
694 test_is_xs($info);
695 test_has_tests($info);
696 test_has_examples($info);
697 test_has_doc_files($info);
698 test_build_style($info);
699 gen_tarname_unexp($info);
0a7642e7 700 build_reqs_list($info);
6f720ca8 701
702 $info->{dir} =~ s#.*/##;
703 $info->{dir_unexp} = unexpand_macros($info, $info->{dir});
704
0a7642e7 705 # try to fixup the URL
706 if ($info->{url} && $info->{url} =~ m,/by-authors/id/, && $info->{pdir}) {
707 my $base_url = "http://www.cpan.org/modules/by-module/$info->{pdir}/";
708 if (LWP::Simple::head($base_url . $info->{tarname})) {
709 $info->{url} = $base_url . unexpand_macros($info, $info->{tarname});
710 }
711 }
712
6f720ca8 713 chdir $basedir;
714
715 # hack for TT
716 $info = {
717 %$info,
718 map { ; "test_$_" => $info->{_tests}->{$_} }
719 keys %{ $info->{_tests} }
720 };
721
857f480b 722 pp($info) if $opts{verbose};
6f720ca8 723
157e61cd 724 die " !! I find the idea of overwriting perl.spec disgusting."
725 unless @{ $info->{parts} };
6f720ca8 726 my $spec = join('-', "$basedir/perl", @{ $info->{parts} }) . '.spec';
157e61cd 727 warn " .. writing to '$spec'" . (-e $spec ? " ... which exists...\n" : "\n");
728 die " !! I'm not to overwriting '$spec' without --force\n"
729 if -e $spec && !$opts{force};
6f720ca8 730
857f480b 731 my $rotfl = tell DATA;
581ece85 732 my $tmpl =
6f720ca8 733 Template->new(
734 { INTERPOLATE => 0, POST_CHOMP => 0, EVAL_PERL => 1, ABSOLUTE => 1 });
735 $tmpl->process(\*DATA, $info, $spec)
736 || warn "error parsing $info->{dir}: "
737 . $tmpl->error->type . "\n"
738 . $tmpl->error->info . "\n"
739 . $tmpl->error . "\n";
857f480b 740 seek DATA, $rotfl, 0;
6f720ca8 741}
742
6f720ca8 743# vim: ts=4 sw=4 noet noai nosi cin
744__DATA__
ae077681 745# $[% 'Revision:$, $Date'%]:$
6f720ca8 746#
747# Conditional build:
2c280bf9 748%bcond_without autodeps # don't BR packages needed only for resolving deps
dc543d6a 749%bcond_without tests # do not perform "make test"
6f720ca8 750#
751%include /usr/lib/rpm/macros.perl
752%define pdir [% pdir %]
753[% IF pnam -%]
754%define pnam [% pnam %]
755[% END -%]
397c2cff 756Summary: [% summary.replace('[\r\n]+', ' ') %]
abc368d6 757#Summary(pl.UTF-8):
6f720ca8 758Name: perl-[% pdir %][% IF pnam %]-[% pnam %][% END %]
759Version: [% version %]
07eda004 760Release: 1
6f720ca8 761[% IF test_license && license == 'perl' -%]
762# same as perl
763License: GPL v1+ or Artistic
764[% ELSIF test_license -%]
765License: [% license %]
766[% ELSE -%]
767# same as perl (REMOVE THIS LINE IF NOT TRUE)
768#License: GPL v1+ or Artistic
769[% END -%]
770Group: Development/Languages/Perl
dbdc4dab 771[% IF url -%]
772Source0: [% url %]
773[% ELSIF tarname -%]
e523e325 774Source0: http://www.cpan.org/modules/by-module/[% pdir %]/[% tarname_unexp %]
6f720ca8 775[% ELSIF pnam -%]
e523e325 776Source0: http://www.cpan.org/modules/by-module/[% pdir %]/%{pdir}-%{pnam}-%{version}.tar.gz
6f720ca8 777[% ELSE -%]
e523e325 778Source0: http://www.cpan.org/modules/by-module/[% pdir %]/%{pdir}-%{version}.tar.gz
6f720ca8 779[% END -%]
857f480b 780[% IF source0md5 -%]
781# Source0-md5: [% source0md5 %]
782[% END -%]
e523e325
JB
783# generic URL, check or change before uncommenting
784[% IF pnam -%]
e523e325 785#URL: http://search.cpan.org/dist/[% pdir %]-[% pnam %]/
41aff60a
JB
786[% ELSE -%]
787#URL: http://search.cpan.org/dist/[% pdir %]/
e523e325 788[% END -%]
028d6bb6 789BuildRequires: perl-devel >= 1:5.8.0
6f720ca8 790BuildRequires: rpm-perlprov >= 4.1-13
791[% IF test_has_tests -%]
2c280bf9 792%if %{with autodeps} || %{with tests}
0a7642e7 793[% FOREACH req IN requires.keys.sort -%]
794BuildRequires: [% req %][% ' >= ' _ requires.$req IF requires.$req %]
75f5735b 795[% END -%]
0a7642e7 796[% FOREACH req IN build_requires.keys.sort -%]
797[% NEXT IF requires.exists(req) -%]
798BuildRequires: [% req %][% ' >= ' _ build_requires.$req IF build_requires.$req %]
6f720ca8 799[% END -%]
800%endif
801[% END -%]
802[% IF !test_is_xs -%]
803BuildArch: noarch
804[% END -%]
805BuildRoot: %{tmpdir}/%{name}-%{version}-root-%(id -u -n)
806
807%description
808[% descr %]
809
abc368d6 810# %description -l pl.UTF-8
6f720ca8 811# TODO
812
813%prep
814%setup -q -n [% dir_unexp %][% IF is_impolite %]-c[% END %]
815
816%build
fe997d58 817[%- IF uses_module_build %]
6f720ca8 818%{__perl} Build.PL \
fe997d58 819[%- IF test_is_xs %]
820 config="optimize='%{rpmcflags}'" \
821[%- END %]
6f720ca8 822 destdir=$RPM_BUILD_ROOT \
823 installdirs=vendor
824./Build
825
826%{?with_tests:./Build test}
fe997d58 827[%- ELSIF uses_makemaker %]
e208a9ad 828%{__perl} Makefile.PL \
829 INSTALLDIRS=vendor
830%{__make}[% IF test_is_xs -%] \
831 OPTIMIZE="%{rpmcflags}"[% END %]
832
833%{?with_tests:%{__make} test}
fe997d58 834[%- ELSE %]
e1a9df87 835%{__perl} -MExtUtils::MakeMaker -wle 'WriteMakefile(NAME=>"[% parts_joined %]")' \
836 INSTALLDIRS=vendor
6f720ca8 837%{__make}[% IF test_is_xs -%] \
838 OPTIMIZE="%{rpmcflags}"[% END %]
839
840%{?with_tests:%{__make} test}
fe997d58 841[%- END %]
6f720ca8 842
843%install
844rm -rf $RPM_BUILD_ROOT
845
e208a9ad 846[% IF uses_module_build || !uses_makemaker -%]
847./Build install
848[% ELSE -%]
2c280bf9 849%{__make} pure_install \
6f720ca8 850 DESTDIR=$RPM_BUILD_ROOT
6f720ca8 851[% END -%]
852[% IF test_has_examples -%]
853
854install -d $RPM_BUILD_ROOT%{_examplesdir}/%{name}-%{version}
855[% FOREACH eg = examples -%]
856cp -a [% eg %] $RPM_BUILD_ROOT%{_examplesdir}/%{name}-%{version}
857[% END -%]
858[% END -%]
859
860%clean
861rm -rf $RPM_BUILD_ROOT
862
863%files
864%defattr(644,root,root,755)
865[% IF test_has_doc_files -%]
866%doc[% FOREACH doc = doc_files %] [% doc %][% END %]
867[% END -%]
868[% IF test_is_xs -%]
c94a8aeb 869%{perl_vendorarch}/[% pdir %]/*.pm
870%dir %{perl_vendorarch}/auto/[% pdir %]/[% pnam %]
871%{perl_vendorarch}/auto/[% pdir %]/[% pnam %]/*.bs
872%attr(755,root,root) %{perl_vendorarch}/auto/[% pdir %]/[% pnam %]/*.so
6f720ca8 873[% ELSE -%]
038260e3 874[%- number = parts.size - 1 -%]
875%{perl_vendorlib}/[% parts.first(number).join('/') %]/*.pm
876%{perl_vendorlib}/[% pdir %]/[% parts.last(number).join('/') %]
6f720ca8 877[% END -%]
878%{_mandir}/man3/*
879[% IF test_has_examples -%]
880%{_examplesdir}/%{name}-%{version}
881[% END -%]
882
dc543d6a 883%define date %(echo `LC_ALL="C" date +"%a %b %d %Y"`)
6f720ca8 884%changelog
885* %{date} PLD Team <feedback@pld-linux.org>
886All persons listed below can be reached at <cvs_login>@pld-linux.org
887
9a16c431 888$[%'Log:'%]$
This page took 0.182195 seconds and 4 git commands to generate.