diff options
author | Ian Jackson <ijackson@chiark.greenend.org.uk> | 2016-10-09 13:56:57 +0100 |
---|---|---|
committer | Ian Jackson <ijackson@chiark.greenend.org.uk> | 2016-10-10 01:01:11 +0100 |
commit | 31bab49c4f673e84a1dd88ad055a134543af654b (patch) | |
tree | 87b589112d7aca8705f49529d6d088ba0125d881 | |
parent | a3574bc6e8adc0efc79a7112336d1e770ba0bb2e (diff) |
dgit: Before committing to push, check that .dsc and .changes correspond.
Closes:#800060.
Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
-rw-r--r-- | debian/changelog | 2 | ||||
-rwxr-xr-x | dgit | 63 |
2 files changed, 65 insertions, 0 deletions
diff --git a/debian/changelog b/debian/changelog index f59e395..a751449 100644 --- a/debian/changelog +++ b/debian/changelog @@ -42,6 +42,8 @@ dgit (1.5~~) unstable; urgency=medium from dgit about what it was doing. * Make --quilt=gbp the default for dgit gbp-build. * New tag format (for dgit view) archive/debian/VERSION. + * Before committing to push, check that .dsc and .changes correspond. + Closes:#800060. Infrastructure: * Better error handling in dgit-repos-policy-debian. @@ -1448,6 +1448,65 @@ sub dsc_files () { map { $_->{Filename} } dsc_files_info(); } +sub files_compare_inputs (@) { + my $inputs = \@_; + my %record; + my %fchecked; + + my $showinputs = sub { + return join "; ", map { $_->get_option('name') } @$inputs; + }; + + foreach my $in (@$inputs) { + my $expected_files; + my $in_name = $in->get_option('name'); + + printdebug "files_compare_inputs $in_name\n"; + + foreach my $csumi (@files_csum_info_fields) { + my ($fname) = @$csumi; + printdebug "files_compare_inputs $in_name $fname\n"; + + my $field = $in->{$fname}; + next unless defined $field; + + my @files; + foreach (split /\n/, $field) { + next unless m/\S/; + + my ($info, $f) = m/^(\w+ \d+) (?:\S+ \S+ )?(\S+)$/ or + fail "could not parse $in_name $fname line \`$_'"; + + printdebug "files_compare_inputs $in_name $fname $f\n"; + + push @files, $f; + + my $re = \ $record{$f}{$fname}; + if (defined $$re) { + $fchecked{$f}{$in_name} = 1; + $$re eq $info or + fail "hash or size of $f varies in $fname fields". + " (between: ".$showinputs->().")"; + } else { + $$re = $info; + } + } + @files = sort @files; + $expected_files //= \@files; + "@$expected_files" eq "@files" or + fail "file list in $in_name varies between hash fields!"; + } + $expected_files or + fail "$in_name has no files list field(s)"; + } + printdebug "files_compare_inputs ".Dumper(\%fchecked, \%record) + if $debuglevel>=2; + + grep { keys %$_ == @$inputs-1 } values %fchecked + or fail "no file appears in all file lists". + " (looked in: ".$showinputs->().")"; +} + sub is_orig_file_in_dsc ($$) { my ($f, $dsc_files_info) = @_; return 0 if @$dsc_files_info <= 1; @@ -3166,6 +3225,10 @@ END $changesfile = "$buildproductsdir/$changesfile"; } + # Check that changes and .dsc agree enough + $changesfile =~ m{[^/]*$}; + files_compare_inputs($dsc, parsecontrol($changesfile,$&)); + # Checks complete, we're going to try and go ahead: responder_send_file('changes',$changesfile); |