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;
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;
# 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;
@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";
}
}
$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',
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";
}
}
$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;
);
}
}
+ };
+ 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],
}
# 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,
$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;
\#|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) {
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);