use Encode qw(decode encode is_utf8);
use Storable qw(dclone);
-use List::Util qw(min max);
+use List::AllUtils qw(min max uniq);
+use DateTime::Format::Pg;
use Carp qw(croak);
$data{archived} = (defined($location) and ($location eq 'archive'))?1:0;
$data{bug_num} = $param{bug};
+ # mergedwith occasionally is sorted badly. Fix it to always be sorted by <=>
+ # and not include this bug
+ if (defined $data{mergedwith} and
+ $data{mergedwith}) {
+ $data{mergedwith} =
+ join(' ',
+ grep { $_ != $data{bug_num}}
+ sort { $a <=> $b }
+ split / /, $data{mergedwith}
+ );
+ }
return \%data;
}
return grep {length $_} map {split $splitter} @t;
};
-my $ditch_empty_space = sub {return &{$ditch_empty}(' ',@_)};
+our $sort_and_unique = sub {
+ my @v;
+ my %u;
+ my $all_numeric = 1;
+ for my $v (@_) {
+ if ($all_numeric and $v =~ /\D/) {
+ $all_numeric = 0;
+ }
+ next if exists $u{$v};
+ $u{$v} = 1;
+ push @v, $v;
+ }
+ if ($all_numeric) {
+ return sort {$a <=> $b} @v;
+ } else {
+ return sort @v;
+ }
+};
+
+my $ditch_space_unique_and_sort = sub {return &{$sort_and_unique}(&{$ditch_empty}(' ',@_))};
my %split_fields =
(package => \&splitpackages,
affects => \&splitpackages,
- blocks => $ditch_empty_space,
- blockedby => $ditch_empty_space,
+ # Ideally we won't have to split source, but because some consumers of
+ # get_bug_status cannot handle arrayref, we will split it here.
+ source => \&splitpackages,
+ blocks => $ditch_space_unique_and_sort,
+ blockedby => $ditch_space_unique_and_sort,
# this isn't strictly correct, but we'll split both of them for
# the time being until we ditch all use of keywords everywhere
# from the code
- keywords => $ditch_empty_space,
- tags => $ditch_empty_space,
- found_versions => $ditch_empty_space,
- fixed_versions => $ditch_empty_space,
- mergedwith => $ditch_empty_space,
+ keywords => $ditch_space_unique_and_sort,
+ tags => $ditch_space_unique_and_sort,
+ found_versions => $ditch_space_unique_and_sort,
+ fixed_versions => $ditch_space_unique_and_sort,
+ mergedwith => $ditch_space_unique_and_sort,
);
sub split_status_fields {
=cut
sub lockreadbugmerge {
- my ($bug_num,$location) = @_;
my $data = lockreadbug(@_);
if (not defined $data) {
return (0,undef);
# are all merged with eachother
# We do a cmp sort instead of an <=> sort here, because that's
# what merge does
- my $expectmerge= join(' ',grep {$_ != $bug } sort @bugs);
+ my $expectmerge=
+ join(' ',grep {$_ != $bug }
+ sort { $a <=> $b }
+ @bugs);
if ($newdata->{mergedwith} ne $expectmerge) {
for (1..$locks) {
unfilelock(exists $param{locks}?$param{locks}:());
indicatesource => {type => BOOLEAN,
default => 1,
},
+ schema => {type => OBJECT,
+ optional => 1,
+ },
},
);
my %status;
return \%status;
}
if (defined $param{status}) {
- %status = %{$param{status}};
+ %status = %{$param{status}};
+ }
+ elsif (defined $param{schema}) {
+ my $b = $param{schema}->resultset('Bug')->
+ search_rs({'me.id' => $param{bug}},
+ {prefetch => [{'bug_tags'=>'tag'},
+ 'severity',
+ {'bug_binpackages'=> 'bin_pkg'},
+ {'bug_srcpackages'=> 'src_pkg'},
+ {'bug_user_tags'=>{'user_tag'=>'correspondent'}},
+ {owner => 'correspondent_full_names'},
+ {submitter => 'correspondent_full_names'},
+ 'bug_merged_bugs',
+ 'bug_mergeds_merged',
+ 'bug_blocks_blocks',
+ 'bug_blocks_bugs',
+ {'bug_vers' => ['src_pkg','src_ver']},
+ ],
+ '+columns' => [qw(subject log_modified creation last_modified)],
+ collapse => 1,
+ result_class => 'DBIx::Class::ResultClass::HashRefInflator',
+ })->first();
+ $status{keywords} =
+ join(' ',map {$_->{tag}{tag}} @{$b->{bug_tags}});
+ $status{tags} = $status{keywords};
+ $status{subject} = $b->{subject};
+ $status{bug_num} = $b->{id};
+ $status{severity} = $b->{severity}{severity};
+ $status{package} =
+ join(' ',
+ (map {$_->{bin_pkg}{pkg}} @{$b->{bug_binpackages}//[]}),
+ (map {$_->{src_pkg}{pkg}} @{$b->{bug_srcpackages}//[]}));
+ $status{originator} = $b->{submitter_full};
+ $status{log_modified} =
+ DateTime::Format::Pg->parse_datetime($b->{log_modified})->epoch;
+ $status{date} =
+ DateTime::Format::Pg->parse_datetime($b->{creation})->epoch;
+ $status{last_modified} =
+ DateTime::Format::Pg->parse_datetime($b->{last_modified})->epoch;
+ $status{blocks} =
+ join(' ',
+ uniq(sort(map {$_->{block}}
+ @{$b->{bug_blocks_block}},
+ )));
+ $status{blockedby} =
+ join(' ',
+ uniq(sort(map {$_->{bug}}
+ @{$b->{bug_blocks_bug}},
+ )));
+ $status{mergedwith} =
+ join(' ',uniq(sort(map {$_->{bug},$_->{merged}}
+ @{$b->{bug_merged_bugs}},
+ @{$b->{bug_mergeds_merged}},
+ )));
+ $status{fixed_versions} =
+ [map {$_->{found}?():$_->{ver_string}} @{$b->{bug_vers}}];
+ $status{found_versions} =
+ [map {$_->{found}?$_->{ver_string}:()} @{$b->{bug_vers}}];
}
else {
my $location = getbuglocation($param{bug}, 'summary');