Updated Module::Build to 0.35_08
[p5sagit/p5-mst-13.2.git] / cpan / Module-Build / t / compat.t
CommitLineData
bb4e9162 1#!/usr/bin/perl -w
2
3use strict;
10b84a45 4use lib 't/lib';
bb4e9162 5use MBTest;
6use File::Spec;
7a827510 7use IO::File;
bb4e9162 8use Config;
9
10# Don't let our own verbosity/test_file get mixed up with our subprocess's
11my @makefile_keys = qw(TEST_VERBOSE HARNESS_VERBOSE TEST_FILES MAKEFLAGS);
12local @ENV{@makefile_keys};
13delete @ENV{@makefile_keys};
14
15my @makefile_types = qw(small passthrough traditional);
738349a8 16my $tests_per_type = 15;
17
18#find_in_path does not understand VMS.
19
20if ( $Config{make} && $^O ne 'VMS' ? find_in_path($Config{make}) : 1 ) {
15cb7b9d 21 plan 'no_plan';
bb4e9162 22} else {
23 plan skip_all => "Don't know how to invoke 'make'";
24}
738349a8 25
26my $is_vms_mms = ($^O eq 'VMS') && ($Config{make} =~ /MM[SK]/i);
27
613f422f 28blib_load('Module::Build');
29blib_load('Module::Build::Version');
bb4e9162 30
31
32#########################
33
7a827510 34my $tmp = MBTest->tmpdir;
bb4e9162 35
7a827510 36# Create test distribution; set requires and build_requires
bb4e9162 37use DistGen;
38my $dist = DistGen->new( dir => $tmp );
39$dist->regen;
40
738349a8 41$dist->chdir_in;
bb4e9162 42
43
44#########################
45
613f422f 46blib_load('Module::Build');
47blib_load('Module::Build::Compat');
bb4e9162 48
49use Carp; $SIG{__WARN__} = \&Carp::cluck;
50
51my @make = $Config{make} eq 'nmake' ? ('nmake', '-nologo') : ($Config{make});
52
738349a8 53my $makefile = 'Makefile';
54
55# VMS MMK/MMS by convention use Descrip.MMS
56if ($is_vms_mms) {
57 $makefile = 'Descrip.MMS';
58}
59
60
bb4e9162 61#########################
62
7a827510 63# Test without requires
bb4e9162 64
7a827510 65test_makefile_types();
66
15cb7b9d 67# Test with requires and PL_files
7a827510 68
69my $distname = $dist->name;
70$dist->change_build_pl({
71 module_name => $distname,
72 license => 'perl',
73 requires => {
74 'perl' => $],
613f422f 75 'File::Spec' => 0.2,
7a827510 76 },
613f422f 77 build_requires => {
78 'Test::More' => 0,
79 'File::Spec' => 0,
7a827510 80 },
15cb7b9d 81 PL_files => { 'foo.PL' => 'foo' },
7a827510 82});
83
15cb7b9d 84$dist->add_file("foo.PL", <<'END');
85open my $fh, ">$ARGV[0]" or die $!;
86print $fh "foo\n";
87END
88
7a827510 89$dist->regen;
90
15cb7b9d 91test_makefile_types(
92 requires => {
93 'perl' => $],
613f422f 94 'File::Spec' => 0.2,
95 },
96 build_requires => {
15cb7b9d 97 'Test::More' => 0,
613f422f 98 'File::Spec' => 0,
15cb7b9d 99 },
100 PL_files => {
101 'foo.PL' => 'foo',
102 },
103);
7a827510 104
105######################
106
107$dist->change_build_pl({
108 module_name => $distname,
109 license => 'perl',
110});
111$dist->regen;
112
113# Create M::B instance but don't pollute STDOUT
114my $mb;
613f422f 115stdout_stderr_of( sub {
7a827510 116 $mb = Module::Build->new_from_context;
117});
118ok $mb, "Module::Build->new_from_context";
bb4e9162 119
bb4e9162 120
121{
122 # Make sure fake_makefile() can run without 'build_class', as it may be
123 # in older-generated Makefile.PLs
124 my $warning = '';
125 local $SIG{__WARN__} = sub { $warning = shift; };
738349a8 126
127 my $maketext = eval { Module::Build::Compat->fake_makefile(makefile => $makefile) };
7a827510 128 is $@, '', "fake_makefile lived";
129 like $maketext, qr/^realclean/m, "found 'realclean' in fake_makefile output";
130 like $warning, qr/build_class/, "saw warning about 'build_class'";
bb4e9162 131}
132
133{
134 # Make sure custom builder subclass is used in the created
135 # Makefile.PL - make sure it fails in the right way here.
136 local @Foo::Builder::ISA = qw(Module::Build);
7a827510 137 my $foo_builder;
613f422f 138 stdout_stderr_of( sub {
7a827510 139 $foo_builder = Foo::Builder->new_from_context;
140 });
bb4e9162 141 foreach my $style ('passthrough', 'small') {
94410036 142 create_makefile_pl($style, $foo_builder);
bb4e9162 143
144 # Should fail with "can't find Foo/Builder.pm"
7a827510 145 my $result;
146 my ($stdout, $stderr ) = stdout_stderr_of (sub {
147 $result = $mb->run_perl_script('Makefile.PL');
148 });
149 ok ! $result, "Makefile.PL failed";
150 like $stderr, qr{Foo/Builder.pm}, "custom builder wasn't found";
bb4e9162 151 }
152
153 # Now make sure it can actually work.
7a827510 154 my $bar_builder;
613f422f 155 stdout_stderr_of( sub {
7a827510 156 $bar_builder = Module::Build->subclass( class => 'Bar::Builder' )->new_from_context;
157 });
bb4e9162 158 foreach my $style ('passthrough', 'small') {
94410036 159 create_makefile_pl($style, $bar_builder);
7a827510 160 my $result;
613f422f 161 stdout_stderr_of( sub {
7a827510 162 $result = $mb->run_perl_script('Makefile.PL');
163 });
164 ok $result, "Makefile.PL ran without error";
bb4e9162 165 }
166}
167
168{
169 # Make sure various Makefile.PL arguments are supported
94410036 170 create_makefile_pl('passthrough', $mb);
bb4e9162 171
738349a8 172 my $libdir = File::Spec->catdir( $tmp, 'libdir' );
7a827510 173 my $result;
613f422f 174 stdout_stderr_of( sub {
7a827510 175 $result = $mb->run_perl_script('Makefile.PL', [],
176 [
177 "LIB=$libdir",
178 'TEST_VERBOSE=1',
179 'INSTALLDIRS=perl',
180 'POLLUTE=1',
181 ]
182 );
183 });
184 ok $result, "passthrough Makefile.PL ran with arguments";
185 ok -e 'Build.PL', "Build.PL generated";
bb4e9162 186
187 my $new_build = Module::Build->resume();
7a827510 188 is $new_build->installdirs, 'core', "installdirs is core";
189 is $new_build->verbose, 1, "tests set for verbose";
190 is $new_build->install_destination('lib'), $libdir, "custom libdir";
191 is $new_build->extra_compiler_flags->[0], '-DPERL_POLLUTE', "PERL_POLLUTE set";
bb4e9162 192
193 # Make sure those switches actually had an effect
194 my ($ran_ok, $output);
613f422f 195 $output = stdout_stderr_of( sub { $ran_ok = $new_build->do_system(@make, 'test') } );
7a827510 196 ok $ran_ok, "make test ran without error";
bb4e9162 197 $output =~ s/^/# /gm; # Don't confuse our own test output
198 like $output, qr/(?:# ok \d+\s+)+/, 'Should be verbose';
199
200 # Make sure various Makefile arguments are supported
738349a8 201 my $make_macro = 'TEST_VERBOSE=0';
202
203 # VMS MMK/MMS macros use different syntax.
204 if ($is_vms_mms) {
205 $make_macro = '/macro=("' . $make_macro . '")';
206 }
207
613f422f 208 $output = stdout_stderr_of( sub {
798f208d 209 local $ENV{HARNESS_TIMER}; # RT#39635 - timer messes with output
738349a8 210 $ran_ok = $mb->do_system(@make, 'test', $make_macro)
211 } );
212
7a827510 213 ok $ran_ok, "make test without verbose ran ok";
bb4e9162 214 $output =~ s/^/# /gm; # Don't confuse our own test output
ba889e8f 215 like $output,
738349a8 216 qr/# .+basic(\.t)?[.\s#]+ok[.\s#]+All tests successful/,
217 'Should be non-verbose';
bb4e9162 218
738349a8 219 (my $libdir2 = $libdir) =~ s/libdir/lbiidr/;
23837600 220 my $libarch2 = File::Spec->catdir($libdir2, 'arch');
738349a8 221
66e531b6 222 SKIP: {
cdbde1c3 223 my @cases = (
224 {
225 label => "INSTALLDIRS=vendor",
226 args => [ 'INSTALLDIRS=vendor', "INSTALLVENDORLIB=$libdir2", "INSTALLVENDORARCH=$libarch2"],
227 check => qr/\Q$libdir2\E .* Simple\.pm/ix,
228 },
229 {
230 label => "PREFIX=\$libdir2",
231 args => [ "PREFIX=$libdir2"],
232 check => qr/\Q$libdir2\E .* Simple\.pm/ix,
233 },
234 {
235 label => "PREFIX=\$libdir2 LIB=mylib",
236 args => [ "PREFIX=$libdir2", "LIB=mylib" ],
237 check => qr{\Q$libdir2\E[/\\]mylib[/\\]Simple\.pm}ix,
238 },
239 );
240
66e531b6 241 require ExtUtils::Install;
cdbde1c3 242 skip "Needs ExtUtils::Install 1.32 or later", 2 * @cases
66e531b6 243 if ExtUtils::Install->VERSION < 1.32;
244
cdbde1c3 245 for my $c (@cases) {
246 my @make_args = @{$c->{args}};
247 if ($is_vms_mms) { # VMS MMK/MMS macros use different syntax.
248 $make_args[0] = '/macro=("' . join('","',@make_args) . '")';
249 pop @make_args while scalar(@make_args) > 1;
66e531b6 250 }
cdbde1c3 251 ($output) = stdout_stderr_of(
252 sub {
253 $result = $mb->run_perl_script('Makefile.PL', [], \@make_args);
254 $ran_ok = $mb->do_system(@make, 'fakeinstall');
255 }
256 );
257
258 ok $ran_ok, "fakeinstall $c->{label} ran ok";
259 $output =~ s/^/# /gm; # Don't confuse our own test output
260 like $output, $c->{check},
261 "Saw destination directory for $c->{label}";
262 }
66e531b6 263 }
bb4e9162 264
613f422f 265 stdout_stderr_of( sub { $mb->do_system(@make, 'realclean'); } );
738349a8 266 ok ! -e $makefile, "$makefile shouldn't exist";
bb4e9162 267
268 1 while unlink 'Makefile.PL';
7a827510 269 ok ! -e 'Makefile.PL', "Makefile.PL cleaned up";
738349a8 270
271 1 while unlink $libdir, $libdir2;
bb4e9162 272}
273
274{ # Make sure tilde-expansion works
275
276 # C<glob> on MSWin32 uses $ENV{HOME} if defined to do tilde-expansion
277 local $ENV{HOME} = 'C:/' if $^O =~ /MSWin/ && !exists( $ENV{HOME} );
278
94410036 279 create_makefile_pl('passthrough', $mb);
bb4e9162 280
613f422f 281 stdout_stderr_of( sub {
7a827510 282 $mb->run_perl_script('Makefile.PL', [], ['INSTALL_BASE=~/foo']);
283 });
bb4e9162 284 my $b2 = Module::Build->current;
7a827510 285 ok $b2->install_base, "install_base set";
bb4e9162 286 unlike $b2->install_base, qr/^~/, "Tildes should be expanded";
287
613f422f 288 stdout_stderr_of( sub { $mb->do_system(@make, 'realclean'); } );
738349a8 289 ok ! -e $makefile, "$makefile shouldn't exist";
7a827510 290
bb4e9162 291 1 while unlink 'Makefile.PL';
7a827510 292 ok ! -e 'Makefile.PL', "Makefile.PL cleaned up";
bb4e9162 293}
7a827510 294
23837600 295{
296 $dist->add_file('t/deep/foo.t', q{});
297 $dist->regen;
298
299 my $mb;
613f422f 300 stdout_stderr_of( sub {
23837600 301 $mb = Module::Build->new_from_context( recursive_test_files => 1 );
302 });
303
304 create_makefile_pl('traditional', $mb);
305 my $args = extract_writemakefile_args() || {};
23837600 306
613f422f 307 if ( exists $args->{test}->{TESTS} ) {
308 is $args->{test}->{TESTS},
309 join( q{ },
310 File::Spec->catfile(qw(t *.t)),
311 File::Spec->catfile(qw(t deep *.t))
312 ),
313 'Makefile.PL has correct TESTS line for recursive test files';
314 } else {
315 ok( ! exists $args->{TESTS}, 'Not using incorrect recursive tests key' );
316 }
317
318}
738349a8 319
bb4e9162 320#########################################################
321
613f422f 322sub _merge_prereqs {
323 my ($first, $second) = @_;
324 my $new = { %$first };
325 for my $k (keys %$second) {
326 if ( exists $new->{$k} ) {
327 my ($v1,$v2) = ($new->{$k},$second->{$k});
328 $new->{$k} = ($v1 > $v2 ? $v1 : $v2);
329 }
330 else {
331 $new->{$k} = $second->{$k};
332 }
333 }
334 return $new;
335}
336
7a827510 337sub test_makefile_types {
338 my %opts = @_;
339 $opts{requires} ||= {};
613f422f 340 $opts{build_requires} ||= {};
15cb7b9d 341 $opts{PL_files} ||= {};
7a827510 342
343 foreach my $type (@makefile_types) {
344 # Create M::B instance
345 my $mb;
613f422f 346 stdout_stderr_of( sub {
7a827510 347 $mb = Module::Build->new_from_context;
348 });
349 ok $mb, "Module::Build->new_from_context";
350
351 # Create and test Makefile.PL
94410036 352 create_makefile_pl($type, $mb);
353
7a827510 354 test_makefile_pl_requires_perl( $opts{requires}{perl} );
355 test_makefile_creation($mb);
613f422f 356 test_makefile_prereq_pm( _merge_prereqs($opts{requires}, $opts{build_requires}) );
15cb7b9d 357 test_makefile_pl_files( $opts{PL_files} ) if $type eq 'traditional';
7a827510 358
359 my ($output,$success);
360 # Capture output to keep our STDOUT clean
613f422f 361 $output = stdout_stderr_of( sub {
7a827510 362 $success = $mb->do_system(@make);
363 });
364 ok $success, "make ran without error";
365
15cb7b9d 366 for my $file (values %{ $opts{PL_files} }) {
367 ok -e $file, "PL_files generated - $file";
368 }
369
7a827510 370 # Can't let 'test' STDOUT go to our STDOUT, or it'll confuse Test::Harness.
613f422f 371 $output = stdout_stderr_of( sub {
7a827510 372 $success = $mb->do_system(@make, 'test');
373 });
374 ok $success, "make test ran without error";
375 like uc $output, qr{DONE\.|SUCCESS}, "make test output indicated success";
376
613f422f 377 $output = stdout_stderr_of( sub {
7a827510 378 $success = $mb->do_system(@make, 'realclean');
379 });
380 ok $success, "make realclean ran without error";
381
382 # Try again with some Makefile.PL arguments
94410036 383 test_makefile_creation($mb, [], 'INSTALLDIRS=vendor', 'realclean');
7a827510 384
94410036 385 # Try again using distclean
386 test_makefile_creation($mb, [], '', 'distclean');
387
7a827510 388 1 while unlink 'Makefile.PL';
389 ok ! -e 'Makefile.PL', "cleaned up Makefile";
390 }
391}
392
bb4e9162 393sub test_makefile_creation {
394 my ($build, $preargs, $postargs, $cleanup) = @_;
395
7a827510 396 my ($output, $result);
397 # capture output to avoid polluting our test output
613f422f 398 $output = stdout_stderr_of( sub {
7a827510 399 $result = $build->run_perl_script('Makefile.PL', $preargs, $postargs);
400 });
401 my $label = "Makefile.PL ran without error";
402 if ( defined $postargs && length $postargs ) {
403 $label .= " (postargs: $postargs)";
404 }
405 ok $result, $label;
738349a8 406 ok -e $makefile, "$makefile exists";
bb4e9162 407
408 if ($cleanup) {
94410036 409 # default to 'realclean' unless we recognize the clean method
410 $cleanup = 'realclean' unless $cleanup =~ /^(dist|real)clean$/;
411 my ($stdout, $stderr ) = stdout_stderr_of (sub {
412 $build->do_system(@make, $cleanup);
7a827510 413 });
94410036 414 ok ! -e $makefile, "$makefile cleaned up with $cleanup";
7a827510 415 }
416 else {
417 pass '(skipping cleanup)'; # keep test count constant
bb4e9162 418 }
419}
420
7a827510 421sub test_makefile_prereq_pm {
422 my %requires = %{ $_[0] };
423 delete $requires{perl}; # until EU::MM supports this
424 SKIP: {
738349a8 425 skip "$makefile not found", 1 unless -e $makefile;
15cb7b9d 426 my $prereq_pm = find_params_in_makefile()->{PREREQ_PM} || {};
7a827510 427 is_deeply $prereq_pm, \%requires,
738349a8 428 "$makefile has correct PREREQ_PM line";
7a827510 429 }
430}
431
15cb7b9d 432sub test_makefile_pl_files {
433 my $expected = shift;
434
435 SKIP: {
94410036 436 skip 1, 'Makefile.PL not found' unless -e 'Makefile.PL';
437 my $args = extract_writemakefile_args() || {};
438 is_deeply $args->{PL_FILES}, $expected,
439 "Makefile.PL has correct PL_FILES line";
15cb7b9d 440 }
441}
442
7a827510 443sub test_makefile_pl_requires_perl {
444 my $perl_version = shift || q{};
445 SKIP: {
94410036 446 skip 1, 'Makefile.PL not found' unless -e 'Makefile.PL';
7a827510 447 my $file_contents = slurp 'Makefile.PL';
448 my $found_requires = $file_contents =~ m{^require $perl_version;}ms;
449 if (length $perl_version) {
450 ok $found_requires, "Makefile.PL has 'require $perl_version;'"
451 or diag "Makefile.PL:\n$file_contents";
452 }
453 else {
454 ok ! $found_requires, "Makefile.PL does not require a perl version";
455 }
456 }
457}
458
15cb7b9d 459sub find_params_in_makefile {
738349a8 460 my $fh = IO::File->new( $makefile, 'r' )
461 or die "Can't read $makefile: $!";
7a827510 462 local($/) = "\n";
15cb7b9d 463
464 my %params;
7a827510 465 while (<$fh>) {
15cb7b9d 466 # Blank line after params.
467 last if keys %params and !/\S+/;
468
469 next unless m{^\# \s+ ( [A-Z_]+ ) \s+ => \s+ ( .* )$}x;
470
471 my($key, $val) = ($1, $2);
472 # extract keys and values
473 while ( $val =~ m/(?:\s)(\S+)=>(q\[.*?\]|undef),?/g ) {
7a827510 474 my($m,$n) = ($1,$2);
475 if ($n =~ /^q\[(.*?)\]$/) {
476 $n = $1;
477 }
15cb7b9d 478 $params{$key}{$m} = $n;
7a827510 479 }
7a827510 480 }
15cb7b9d 481
482 return \%params;
7a827510 483}
94410036 484
485sub extract_writemakefile_args {
486 SKIP: {
487 skip 1, 'Makefile.PL not found' unless -e 'Makefile.PL';
488 my $file_contents = slurp 'Makefile.PL';
489 my ($args) = $file_contents =~ m{^WriteMakefile\n\((.*)\).*;}ms;
490 ok $args, "Found WriteMakefile arguments"
491 or diag "Makefile.PL:\n$file_contents";
492 my %args = eval $args or diag $args; ## no critic
493 return \%args;
494 }
495}
496
497sub create_makefile_pl {
613f422f 498 my @args = @_;
499 stdout_stderr_of( sub { Module::Build::Compat->create_makefile_pl(@args) } );
94410036 500 my $ok = ok -e 'Makefile.PL', "$_[0] Makefile.PL created";
501
502 # Some really conservative make's, like HP/UX, assume files with the same
503 # timestamp are out of date. Send the Makefile.PL one second into the past
504 # so its older than the Makefile it will generate.
505 # See [rt.cpan.org 45700]
506 my $mtime = (stat("Makefile.PL"))[9];
507 utime $mtime, $mtime - 1, "Makefile.PL";
508
509 return $ok;
510}