]> git.donarmstrong.com Git - debbugs.git/blobdiff - Debbugs/Control.pm
allow specifying the dist in source_to_binary (for DB actions)
[debbugs.git] / Debbugs / Control.pm
index 6f7420679beadd8339de6574877ec0758937d55e..1f8b3aac60d3cb98fe5264795fc7806e795c4bac 100644 (file)
@@ -134,7 +134,7 @@ use Mail::RFC822::Address qw();
 use POSIX qw(strftime);
 
 use Storable qw(dclone nfreeze);
-use List::Util qw(first max);
+use List::AllUtils qw(first max);
 use Encode qw(encode_utf8);
 
 use Carp;
@@ -364,7 +364,7 @@ sub set_blocks {
        next if $ok_blockers{$blocker} or $bad_blockers{$blocker};
        my $data = read_bug(bug=>$blocker,
                           );
-       if (defined $data and not $data->{archive}) {
+       if (defined $data and not $data->{archived}) {
            $data = split_status_fields($data);
            $ok_blockers{$blocker} = 1;
            my @merged_bugs;
@@ -379,15 +379,17 @@ sub set_blocks {
     # throw an error if we are setting the blockers and there is a bad
     # blocker
     if (keys %bad_blockers and $mode eq 'set') {
-       croak "Unknown blocking bug(s):".join(', ',keys %bad_blockers).
-           keys %ok_blockers?'':" and no known blocking bug(s)";
+       __end_control(%info);
+       croak "Unknown/archived blocking bug(s):".join(', ',keys %bad_blockers).
+           keys %ok_blockers?'':" and no good blocking bug(s)";
     }
     # if there are no ok blockers and we are not setting the blockers,
     # there's an error.
     if (not keys %ok_blockers and $mode ne 'set') {
        print {$transcript} "No valid blocking bug(s) given; not doing anything\n";
        if (keys %bad_blockers) {
-           croak "Unknown blocking bug(s):".join(', ',keys %bad_blockers);
+           __end_control(%info);
+           croak "Unknown/archived blocking bug(s):".join(', ',keys %bad_blockers);
        }
        __end_control(%info);
        return;
@@ -410,6 +412,7 @@ sub set_blocks {
     @bugs{@bugs} = (1) x @bugs;
     for my $blocker (@change_blockers) {
        if ($bugs{$blocker}) {
+           __end_control(%info);
            croak "It is nonsensical for a bug to block itself (or a merged partner): $blocker";
        }
     }
@@ -1975,8 +1978,11 @@ sub set_merged {
                $data->{mergedwith} = '';
            }
            else {
-               $data->{mergedwith} = join(' ',sort grep {$_ != $data->{bug_num}}
-                                           keys %merged_bugs);
+               $data->{mergedwith} =
+                   join(' ',
+                        sort {$a <=> $b}
+                        grep {$_ != $data->{bug_num}}
+                        keys %merged_bugs);
            }
            append_action_to_log(bug => $data->{bug_num},
                                 command  => 'merge',
@@ -2067,9 +2073,11 @@ sub set_merged {
                print {$transcript} "$change->{field} of #$change->{bug} is '$change->{text_orig_value}' not '$change->{text_value}'\n";
            }
            if ($attempts > 0) {
+               __end_control(%info);
                croak "Some bugs were altered while attempting to merge";
            }
            else {
+               __end_control(%info);
                croak "Did not alter merged bugs";
            }
        }
@@ -2081,6 +2089,7 @@ sub set_merged {
                $param{show_bug_info} and not __internal_request(1);
            $bug_info_shown{$change_bug} = 1;
            __allow_relocking($param{locks},[keys %data]);
+           eval {
            for my $change (@{$changes->{$change_bug}}) {
                if ($change->{field} eq 'blockedby' or $change->{field} eq 'blocks') {
                    my %target_blockedby;
@@ -2117,6 +2126,12 @@ sub set_merged {
                                         );
                }
            }
+       };
+           if ($@) {
+               __disallow_relocking($param{locks});
+               __end_control(%info);
+               croak "Failure while trying to adjust bugs, please report this as a bug: $@";
+           }
            __disallow_relocking($param{locks});
            my ($data,$n_locks) =
                __lock_and_load_merged_bugs(bugs_to_load => [keys %merging],
@@ -2157,11 +2172,14 @@ sub set_merged {
     }
 
     # finally, we can merge the bugs
-    my $action = "Merged ".join(' ',sort keys %merged_bugs);
+    my $action = "Merged ".join(' ',sort { $a <=> $b } keys %merged_bugs);
     for my $data (@data) {
        my $old_data = dclone($data);
-       $data->{mergedwith} = join(' ',sort grep {$_ != $data->{bug_num}}
-                                   keys %merged_bugs);
+       $data->{mergedwith} =
+           join(' ',
+                sort { $a <=> $b }
+                grep {$_ != $data->{bug_num}}
+                keys %merged_bugs);
        append_action_to_log(bug => $data->{bug_num},
                             command  => 'merge',
                             new_data => $data,
@@ -2280,13 +2298,22 @@ sub __calculate_merge_status{
            $merged_bugs{$data->{bug_num}} = 1;
            $bugs_to_merge = 1;
        }
+    }
+    for my $data (@{$data_a}) {
        # the master_bug is the bug that every other bug is made to
        # look like. However, if merge is set, tags, fixed and found
        # are merged.
        if ($data->{bug_num} == $master_bug) {
-           for (qw(package forwarded severity blocks blockedby done owner summary outlook affects)) {
+           for (qw(package forwarded severity done owner summary outlook affects)) {
                $merge_status{$_} = $data->{$_}
            }
+           # bugs which are in the newly merged set and are also
+           # blocks/blockedby must be removed before merging
+           for (qw(blocks blockedby)) {
+               $merge_status{$_} =
+                   join(' ',grep {not exists $merged_bugs{$_}}
+                        split / /,$data->{$_});
+           }
        }
        if (defined $merge_status) {
            next unless $data->{bug_num} == $master_bug;
@@ -2764,7 +2791,8 @@ sub _summary {
                                 \#|reopen|close|(?:not|)(?:fixed|found)|clone|
                                 debug|(?:not|)forwarded|priority|
                                 (?:un|)block|limit|(?:un|)archive|
-                                reassign|retitle|affects|wrongpackage
+                                reassign|retitle|affects|package|
+                                outlook|
                                 (?:un|force|)merge|user(?:category|tags?|)
                             )\s+\S}xis) {
                   if (not length $paragraph) {
@@ -2936,7 +2964,8 @@ sub clone_bug {
     for my $bug (split ' ', $data->{blocks}) {
        for my $new_bug (@new_bugs) {
            set_blocks(bug => $bug,
-                   block => $new_bug,
+                      block => $new_bug,
+                      add => 1,
                       hash_slice(%param,
                                  keys %common_options,
                                  keys %append_action_options),
@@ -2947,7 +2976,8 @@ sub clone_bug {
     for my $bug (split ' ', $data->{blockedby}) {
        for my $new_bug (@new_bugs) {
            set_blocks(bug => $new_bug,
-                   block => $bug,
+                      block => $bug,
+                      add => 1,
                       hash_slice(%param,
                                  keys %common_options,
                                  keys %append_action_options),
@@ -3216,6 +3246,15 @@ sub bug_unarchive {
      my @bugs = @{$info{bugs}};
      my $action = "$config{bug} unarchived.";
      my @files_to_remove;
+     ## error out if we're unarchiving unarchived bugs
+     for my $data (@{$info{data}}) {
+        if (not defined $data->{archived} or
+            not $data->{archived}
+           ) {
+            __end_control(%info);
+            croak("Bug $data->{bug_num} was not archived; not unarchiving it.");
+        }
+     }
      for my $bug (@bugs) {
          print {$debug} "$param{bug} removing $bug\n";
          my $dir = get_hashname($bug);
@@ -3790,7 +3829,7 @@ LIMIT:        for my $limit (make_list($param{limit}{$field})) {
            }
            if (not $match) {
                $going_to_fail = 1;
-               print {$transcript} qq($field: ).join(', ',map{qq("$_")} make_list($data->{$field})).
+               print {$transcript} qq($field: ').join(', ',map{qq("$_")} make_list($data->{$field})).
                    "' does not match at least one of ".
                    join(', ',map {ref($_)?'(regex)':qq("$_")} make_list($param{limit}{$field}))."\n";
            }
@@ -3833,7 +3872,7 @@ sub __message_body_template{
      $extra_var ||={};
      my $hole_var = {'&bugurl' =>
                     sub{"$_[0]: ".
-                            'http://'.$config{cgi_domain}.'/'.
+                            $config{cgi_domain}.'/'.
                                 Debbugs::CGI::bug_links(bug => $_[0],
                                                         links_only => 1,
                                                        );