Skip Menu |

Preferred bug tracker

Please visit the preferred bug tracker to report your issue.

This queue is for tickets about the Perl-Critic CPAN distribution.

Report information
The Basics
Id: 15023
Status: resolved
Priority: 0/
Queue: Perl-Critic

People
Owner: thaljef [...] cpan.org
Requestors: chris+rt [...] chrisdolan.net
Cc:
AdminCc:

Bug Information
Severity: Normal
Broken in: 0.12
Fixed in: 0.13



Subject: False positive with ExtUtils munged script files
When MakeMaker or Module::Build encounter script/bin file, they munge it a little when copying it to blib. They insert this standard prefix: #!/usr/bin/perl -w eval 'exec /usr/bin/perl -w -S $0 ${1+"$@"}' if 0; # not running under some shell at the beginning of each file. This block triggers 6 separate criticisms in v0.12. I propose that Perl::Critic ignore that boilerplate code somehow. -- Chris
The ExtUtils docs don't seems to explain this. Can you educate me a little, and tell me what this does and why it does it? I can certainly teach Perl::Critic to overlook this (probably by just removing it from the parse tree).
From: cdolan [...] cpan.org
[THALJEF - Wed Oct 12 03:08:25 2005]: Show quoted text
> The ExtUtils docs don't seems to explain this. Can you educate me a > little, and tell me what this does and why it does it? > > I can certainly teach Perl::Critic to overlook this (probably by just > removing it from the parse tree).
Sure. This functionality is called "fixing the shebang line". It is performed by both Makefile.PL (via fixin()) and Build.PL (via process_script_files()) to tweak command-line programs to work with the local Perl. For example, if my Perl is at /usr/local/bin instead of /usr/bin, the start line becomes "#!/usr/local/bin/perl -w". Additionally, some magic is added in case the program is run like "sh prog.pl". The magic exec line is simultaneously valid shell script and valid perl code. Under Perl, the "if 0" causes the line to be ignored, but under sh or csh, it aborts execution and runs the program under perl instead. This magic code is added to all Makefile.PL "EXE_FILES" and all Build.PL "script_files". It is ALWAYS the first code in the program after the shebang line. -- Chris
From: cdolan [...] cpan.org
Here's some code that munges the source to comment out the offending lines. I've tested this against Module::Build output, but not MakeMaker output (they *should* be identical). -- Chris # Statement inserted into scripts by Module::Build and ExtUtils::MM_Unix my @magicexec = split /\n/, <<'EOF'; eval 'exec /usr/bin/perl -w -S $0 ${1+"$@"}' if 0; # not running under some shell EOF # Add comment marks before each line of the magic statement $source_code =~ s/^ (\#\![^\n\r]+[\r\n]+) # shebang line plus blank lines (\Q$magicexec[0]\E[\r\n]+) # statement line 1 (\Q$magicexec[1]\E[\r\n]+) # statement line 2 /$1\#$2\#$3/xms;
From: cdolan [...] cpan.org
Here's a patch that implements the above regexp within critique(), along with the needed glue. This patch solves the bug for me. -- Chris
diff -Nur Perl-Critic-0.12-orig/lib/Perl/Critic.pm Perl-Critic-0.12-script/lib/Perl/Critic.pm --- Perl-Critic-0.12-orig/lib/Perl/Critic.pm 2005-10-11 03:55:14.000000000 -0500 +++ Perl-Critic-0.12-script/lib/Perl/Critic.pm 2005-10-17 09:25:40.000000000 -0500 @@ -87,6 +87,30 @@ # Here we go! my ( $self, $source_code ) = @_; + # Ignore ExtUtils::MM_Unix boilerplate in script files + if (!ref $source_code && open my $fh, '<', $source_code) + { + my $code = do{local $/; <$fh>}; + close $fh; + + # Statement inserted into scripts by Module::Build and ExtUtils::MM_Unix + my @magicexec = split /\n/, <<'EOF'; +eval 'exec /usr/bin/perl -w -S $0 ${1+"$@"}' + if 0; # not running under some shell +EOF + + # Add comment marks before each line of the magic statement + if ($code =~ + s/^ + (\#\![^\r\n]+[\r\n]+) # shebang line plus blank lines + (\Q$magicexec[0]\E[\r\n]+) # statement line 1 + (\Q$magicexec[1]\E[\r\n]+) # statement line 2 + /$1\#$2\#$3/xms) + { + $source_code = \$code; + } + } + # Parse the code my $doc = PPI::Document->new($source_code) || croak q{Cannot parse code}; $doc->index_locations();