diff --git a/Changes b/Changes index e74b15dea..fb4c33fe1 100644 --- a/Changes +++ b/Changes @@ -2,6 +2,9 @@ Revision history for Perl extension DBIx::Class::Schema::Loader - Introspect view definitions for PostgreSQL, MySQL, Oracle, Firebird, and InterBase. + - When a file's md5sum was wrong but no other content in the file had + changed, it would not be rewritten even when overwrite_modifications + was true. Fixed by Dave Rolsky. GH #8. 0.07045 2016-01-22 - Regenerate tarball without author-mode test dependencies diff --git a/lib/DBIx/Class/Schema/Loader/Base.pm b/lib/DBIx/Class/Schema/Loader/Base.pm index 923209cc4..07be607a0 100644 --- a/lib/DBIx/Class/Schema/Loader/Base.pm +++ b/lib/DBIx/Class/Schema/Loader/Base.pm @@ -2252,9 +2252,16 @@ sub _parse_generated_file { $gen .= $pre_md5; $real_md5 = Digest::MD5::md5_base64(encode 'UTF-8', $gen); - croak "Checksum mismatch in '$fn', the auto-generated part of the file has been modified outside of this loader. Aborting.\nIf you want to overwrite these modifications, set the 'overwrite_modifications' loader option.\n" - if !$self->overwrite_modifications && $real_md5 ne $mark_md5; - + if ($real_md5 ne $mark_md5) { + if ($self->overwrite_modifications) { + # Setting this to something that is not a valid MD5 forces + # the file to be rewritten. + $real_md5 = 'not an MD5'; + } + else { + croak "Checksum mismatch in '$fn', the auto-generated part of the file has been modified outside of this loader. Aborting.\nIf you want to overwrite these modifications, set the 'overwrite_modifications' loader option.\n"; + } + } last; } else { diff --git a/t/40overwrite_modifications.t b/t/40overwrite_modifications.t index 1dd6c9894..aa7b85465 100644 --- a/t/40overwrite_modifications.t +++ b/t/40overwrite_modifications.t @@ -22,16 +22,7 @@ dump_schema(); ok( -f $foopm, 'looks like it dumped' ); # now modify one of the files -{ - open my $in, '<', $foopm or die "$! reading $foopm"; - my ($tfh,$temp) = tempfile( UNLINK => 1); - while(<$in>) { - s/"bars"/"somethingelse"/; - print $tfh $_; - } - close $tfh; - copy( $temp, $foopm ); -} +rewrite_foopm($foopm, qr{"bars"}, q{"somethingelse"}); # and dump again without overwrites throws_ok { @@ -43,8 +34,37 @@ lives_ok { dump_schema( overwrite_modifications => 1 ); } 'does not throw when dumping with overwrite_modifications'; +# Replace the md5 with a bad MD5 in Foo.pm +my $foopm_content = slurp_file($foopm); +my ($md5) = $foopm_content =~/md5sum:(.+)$/m; +# This cannot be just any arbitrary value, it has to actually look like an MD5 +# value or DBICSL doesn't even see it as an MD5 at all (which makes sense). +my $bad_md5 = reverse $md5; +rewrite_foopm($foopm, qr{md5sum:.+$}, "md5sum:$bad_md5"); -unlike slurp_file $foopm, qr/"somethingelse"/, "Modifications actually overwritten"; +# and dump again without overwrites +throws_ok { + dump_schema(); +} qr/mismatch/, 'throws error dumping without overwrite_modifications'; + +$foopm_content = slurp_file($foopm); +like( + $foopm_content, + qr/\Q$bad_md5/, + 'bad MD5 is not rewritten when overwrite_modifications is false' +); + +# and then dump with overwrite +lives_ok { + dump_schema( overwrite_modifications => 1 ); +} 'does not throw when dumping with overwrite_modifications'; + +$foopm_content = slurp_file($foopm); +unlike( + $foopm_content, + qr/\Q$bad_md5/, + 'bad MD5 is rewritten when overwrite_modifications is true' +); sub dump_schema { @@ -60,7 +80,23 @@ sub dump_schema { { dump_directory => $tempdir, @$args }, [ $make_dbictest_db::dsn ], ); - } [qr/^Dumping manual schema/, qr/^Schema dump completed/ ]; + } [qr/^Dumping manual schema/, qr/^Schema dump completed/ ], + 'schema was dumped with expected warnings'; +} + +sub rewrite_foopm { + my $foopm = shift; + my $match = shift; + my $replace = shift; + + open my $in, '<', $foopm or die "$! reading $foopm"; + my ($tfh, $temp) = tempfile( UNLINK => 1); + while(<$in>) { + s/$match/$replace/; + print $tfh $_; + } + close $tfh; + copy( $temp, $foopm ); } done_testing();