use warnings;
use strict;
+use feature 'state';
+
use vars qw($VERSION $DEBUG %EXPORT_TAGS @EXPORT_OK @EXPORT);
use Exporter qw(import);
use Encode qw(decode encode is_utf8);
use Storable qw(dclone);
-use List::AllUtils qw(min max);
+use List::AllUtils qw(min max uniq);
+use DateTime::Format::Pg;
use Carp qw(croak);
if (@_ == 1) {
unshift @_, 'bug';
}
+ state $spec =
+ {bug => {type => SCALAR,
+ optional => 1,
+ # something really stupid passes negative bugnumbers
+ regex => qr/^-?\d+/,
+ },
+ location => {type => SCALAR|UNDEF,
+ optional => 1,
+ },
+ summary => {type => SCALAR,
+ optional => 1,
+ },
+ lock => {type => BOOLEAN,
+ optional => 1,
+ },
+ locks => {type => HASHREF,
+ optional => 1,
+ },
+ };
my %param = validate_with(params => \@_,
- spec => {bug => {type => SCALAR,
- optional => 1,
- # something really
- # stupid passes
- # negative bugnumbers
- regex => qr/^-?\d+/,
- },
- location => {type => SCALAR|UNDEF,
- optional => 1,
- },
- summary => {type => SCALAR,
- optional => 1,
- },
- lock => {type => BOOLEAN,
- optional => 1,
- },
- locks => {type => HASHREF,
- optional => 1,
- },
- },
+ spec => $spec,
);
die "One of bug or summary must be passed to read_bug"
if not exists $param{bug} and not exists $param{summary};
my %data;
my @lines;
- my $version = 2;
+ my $version;
local $_;
while (<$status_fh>) {
chomp;
push @lines, $_;
- $version = $1 if /^Format-Version: ([0-9]+)/i;
+ if (not defined $version and
+ /^Format-Version: ([0-9]+)/i
+ ) {
+ $version = $1;
+ }
}
-
+ $version = 2 if not defined $version;
# Version 3 is the latest format version currently supported.
if ($version > 3) {
warn "Unsupported status version '$version'";
return undef;
}
- my %namemap = reverse %fields;
+ state $namemap = {reverse %fields};
for my $line (@lines) {
if ($line =~ /(\S+?): (.*)/) {
my ($name, $value) = (lc $1, $2);
# or \n in the fields of status. Kill them off here.
# [Eventually, this should be superfluous.]
$value =~ s/[\r\n]//g;
- $data{$namemap{$name}} = $value if exists $namemap{$name};
+ $data{$namemap->{$name}} = $value if exists $namemap->{$name};
}
}
for my $field (keys %fields) {
if (@_ == 1) {
unshift @_, 'bug';
}
+ state $spec =
+ {bug => {type => SCALAR,
+ regex => qr/^\d+$/,
+ },
+ status => {type => HASHREF,
+ optional => 1,
+ },
+ bug_index => {type => OBJECT,
+ optional => 1,
+ },
+ version => {type => SCALAR|ARRAYREF,
+ optional => 1,
+ },
+ dist => {type => SCALAR|ARRAYREF,
+ optional => 1,
+ },
+ arch => {type => SCALAR|ARRAYREF,
+ optional => 1,
+ },
+ bugusertags => {type => HASHREF,
+ optional => 1,
+ },
+ sourceversions => {type => ARRAYREF,
+ optional => 1,
+ },
+ indicatesource => {type => BOOLEAN,
+ default => 1,
+ },
+ binary_to_source_cache => {type => HASHREF,
+ optional => 1,
+ },
+ schema => {type => OBJECT,
+ optional => 1,
+ },
+ };
my %param = validate_with(params => \@_,
- spec => {bug => {type => SCALAR,
- regex => qr/^\d+$/,
- },
- status => {type => HASHREF,
- optional => 1,
- },
- bug_index => {type => OBJECT,
- optional => 1,
- },
- version => {type => SCALAR|ARRAYREF,
- optional => 1,
- },
- dist => {type => SCALAR|ARRAYREF,
- optional => 1,
- },
- arch => {type => SCALAR|ARRAYREF,
- optional => 1,
- },
- bugusertags => {type => HASHREF,
- optional => 1,
- },
- sourceversions => {type => ARRAYREF,
- optional => 1,
- },
- indicatesource => {type => BOOLEAN,
- default => 1,
- },
- },
+ spec => $spec,
);
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');
$status{source} = binary_to_source(binary=>[split /\s*,\s*/, $status{package}],
source_only => 1,
+ exists $param{binary_to_source_cache}?
+ (cache =>$param{binary_to_source_cache}):(),
);
$status{"package"} = 'unknown' if ($status{"package"} eq '');