+sub parse_argv {
+# parts the array $_[0] and $_[1] and returns the sub-array (modifies the original one)
+ my @ret = ();
+ my $args = shift;
+ my $separator = shift;
+ while($args->[0] && $args->[0] ne $separator) {
+ push @ret, shift @$args;
+ }
+ shift @$args if @$args;
+ return @ret;
+}
+
+sub parse_all_v3 {
+ my $srcs = shift;
+ my $vars = shift;
+ my $db = get_all_source_info();
+ my $binary = $srcs->{'_binary'};
+
+ SRCS:
+ foreach my $name (keys %$srcs) {
+ next if $name eq '_binary';
+
+ # state = installed, out-of-date, uncompiled, not-for-us, auto-not-for-us
+ my $pkgs = $srcs->{$name};
+ my $pkg = $db->{$name};
+
+ unless ($pkg) {
+ next SRCS if $pkgs->{'status'} eq 'not-for-us';
+ my $logstr = sprintf("merge-v3 %s %s_%s (%s, %s):", $vars->{'time'}, $name, $pkgs->{'version'}, $vars->{'arch'}, $vars->{'suite'});
+
+ # does at least one binary exist in the database and is more recent - if so, we're probably just outdated, ignore the source package
+ for my $bin (@{$pkgs->{'binary'}}) {
+ if ($binary->{$bin} and vercmp($pkgs->{'version'}, $binary->{$bin}->{'version'}) < 0) {
+ print "$logstr skipped because binaries (assumed to be) overwritten\n" if $verbose || $simulate;
+ next SRCS;
+ }
+ }
+ $pkg->{'package'} = $name;
+ }
+ my $logstr = "merge-v3 $vars->{'time'} ".$name."_$pkgs->{'version'}".
+ ($pkgs->{'binnmu'} ? ";b".$pkgs->{'binnmu'} : "").
+ " ($vars->{'arch'}, $vars->{'suite'}, previous: $pkg->{'version'}".
+ ($pkg->{'binary_nmu_version'} ? ";b".$pkg->{'binary_nmu_version'} : "").
+ ", $pkg->{'state'}):";
+
+ if (isin($pkgs->{'status'}, qw (installed related)) && $pkgs->{'version'} eq $pkg->{'version'} && $pkg->{'binary_nmu_version'} && $pkgs->{'binnmu'} < int($pkg->{'binary_nmu_version'})) {
+ $pkgs->{'status'} = 'out-of-date';
+ }
+ if (isin($pkgs->{'status'}, qw (installed related))) {
+ my $change = 0;
+ if ($pkg->{'state'} ne 'Installed') {
+ change_state( \$pkg, 'Installed');
+ delete $pkg->{'depends'};
+ delete $pkg->{'extra_depends'};
+ delete $pkg->{'extra_conflicts'};
+ $change++;
+ }
+ my $attrs = { 'version' => 'version', 'installed_version' => 'version', 'binary_nmu_version' => 'binnmu', 'section' => 'section', 'priority' => 'priority' };
+ foreach my $k (keys %$attrs) {
+ if ($pkg->{$k} ne $pkgs->{$attrs->{$k}}) {
+ $pkg->{$k} = $pkgs->{$attrs->{$k}};
+ $change++;
+ }
+ }
+ if (isin($pkgs->{'status'}, qw (related)) and $pkg->{'notes'} ne "related") {
+ $pkg->{'notes'} = "related";
+ $change++;
+ }
+ if ($change) {
+ print "$logstr set to installed/".$pkg->{'notes'}."\n" if $verbose || $simulate;
+ log_ta( $pkg, "--merge-v3: installed" ) unless $simulate;
+ update_source_info($pkg) unless $simulate;
+ }
+ next;
+ }
+
+ if ($pkgs->{'status'} eq 'not-for-us') {
+ next if isin( $pkg->{'state'}, qw(Not-For-Us Installed Failed-Removed));
+
+ if (isin( $pkg->{'state'}, qw(Failed Build-Attempted Built))) {
+ change_state( \$pkg, "Failed-Removed" );
+ log_ta( $pkg, "--merge-v3: Failed-Removed" ) unless $simulate;
+ update_source_info($pkg) unless $simulate;
+ print "$logstr (virtually) deleted from database\n" if $verbose || $simulate;
+ next;
+ }
+
+ print "$logstr should delete (not-for-us according to P-a-s)\n" if $verbose || $simulate || 1; # not implemented yet on purpose
+ next;
+ }
+
+ if ($pkgs->{'status'} eq 'auto-not-for-us') {
+ next if isin( $pkg->{'state'}, qw(Not-For-Us Failed Failed-Removed Dep-Wait Dep-Wait-Removed Auto-Not-For-Us));
+ # if the package is currently current, the status is Installed, not not-for-us
+
+ change_state( \$pkg, "Auto-Not-For-Us" );
+ log_ta( $pkg, "--merge-v3: Auto-Not-For-Us" ) unless $simulate;
+ update_source_info($pkg) unless $simulate;
+ print "$logstr set to auto-not-for-us\n" if $verbose || $simulate;
+ next SRCS;
+ }
+
+ # only uncompiled / out-of-date are left, so check if anything new
+ if (!(isin($pkgs->{'status'}, qw (uncompiled out-of-date)))) {
+ print "$logstr package in unknown state: $pkgs->{'status'}\n";
+ next SRCS;
+ }
+ next if $pkgs->{'version'} eq $pkg->{'version'} and $pkgs->{'binnmu'} >= int($pkg->{'binary_nmu_version'});
+ next if $pkgs->{'version'} eq $pkg->{'version'} and !isin( $pkg->{'state'}, qw(Installed));
+ next if isin( $pkg->{'state'}, qw(Not-For-Us Failed-Removed));
+
+ if (defined( $pkg->{'state'} ) && isin( $pkg->{'state'}, qw(Building Built Build-Attempted))) {
+ send_mail( $pkg->{'builder'},
+ "new version of $name (dist=$distribution)",
+ "As far as I'm informed, you're currently building the package $name\n".
+ "in version $pkg->{'version'}.\n\n".
+ "Now there's a new source version $pkgs->{'version'}. If you haven't finished\n".
+ "compiling $name yet, you can stop it to save some work.\n".
+ "Just to inform you...\n".
+ "(This is an automated message)\n" ) unless $simulate;
+ print "$logstr new version while building $pkg->{'version'} -- sending mail to builder ($pkg->{'builder'})\n"
+ if $verbose || $simulate;
+ }
+ change_state( \$pkg, 'Needs-Build');
+ $pkg->{'notes'} = $pkgs->{'status'};
+ $pkg->{'version'} = $pkgs->{'version'};
+ $pkg->{'section'} = $pkgs->{'section'};
+ $pkg->{'priority'} = $pkgs->{'priority'};
+ $pkg->{'dep'} = $pkgs->{'depends'};
+ $pkg->{'conf'} = $pkgs->{'conflicts'};
+ delete $pkg->{'builder'};
+ delete $pkg->{'binary_nmu_version'} unless $pkgs->{'binnmu'};
+ delete $pkg->{'binary_nmu_changelog'} unless $pkgs->{'binnmu'};
+ log_ta( $pkg, "--merge-v3: needs-build" ) unless $simulate;
+ update_source_info($pkg) unless $simulate;
+ print "$logstr set to needs-builds\n" if $simulate || $verbose;
+ }
+
+ foreach my $name (keys %$db) {
+ next if $srcs->{$name};
+ my $pkg = $db->{$name};
+ my $logstr = "merge-v3 $vars->{'time'} ".$name."_$pkg->{'version'} ($vars->{'arch'}, $vars->{'suite'}, previous: $pkg->{'state'}):";
+ # package disappeared - delete
+ change_state( \$pkg, 'deleted' );
+ log_ta( $pkg, "--merge-v3: deleted" ) unless $simulate;
+ print "$logstr deleted from database\n" if $verbose || $simulate;
+ del_source_info($name) unless $simulate;
+ delete $db->{$name};
+ }
+}