Initial commit. Doesn't work, but I gotta go to work..
t0m [Wed, 15 Jul 2009 09:02:48 +0000 (10:02 +0100)]
Changes [new file with mode: 0644]
MANIFEST.SKIP [new file with mode: 0644]
Makefile.PL [new file with mode: 0644]
README [new file with mode: 0644]
lib/Test/EOL.pm [new file with mode: 0644]
t/00-load.t [new file with mode: 0644]
t/04-pod.t [new file with mode: 0644]
t/05-pod-coverage.t [new file with mode: 0644]
t/11-all.t [new file with mode: 0644]
t/12-fail.t [new file with mode: 0644]

diff --git a/Changes b/Changes
new file mode 100644 (file)
index 0000000..8b96faa
--- /dev/null
+++ b/Changes
@@ -0,0 +1,5 @@
+Revision history for Test-NoTabs
+
+0.1  2009-07-15
+     - Module created and released on an unsuspecting world.
+
diff --git a/MANIFEST.SKIP b/MANIFEST.SKIP
new file mode 100644 (file)
index 0000000..62619f4
--- /dev/null
@@ -0,0 +1,12 @@
+MANIFEST.bak
+MANIFEST.SKIP
+.git
+.gitignore
+Test-NoTabs-*
+Makefile.old
+.shipit
+^Makefile$
+blib
+pm_to_blib
+.*.swp
+
diff --git a/Makefile.PL b/Makefile.PL
new file mode 100644 (file)
index 0000000..e937bd2
--- /dev/null
@@ -0,0 +1,21 @@
+use inc::Module::Install 0.78;
+
+name     'Test-EOL';
+license  'perl';
+author   'Tomas Doran <bobtfish@bobtfish.net>';
+
+all_from 'lib/Test/EOL.pm';
+requires 'Test::More';
+requires 'Test::Builder';
+requires 'File::Spec';
+requires 'FindBin';
+requires 'File::Find';
+
+resources repository => 'git://github.com/bobtfish/perl-test-eol.git';
+
+if ($Module::Install::AUTHOR) {
+    system("pod2text lib/Test/EOL.pm > README") and die;
+}
+
+WriteAll;
+
diff --git a/README b/README
new file mode 100644 (file)
index 0000000..eff543d
--- /dev/null
+++ b/README
@@ -0,0 +1,77 @@
+NAME
+    Test::EOL - Check the correct line endings in your project
+
+SYNOPSIS
+    "Test::EOL" lets you check the presence of tabs in your perl code. It
+    report its results in standard "Test::Simple" fashion:
+
+      use Test::EOL tests => 1;
+      eol_unix_ok( 'lib/Module.pm', 'Module is tab free');
+
+    Module authors can include the following in a t/eol.t and have
+    "Test::EOL" automatically find and check all perl files in a module
+    distribution:
+
+      use Test::EOL;
+      all_perl_files_ok();
+
+    or
+
+      use Test::EOL;
+      all_perl_files_ok( @mydirs );
+
+DESCRIPTION
+    This module scans your project/distribution for any perl files (scripts,
+    modules, etc) for the presence of tabs.
+
+EXPORT
+    A list of functions that can be exported. You can delete this section if
+    you don't export anything, such as for a purely object-oriented module.
+
+FUNCTIONS
+  all_perl_files_ok( [ @directories ] )
+    Applies "eol_unix_ok()" to all perl files found in @directories (and sub
+    directories). If no <@directories> is given, the starting point is one
+    level above the current running script, that should cover all the files
+    of a typical CPAN distribution. A perl file is *.pl or *.pm or *.t or a
+    file starting with "#!...perl"
+
+    If the test plan is defined:
+
+      use Test::EOL tests => 3;
+      all_perl_files_ok();
+
+    the total number of files tested must be specified.
+
+  eol_unix_ok( $file [, $text] )
+    Run a unix EOL check on $file. For a module, the path (lib/My/Module.pm)
+    or the name (My::Module) can be both used.
+
+AUTHOR
+    Tomas Doran (t0m) "<bobtfish@bobtfish.net>"
+
+BUGS
+    Testing for EOL styles other than unix (\n) currently unsupported.
+
+    The source code can be found on github, as listed in " META.yml ",
+    patches are welcome.
+
+    Otherwise please report any bugs or feature requests to "bug-test-eol at
+    rt.cpan.org", or through the web interface at
+    <http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Test-EOL>. I will be
+    notified, and then you'll automatically be notified of progress on your
+    bug as I make changes.
+
+ACKNOWLEDGEMENTS
+    Shamelessly ripped off from Test::NoTabs.
+
+SEE ALSO
+    Test::More, Test::Pod. Test::Distribution, <Test:NoWarnings>,
+    Test::NoTabs, Module::Install::AuthorTests.
+
+COPYRIGHT & LICENSE
+    Copyright 2009 Tomas Doran, some rights reserved.
+
+    This program is free software; you can redistribute it and/or modify it
+    under the same terms as Perl itself.
+
diff --git a/lib/Test/EOL.pm b/lib/Test/EOL.pm
new file mode 100644 (file)
index 0000000..31a3a47
--- /dev/null
@@ -0,0 +1,221 @@
+package Test::EOL;
+
+use strict;
+use warnings;
+
+use Test::Builder;
+use File::Spec;
+use FindBin qw($Bin);
+use File::Find;
+
+use vars qw( $VERSION $PERL $UNTAINT_PATTERN $PERL_PATTERN);
+
+$VERSION = '0.1';
+
+$PERL    = $^X || 'perl';
+$UNTAINT_PATTERN  = qr|^([-+@\w./:\\]+)$|;
+$PERL_PATTERN     = qr/^#!.*perl/;
+
+my %file_find_arg = ($] <= 5.006) ? () : (
+    untaint => 1,
+    untaint_pattern => $UNTAINT_PATTERN,
+    untaint_skip => 1,
+);
+
+my $Test  = Test::Builder->new;
+my $updir = File::Spec->updir();
+
+sub import {
+    my $self   = shift;
+    my $caller = caller;
+    {
+        no strict 'refs';
+        *{$caller.'::eol_unix_ok'} = \&eol_unix_ok;
+        *{$caller.'::all_perl_files_ok'} = \&all_perl_files_ok;
+    }
+    $Test->exported_to($caller);
+    $Test->plan(@_);
+}
+
+sub _all_perl_files {
+    my @all_files = _all_files(@_);
+    return grep { _is_perl_module($_) || _is_perl_script($_) } @all_files;
+}
+
+sub _all_files {
+    my @base_dirs = @_ ? @_ : File::Spec->catdir($Bin, $updir);
+    my @found;
+    my $want_sub = sub {
+        return if ($File::Find::dir =~ m![\\/]?CVS[\\/]|[\\/]?.svn[\\/]|[\\/]?.git[\\/]!); # Filter out cvs or subversion dirs/
+        return if ($File::Find::dir =~ m![\\/]?blib[\\/]libdoc$!); # Filter out pod doc in dist
+        return if ($File::Find::dir =~ m![\\/]?blib[\\/]man\d$!); # Filter out pod doc in dist
+        return if ($File::Find::name =~ m!Build$!i); # Filter out autogenerated Build script
+        return unless (-f $File::Find::name && -r _);
+        push @found, File::Spec->no_upwards( $File::Find::name );
+    };
+    my $find_arg = {
+        %file_find_arg,
+        wanted   => $want_sub,
+        no_chdir => 1,
+    };
+    find( $find_arg, @base_dirs);
+    return @found;
+}
+
+sub eol_unix_ok {
+    my $file = shift;
+    my $test_txt = shift || "No windows line endings in '$file'";
+    $file = _module_to_path($file);
+    open my $fh, $file or do { $Test->ok(0, $test_txt); $Test->diag("Could not open $file: $!"); return; };
+    my $line = 0;
+    while (<$fh>) {
+        $line++;
+        if ( /\r$/ ) {
+          $Test->ok(0, $test_txt . " on line $line");
+          return 0;
+        }
+    }
+    $Test->ok(1, $test_txt);
+    return 1;
+}
+
+sub all_perl_files_ok {
+    my @files = _all_perl_files( @_ );
+    _make_plan();
+    foreach my $file ( @files ) {
+      eol_unix_ok($file);
+    }
+}
+
+sub _is_perl_module {
+    $_[0] =~ /\.pm$/i || $_[0] =~ /::/;
+}
+
+sub _is_perl_script {
+    my $file = shift;
+    return 1 if $file =~ /\.pl$/i;
+    return 1 if $file =~ /\.t$/;
+    open my $fh, $file or return;
+    my $first = <$fh>;
+    return 1 if defined $first && ($first =~ $PERL_PATTERN);
+    return;
+}
+
+sub _module_to_path {
+    my $file = shift;
+    return $file unless ($file =~ /::/);
+    my @parts = split /::/, $file;
+    my $module = File::Spec->catfile(@parts) . '.pm';
+    foreach my $dir (@INC) {
+        my $candidate = File::Spec->catfile($dir, $module);
+        next unless (-e $candidate && -f _ && -r _);
+        return $candidate;
+    }
+    return $file;
+}
+
+sub _make_plan {
+    unless ($Test->has_plan) {
+        $Test->plan( 'no_plan' );
+    }
+    $Test->expected_tests;
+}
+
+sub _untaint {
+    my @untainted = map { ($_ =~ $UNTAINT_PATTERN) } @_;
+    return wantarray ? @untainted : $untainted[0];
+}
+
+1;
+__END__
+
+=head1 NAME
+
+Test::EOL - Check the correct line endings in your project
+
+=head1 SYNOPSIS
+
+C<Test::EOL> lets you check the presence of tabs in your perl code. It
+report its results in standard C<Test::Simple> fashion:
+
+  use Test::EOL tests => 1;
+  eol_unix_ok( 'lib/Module.pm', 'Module is tab free');
+
+Module authors can include the following in a t/eol.t and have C<Test::EOL>
+automatically find and check all perl files in a module distribution:
+
+  use Test::EOL;
+  all_perl_files_ok();
+
+or
+
+  use Test::EOL;
+  all_perl_files_ok( @mydirs );
+
+=head1 DESCRIPTION
+
+This module scans your project/distribution for any perl files (scripts,
+modules, etc) for the presence of tabs.
+
+=head1 EXPORT
+
+A list of functions that can be exported.  You can delete this section
+if you don't export anything, such as for a purely object-oriented module.
+
+=head1 FUNCTIONS
+
+=head2 all_perl_files_ok( [ @directories ] )
+
+Applies C<eol_unix_ok()> to all perl files found in C<@directories> (and sub
+directories). If no <@directories> is given, the starting point is one level
+above the current running script, that should cover all the files of a typical
+CPAN distribution. A perl file is *.pl or *.pm or *.t or a file starting
+with C<#!...perl>
+
+If the test plan is defined:
+
+  use Test::EOL tests => 3;
+  all_perl_files_ok();
+
+the total number of files tested must be specified.
+
+=head2 eol_unix_ok( $file [, $text] )
+
+Run a unix EOL check on C<$file>. For a module, the path (lib/My/Module.pm) or the
+name (My::Module) can be both used.
+
+=head1 AUTHOR
+
+Tomas Doran (t0m) C<< <bobtfish@bobtfish.net> >>
+
+=head1 BUGS
+
+Testing for EOL styles other than unix (\n) currently unsupported.
+
+The source code can be found on github, as listed in C< META.yml >,
+patches are welcome.
+
+Otherwise please report any bugs or feature requests to
+C<bug-test-eol at rt.cpan.org>, or through the web interface at
+L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Test-EOL>.
+I will be notified, and then you'll automatically be notified of progress on
+your bug as I make changes.
+
+=head1 ACKNOWLEDGEMENTS
+
+Shamelessly ripped off from L<Test::NoTabs>.
+
+=head1 SEE ALSO
+
+L<Test::More>, L<Test::Pod>. L<Test::Distribution>, L<Test:NoWarnings>,
+L<Test::NoTabs>, L<Module::Install::AuthorTests>.
+
+=head1 COPYRIGHT & LICENSE
+
+Copyright 2009 Tomas Doran, some rights reserved.
+
+This program is free software; you can redistribute it and/or modify it
+under the same terms as Perl itself.
+
+=cut
+
diff --git a/t/00-load.t b/t/00-load.t
new file mode 100644 (file)
index 0000000..26b87fc
--- /dev/null
@@ -0,0 +1,9 @@
+#!perl -T
+
+use Test::More tests => 1;
+
+BEGIN {
+    use_ok( 'Test::EOL' );
+}
+
+diag( "Testing Test::EOL $Test::NoTabs::VERSION, Perl $], $^X" );
diff --git a/t/04-pod.t b/t/04-pod.t
new file mode 100644 (file)
index 0000000..e7cae75
--- /dev/null
@@ -0,0 +1,4 @@
+use Test::More;
+eval "use Test::Pod";
+plan skip_all => "Test::Pod required for testing POD" if $@;
+all_pod_files_ok();
diff --git a/t/05-pod-coverage.t b/t/05-pod-coverage.t
new file mode 100644 (file)
index 0000000..a0b0fa9
--- /dev/null
@@ -0,0 +1,4 @@
+use Test::More;
+eval "use Test::Pod::Coverage";
+plan skip_all => "Test::Pod::Coverage required for testing POD coverage" if $@;
+all_pod_coverage_ok();
diff --git a/t/11-all.t b/t/11-all.t
new file mode 100644 (file)
index 0000000..2433d01
--- /dev/null
@@ -0,0 +1,86 @@
+use strict;
+
+use Test::EOL;
+use FindBin qw/$Bin/;
+
+use File::Temp qw( tempdir tempfile );
+
+all_perl_files_ok("$Bin/../lib");
+
+eol_unix_ok( $0, "$0 is unix eol" );
+
+my $file1 = make_file1();
+eol_unix_ok( $file1 );
+
+my $file2 = make_file2();
+eol_unix_ok( $file2 );
+
+my $file3 = make_file3();
+eol_unix_ok( $file3 );
+
+unlink foreach ( $file1, $file2, $file3 );
+
+sub make_file1 {
+  my ($fh, $filename) = tempfile();
+  print $fh <<'DUMMY';
+#!/usr/bin/perl -w
+
+=pod
+
+=head1 NAME
+
+This test script doesn't do anything.
+
+=cut
+
+sub main {
+    my ($name) = @_;
+    print "Hello $name!\n";
+}
+
+DUMMY
+  return $filename;
+}
+
+sub make_file2 {
+  my ($fh, $filename) = tempfile();
+  print $fh <<'DUMMY';
+#!/usr/bin/perl -w
+
+=pod
+
+=head1 NAME
+
+This test script doesn't do anything.
+
+=cut
+
+sub main {
+    my ($name) = @_;
+    print "Hello $name!\n";
+}
+
+DUMMY
+  return $filename;
+}
+
+sub make_file3 {
+  my ($fh, $filename) = tempfile();
+  print $fh <<'DUMMY';
+package My::Test;
+
+use strict;
+use warnings;
+
+sub new {
+    my ($class) = @_;
+    my $self = bless {}, $class;
+    return $self;
+}
+
+1;
+__END__
+DUMMY
+  return $filename;
+}
+
diff --git a/t/12-fail.t b/t/12-fail.t
new file mode 100644 (file)
index 0000000..ae58908
--- /dev/null
@@ -0,0 +1,100 @@
+use strict;
+
+use Test::More qw(no_plan);
+
+use File::Temp qw( tempdir tempfile );
+
+my $perl  = $^X || 'perl';
+my $inc = join(' -I ', @INC) || '';
+$inc = "-I $inc" if $inc;
+
+{
+    my $dir = make_bad_file_1();
+    my (undef, $outfile) = tempfile();
+    ok( `$perl $inc -MTest::EOL -e "all_perl_files_ok( '$dir' )" 2>&1 > $outfile` );
+    local $/ = undef;
+    open my $fh, '<', $outfile or die $!;
+    my $content = <$fh>;
+    like( $content, qr/^not ok 1 - No tabs in '[^']*' on line 4/m, 'windows EOL found in tmp file 1' );
+    #unlink $outfile;
+    #system("rm -rf $dir");
+}
+
+{
+    my $dir = make_bad_file_2();
+    my (undef, $outfile) = tempfile();
+    ok( `$perl $inc -MTest::EOL -e "all_perl_files_ok( '$dir' )" 2>&1 > $outfile` );
+    open my $fh, '<', $outfile or die $!;
+    local $/ = undef;
+    my $content = <$fh>;
+    like( $content, qr/^not ok 1 - No tabs in '[^']*' on line 12/m, 'windows EOL found in tmp file2 ' );
+    unlink $outfile;
+    system("rm -rf $dir");
+}
+
+{
+    my ($dir, $file) = make_bad_file_3();
+    my (undef, $outfile) = tempfile();
+    ok( `$perl $inc -MTest::EOL -e "all_perl_files_ok( '$file' )" 2>&1 > $outfile` );
+    open my $fh, '<', $outfile or die $!;
+    local $/ = undef;
+    my $content = <$fh>;
+    like( $content, qr/^not ok 1 - No tabs in '[^']*' on line 6/m, 'windows EOL found in tmp file 3' );
+    unlink $outfile;
+    system("rm -rf $dir");
+}
+
+sub make_bad_file_1 {
+  my $tmpdir = tempdir();
+  my ($fh, $filename) = tempfile( DIR => $tmpdir, SUFFIX => '.pL' );
+  print $fh <<"DUMMY";
+#!perl
+
+sub main {
+    print "Hello!\r\n";
+}
+DUMMY
+  return $tmpdir;
+}
+
+sub make_bad_file_2 {
+  my $tmpdir = tempdir();
+  my ($fh, $filename) = tempfile( DIR => $tmpdir, SUFFIX => '.pL' );
+  print $fh <<"DUMMY";
+#!perl
+
+=pod
+
+=head1 NAME
+
+test.pL -      A test script
+\r
+=cut
+
+sub main {
+    print "Hello!\n";
+}
+DUMMY
+  return $tmpdir;
+}
+
+sub make_bad_file_3 {
+  my $tmpdir = tempdir();
+  my ($fh, $filename) = tempfile( DIR => $tmpdir, SUFFIX => '.pm' );
+  print $fh <<"DUMMY";
+use strict;\r
+\r
+package My::Test;\r
+\r
+sub new {\r
+    my (\$class) = @_;\r
+    my \$self = bless { }, \$class;\r
+    return \$self;\r
+}\r
+\r
+1;\r
+DUMMY
+  close $fh;
+  return ($tmpdir, $filename);
+}
+