From: Dave Rolsky Date: Tue, 12 Jan 2016 19:13:18 +0000 (-0600) Subject: Overwrite if the md5sum in a file is wrong but the content has not changed X-Git-Tag: 0.07046~3 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=dbsrgits%2FDBIx-Class-Schema-Loader.git;a=commitdiff_plain;h=348abad20ec56d659682740433f2f1e9dce8e812 Overwrite if the md5sum in a file is wrong but the content has not changed The code was reading the file, then generating an md5sum for the content and comparing it to the md5sum in the file itself. If these didn't match then it would return the _generated_ MD5 rather than what was actually in the file. It would then compare this generated MD5 to the MD5 for a regen of the same file. If they matched it would not bother writing the file. This works fine if it's the _content_ that has changed, but if the md5sum itself is wrong but the content has not changed, then returning the generated MD5 based on the content we just read is wrong. Instead, we now simply return a non-MD5 string. This will force the file to be written again whether it was the file's content that had changed or just its md5sum. --- diff --git a/Changes b/Changes index e74b15d..fb4c33f 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 923209c..07be607 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 1dd6c98..7d35c9a 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_file($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_file($foopm, qr{md5sum:.+$}, "md5sum:$bad_md5"); + +# and dump again without overwrites +throws_ok { + dump_schema(); +} qr/mismatch/, 'throws error dumping without overwrite_modifications'; -unlike slurp_file $foopm, qr/"somethingelse"/, "Modifications actually overwritten"; +$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,21 @@ 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_file { + my ($file, $match, $replace) = @_; + + open my $in, '<', $file or die "$! reading $file"; + my ($tfh, $temp) = tempfile( UNLINK => 1 ); + while(<$in>) { + s/$match/$replace/; + print $tfh $_; + } + close $tfh; + copy( $temp, $file ); } done_testing();