From: Dagfinn Ilmari Mannsåker Date: Sat, 12 Sep 2015 12:45:31 +0000 (+0100) Subject: Add check for wrong number of newlines at the end of the file X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=catagits%2FTest-EOL.git;a=commitdiff_plain;h=131289da01fd94b2ec9ab0da7c1ebfc24fbf8654 Add check for wrong number of newlines at the end of the file --- diff --git a/Changes b/Changes index ee45e86..3e765aa 100644 --- a/Changes +++ b/Changes @@ -4,6 +4,7 @@ Revision history for Test-EOL - Update documentation for starting point change in version 1.5 - Check *.pod files as well as *.pm, *.pl and *.t (RT#82032) + - Add check for wrong number of newlines at the end of the file. 1.6 2015-07-30 21:51:00-07:00 America/Los_Angeles - Add 'no_test' import option to allow more composability diff --git a/lib/Test/EOL.pm b/lib/Test/EOL.pm index a1d7a70..accd162 100644 --- a/lib/Test/EOL.pm +++ b/lib/Test/EOL.pm @@ -86,9 +86,11 @@ sub _show_whitespace { sub _debug_line { my ( $options, $line ) = @_; - $line->[2] =~ s/\n\z//g; + $line->[2] =~ s/\n\z//g if defined $line->[2]; return "line $line->[1]: $line->[0]" . ( - $options->{show_lines} ? qq{: } . _show_whitespace( $line->[2] ) : q{} + $options->{show_lines} && defined $line->[2] + ? qq{: } . _show_whitespace( $line->[2] ) + : q{} ); } @@ -100,6 +102,7 @@ sub eol_unix_ok { my $options = shift if ref $_[0] eq 'HASH'; $options ||= { trailing_whitespace => 0, + trailing_newline => 0, all_reasons => 0, }; $file = _module_to_path($file); @@ -108,16 +111,33 @@ sub eol_unix_ok { # Windows-- , default is :crlf, which hides \r\n -_- binmode( $fh, ':raw' ); my $line = 0; - my @fails; + my $blank_lines = 0; + my (@fails, %fails); while (<$fh>) { $line++; - if ( !$options->{trailing_whitespace} && /(\r+)$/ ) { + if ( /(\r+)$/ ) { my $match = $1; - push @fails, [ _show_whitespace( $match ) , $line , $_ ]; + push @fails, [ _show_whitespace($match) , $line , $_ ] + if !$fails{eol}++ or $options->{all_reasons}; } - if ( $options->{trailing_whitespace} && /([ \t]*\r+|[ \t]+)$/ ) { + if ( $options->{trailing_whitespace} && /([ \t]+)\r*$/ ) { my $match = $1; - push @fails, [ _show_whitespace($match), $line , $_ ]; + push @fails, [ _show_whitespace($match), $line , $_ ] + if !$fails{tws}++ or $options->{all_reasons}; + } + if ( /\A\s*\z/ ) { + $blank_lines++; + } + else { + $blank_lines = 0; + } + if ( $options->{trailing_newline} && eof ) { + push @fails, [ sprintf('%d blank line%s at end of file', + $blank_lines, $blank_lines > 1 ? 's' : ''), + $line, undef ] + if $blank_lines; + push @fails, [ 'Missing "\n" at end of file', $line, undef ] + unless /\n\z/; } # Minor short-circuit for people who don't need the whole file scanned # once there's an err. @@ -233,6 +253,17 @@ or all_perl_files_ok(); done_testing; +and if authors would like to check that there's a single newline and no +blank lines at the end of each file: + + use Test::EOL; + all_perl_files_ok({ trailing_newline => 1 }); + +or + + use Test::EOL; + all_perl_files_ok({ trailing_newline => 1 }, @mydirs ); + =head1 DESCRIPTION This module scans your project/distribution for any perl files (scripts, @@ -263,6 +294,11 @@ By default Test::EOL only looks for Windows (CR/LF) line-endings. Set this to true to raise errors if any kind of trailing whitespace is present in the file. +=item * trailing_newline + +Set this to true to raise an error if the file doesn't end with exactly +one newline and no blank lines. + =item * all_reasons Normally Test::EOL reports only the first error in every file (given that diff --git a/t/10-use-self.t b/t/10-use-self.t index 3e53f29..2579df2 100644 --- a/t/10-use-self.t +++ b/t/10-use-self.t @@ -2,5 +2,8 @@ use Test::EOL; use Cwd; use File::Spec; -all_perl_files_ok(File::Spec->catdir(cwd(), 'lib'), { trailing_whitespace => 1 }); +all_perl_files_ok(File::Spec->catdir(cwd(), 'lib'), { + trailing_whitespace => 1, + trailing_newline => 1, +}); diff --git a/t/11-all.t b/t/11-all.t index dbb4e0f..80cf2d7 100644 --- a/t/11-all.t +++ b/t/11-all.t @@ -19,7 +19,7 @@ my $file3 = make_file3(); eol_unix_ok( $file3 ); my $file4 = make_file3(); -eol_unix_ok( $file3, { trailing_whitespace => 1 }); +eol_unix_ok( $file3, { trailing_whitespace => 1, trailing_newline => 1 }); unlink foreach ( $file1, $file2, $file3, $file4 ); diff --git a/t/12-fail.t b/t/12-fail.t index 4f27208..f98c476 100644 --- a/t/12-fail.t +++ b/t/12-fail.t @@ -43,6 +43,31 @@ $inc = "-I $inc" if $inc; 'Trailing ws EOL found in tmp file 4' ); } +{ + my $dir = make_bad_file_5(); + run_ok( "all_perl_files_ok({trailing_newline => 1}, '$dir' )", + qr/^not ok 1 - No incorrect line endings in '[^']*' \Qon line 2: Missing "\n" at end of file/m, + 'Missing final newline found in tmp file 5' ); +} + +{ + my $dir = make_bad_file_6(); + run_ok( "all_perl_files_ok({trailing_newline => 1}, '$dir' )", + qr/^not ok 1 - No incorrect line endings in '[^']*' \Qon line 2: 1 blank line at end of file/m, + 'Trailing blank line found in tmp file 6' ); +} + +{ + my $dir = make_bad_file_7(); + run_ok( "all_perl_files_ok({ + trailing_whitespace => 1, + trailing_newline => 1, + all_reasons => 1, + }, '$dir' )", + qr/^not ok 1 - No incorrect line endings in '[^']*'.*^# line 2: \Q[\s]: [\s]\E.*^# line 2: 1 blank line at end of file.*^# line 2: Missing "\\n" at end of file/ms, + 'Trailing blank line found in tmp file 7' ); +} + sub run_ok { my ($code, $match, $test_name) = @_; my (undef, $file, $line) = caller; @@ -159,3 +184,30 @@ print $fh '}'; return $tmpdir; } +sub make_bad_file_5 { + my $tmpdir = tempdir( CLEANUP => 1 ); + my ($fh, $filename) = tempfile( DIR => $tmpdir, SUFFIX => '.pL' ); + binmode $fh, ':raw'; + print $fh "one line here\nno EOL here"; + close $fh; + return $filename; +} + +sub make_bad_file_6 { + my $tmpdir = tempdir( CLEANUP => 1 ); + my ($fh, $filename) = tempfile( DIR => $tmpdir, SUFFIX => '.pL' ); + binmode $fh, ':raw'; + print $fh "blank line following here\n \n"; + close $fh; + return $filename; +} + +sub make_bad_file_7 { + my $tmpdir = tempdir( CLEANUP => 1 ); + my ($fh, $filename) = tempfile( DIR => $tmpdir, SUFFIX => '.pL' ); + binmode $fh, ':raw'; + print $fh "blank trailing line without newline\n "; + close $fh; + return $filename; +} +