in reply to Re: Bulk check for successful compilation
in thread Bulk check for successful compilation
I did it. I modified the all_pl_files sub further, to scrape the shebang line and store it into a new hash that I named $Test::Compile::Internal::shebang_of_file -- where the keys are the names of the files being tested, and the values are their shebang lines.
I needed to override another sub also, where the enhancement is applied, namely to replace the perl executable that's running the tester script with the perl executable that's contained on each particular tested script's shebang line, for purposes of assembling the command that Test::Compile::Internal runs on the tested file.
Works great!
In addition to scripts (.pl, .psgi, and .cgi files), Test::Compile::Internal checks Perl modules (.pm files). Of course they have no shebang lines, so I haven't tried to replace the perl executable that is used to test modules. Without a way to map the modules to the particular scripts that use them, one worries that a module that uses one or more OTHER modules might be reported as successfully compiled if those other modules are found in the Perl libraries of the perl executable running the tester script, even though one or more of them is missing from the Perl libraries that actually will be used by the scripts being tested. But pretty much any perl executable should work to find all syntax errors in the modules (which is one reason they wouldn't compile successfully), and the problem of "missing" modules is a problem that would seem to be detected and reported as a compilation failure when Test::Compile::Internal tests the scripts that use them.
#!/opt/perl524 use strict; use warnings; BEGIN { use Test::Compile::Internal; no warnings 'redefine'; *Test::Compile::Internal::all_pl_files = sub { my ( $self, @dirs ) = @_; @dirs = @dirs ? @dirs : _pl_starting_points(); my @pl; for my $file ( $self->_find_files(@dirs) ) { if ( $file =~ /(\.pl|\.psgi|\.cgi)$/i ) { # Files with .pl or .psgi or .cgi extensions are perl +scripts push @pl, $file; my $shebang = $self->_read_shebang($file); if ( $shebang =~ m/perl/ ) { $shebang =~ s/\s+$//; $Test::Compile::Internal::shebang_of_file{$file} = $shebang; } } elsif ( $file =~ /(?:^[^.]+$)/ ) { # Files with no extension, but a perl shebang are perl + scripts my $shebang = $self->_read_shebang($file); if ( $shebang =~ m/perl/ ) { push @pl, $file; $shebang =~ s/\s+$//; $Test::Compile::Internal::shebang_of_file{$file} = + $shebang; } } } return @pl; }; *Test::Compile::Internal::_perl_file_compiles = sub { my ( $self, $file ) = @_; if ( !-f $file ) { $self->{test}->diag("$file could not be found") if $self->verbose(); return 0; } my @inc = ( 'blib/lib', @INC ); my $taint = $self->_is_in_taint_mode($file); my $command; if ( $Test::Compile::Internal::shebang_of_file{$file} ) { ( my $executable_filename = $Test::Compile::Internal::shebang_of_file{$file} + ) =~ s/#!//; $command = join( " ", ( $executable_filename, "-c$taint", +$file ) ); } else { $command = join( " ", ( qq{"$^X"}, ( map {qq{"-I$_"}} @inc ), "-c$taint", $f +ile ) ); } if ( $self->verbose() ) { $self->{test}->diag( "Executing: " . $command ); } my ( $compiles, $output ); eval { ( $compiles, $output ) = $self->_run_command($command); # $output is a reference to an array of one or more lines. 1; } or do { my $array_ref_holding_custom_output = ["Can't run command '$command' for compilation test +on file '$file': $@"]; ( $compiles, $output ) = ( 0, $array_ref_holding_custom_ou +tput ); }; if ( $output && ( !defined( $self->verbose() ) || $self->verbose() != 0 + ) ) { if ( !$compiles || $self->verbose() ) { for my $line (@$output) { $self->{test}->diag($line); } } } return $compiles; }; } ## end BEGIN my $test = Test::Compile::Internal->new(); $test->all_files_ok('/www/cgi-bin'); $test->done_testing();
My BEGIN code needed to override a second subroutine, as shown above, called _perl_file_compiles. Here is the subroutine's code in the Test::Compile::Internal module:
sub _perl_file_compiles { my ($self, $file) = @_; if ( ! -f $file ) { $self->{test}->diag("$file could not be found") if $self->verb +ose(); return 0; } my @inc = ('blib/lib', @INC); my $taint = $self->_is_in_taint_mode($file); my $command = join(" ", (qq{"$^X"}, (map { qq{"-I$_"} } @inc), "-c +$taint", $file)); if ( $self->verbose() ) { $self->{test}->diag("Executing: " . $command); } my ($compiles, $output) = $self->_run_command($command); if ( $output && (!defined($self->verbose()) || $self->verbose() != + 0) ) { if ( !$compiles || $self->verbose() ) { for my $line ( @$output ) { $self->{test}->diag($line); } } } return $compiles; }
|
|---|