prevent mixing non-native and native newlines in manifest files
authorSandy Andy <andk@cpan.org>
Sat, 6 Aug 2011 06:09:22 +0000 (08:09 +0200)
committerFather Chrysostomos <sprout@cpan.org>
Sat, 6 Aug 2011 16:27:28 +0000 (09:27 -0700)
dist/ExtUtils-Manifest/lib/ExtUtils/Manifest.pm
dist/ExtUtils-Manifest/t/Manifest.t

index ce4314c419d73fbac6eaa398f6f18ca398b1128c..62e98779821d0e5559073ef7b2e9afd5def8e5ae 100644 (file)
@@ -13,7 +13,7 @@ use vars qw($VERSION @ISA @EXPORT_OK
           $Is_MacOS $Is_VMS $Is_VMS_mode $Is_VMS_lc $Is_VMS_nodot
           $Debug $Verbose $Quiet $MANIFEST $DEFAULT_MSKIP);
 
-$VERSION = '1.58';
+$VERSION = '1.59';
 @ISA=('Exporter');
 @EXPORT_OK = qw(mkmanifest
                 manicheck  filecheck  fullcheck  skipcheck
@@ -706,21 +706,35 @@ sub maniadd {
 }
 
 
-# Sometimes MANIFESTs are missing a trailing newline.  Fix this.
+# Make sure this MANIFEST is consistently written with native
+# newlines and has a terminal newline.
 sub _fix_manifest {
     my $manifest_file = shift;
 
     open MANIFEST, $MANIFEST or die "Could not open $MANIFEST: $!";
-
-    # Yes, we should be using seek(), but I'd like to avoid loading POSIX
-    # to get SEEK_*
-    my @manifest = <MANIFEST>;
+    local $/;
+    my @manifest = split /(\015\012|\012|\015)/, <MANIFEST>, -1;
     close MANIFEST;
+    my $must_rewrite = "";
+    if ($manifest[-1] eq ""){
+        # sane case: last line had a terminal newline
+        pop @manifest;
+        for (my $i=1; $i<=$#manifest; $i+=2) {
+            unless ($manifest[$i] eq "\n") {
+                $must_rewrite = "not a newline at pos $i";
+                last;
+            }
+        }
+    } else {
+        $must_rewrite = "last line without newline";
+    }
 
-    unless( $manifest[-1] =~ /\n\z/ ) {
-        open MANIFEST, ">>$MANIFEST" or die "Could not open $MANIFEST: $!";
-        print MANIFEST "\n";
-        close MANIFEST;
+    if ( $must_rewrite ) {
+        open MANIFEST, ">", $MANIFEST or die "(must_rewrite=$must_rewrite) Could not open >$MANIFEST: $!";
+        for (my $i=0; $i<=$#manifest; $i+=2) {
+            print MANIFEST "$manifest[$i]\n";
+        }
+        close MANIFEST or die "could not write $MANIFEST: $!";
     }
 }
 
index 91b126b20e2b83e518254444cda9a9d0d94a1a7c..8d2ff8b91e899d800b339e8c023f95b55c567209 100644 (file)
@@ -13,7 +13,7 @@ chdir 't';
 
 use strict;
 
-use Test::More tests => 94;
+use Test::More tests => 96;
 use Cwd;
 
 use File::Spec;
@@ -231,6 +231,48 @@ is( $files->{wibble}, '',    'maniadd() with undef comment' );
 is( $files->{yarrow}, 'hock','          with comment' );
 is( $files->{foobar}, '',    '          preserved old entries' );
 
+{
+    # EOL normalization in maniadd()
+
+    # move manifest away:
+    rename "MANIFEST", "MANIFEST.bak" or die "Could not rename MANIFEST to MANIFEST.bak: $!";
+    my $prev_maniaddresult;
+    my @eol = ("\012","\015","\015\012");
+    # for all line-endings:
+    for my $i (0..$#eol) {
+        my $eol = $eol[$i];
+        #   cp the backup of the manifest to MANIFEST, line-endings adjusted
+        my $content = do { local $/; open my $fh, "MANIFEST.bak" or die; <$fh> };
+    SPLITTER: for my $eol2 (@eol) {
+            if ( index($content, $eol2) > -1 ) {
+                my @lines = split /$eol2/, $content;
+                pop @lines while $lines[-1] eq "";
+                open my $fh, ">", "MANIFEST" or die "Could not open >MANIFEST: $!";
+                print $fh map { "$_$eol" } @lines;
+                close $fh or die "Could not close: $!";
+                last SPLITTER;
+            }
+        }
+        #   try maniadd
+        maniadd({eoltest => "end of line normalization test"});
+        #   slurp result and compare to previous result
+        my $maniaddresult = do { local $/; open my $fh, "MANIFEST" or die; <$fh> };
+        if ($prev_maniaddresult) {
+            if ( $maniaddresult eq $prev_maniaddresult ) {
+                pass "normalization success with i=$i";
+            } else {
+                require Data::Dumper;
+                local $Data::Dumper::Useqq = 1;
+                local $Data::Dumper::Terse = 1;
+                is Data::Dumper::Dumper($maniaddresult), Data::Dumper::Dumper($prev_maniaddresult), "eol normalization failed with i=$i";
+            }
+        }
+        $prev_maniaddresult = $maniaddresult;
+    }
+    # move backup over MANIFEST
+    rename "MANIFEST.bak", "MANIFEST" or die "Could not rename MANIFEST.bak to MANIFEST: $!";
+}
+
 my %funky_files;
 # test including a filename with a space
 SKIP: {