X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=Debbugs%2FCollection%2FPackage.pm;h=62b60798db7bfd506643d2725db2cc878700b574;hb=38ff08d4f8010d674bebe24c96dfe87ac9e5a914;hp=0459b1e04f31f6e50b7ca1921dacbea6d008530e;hpb=0e16a5214d3617d0df54712869b2da0f3c64fcdb;p=debbugs.git diff --git a/Debbugs/Collection/Package.pm b/Debbugs/Collection/Package.pm index 0459b1e..62b6079 100644 --- a/Debbugs/Collection/Package.pm +++ b/Debbugs/Collection/Package.pm @@ -12,6 +12,10 @@ Debbugs::Collection::Package -- Package generation factory =head1 SYNOPSIS +This collection extends L and contains members of +L. Useful for any field which contains one or more package or +tracking lists of packages + =head1 DESCRIPTION @@ -21,56 +25,289 @@ Debbugs::Collection::Package -- Package generation factory use Mouse; use strictures 2; +use v5.10; # for state use namespace::autoclean; -use Debbugs::Common qw(make_list); + +use Carp; +use Debbugs::Common qw(make_list hash_slice); +use Debbugs::Config qw(:config); use Debbugs::OOTypes; -use Debbugs::Status qw(get_bug_statuses); +use Debbugs::Package; + +use List::AllUtils qw(part); + +use Debbugs::Version::Binary; +use Debbugs::Collection::Version; +use Debbugs::Collection::Correspondent; +use Debbugs::VersionTree; extends 'Debbugs::Collection'; -has '+members' => (isa => 'ArrayRef[Package]'); +=head2 my $packages = Debbugs::Collection::Package->new(%params|$param) + +Parameters in addition to those defined by L + +=over + +=item correspondent_collection + +Optional L which is used to look up correspondents + + +=item versiontree + +Optional L which contains known package source versions + +=back + +=head2 $packages->correspondent_collection + +Returns the L for this package collection -around BUILDARGS => sub { +=head2 versiontree + +Returns the L for this package collection + +=head2 $packages->get_source_versions_distributions(@distributions) + +Returns a L of all versions in this package +collection which belong to the distributions given. + +=head2 $packages->get_source_versions('1.2.3-1','foo/1.2.3-5') + +Given a list of binary versions or src/versions, returns a +L of all of the versions in this package +collection which are known to match. You'll have to be sure to load appropriate +versions beforehand for this to actually work. + +=cut + +has '+members' => (isa => 'ArrayRef[Debbugs::Package]'); + +sub BUILD { + my $self = shift; + my $args = shift; + if (exists $args->{packages}) { + $self-> + add($self->_member_constructor(packages => + $args->{packages})); + } +} + +around add_by_key => sub { my $orig = shift; - my $class = shift; + my $self = shift; + my @members = + $self->_member_constructor(packages => [@_]); + return $self->$orig(@members); +}; - my %args; - if (@_==1 and ref($_[0]) eq 'HASH') { - %args = %{$_[0]}; - } else { - %args = @_; +sub _member_constructor { + # handle being called $self->_member_constructor; + my $self = shift; + my %args = @_; + my $schema; + if ($self->has_schema) { + $schema = $self->schema; } - $args{members} //= []; - if (exists $args{packages}) { - if (exists $args{schema}) { - my $statuses = get_bug_statuses(bug => [make_list($args{bugs})], - schema => $args{schema}, - ); - while (my ($bug, $status) = each %{$statuses}) { - push @{$args{members}}, - Debbugs::Bug->new(bug=>$bug, - status=>$status, - schema=>$args{schema}, - @{$args{constructor_args}//[]}, + my @return; + if (defined $schema) { + if (not ref($args{packages}) or @{$args{packages}} == 1 and + $self->universe->count() > 0 + ) { + carp("Likely inefficiency; member_constructor called with one argument"); + } + my $packages = + Debbugs::Package::_get_valid_version_info_from_db(packages => $args{packages}, + schema => $schema, + ); + for my $package (keys %{$packages}) { + push @return, + Debbugs::Package->new(%{$packages->{$package}}, + schema => $schema, + package_collection => $self->universe, + correspondent_collection => + $self->correspondent_collection->universe, ); - } - } else { - for my $bug (make_list($args{bugs})) { - push @{$args{members}}, - Debbugs::Bug->new(bug => $bug, - @{$args{constructor_args}//[]}, + } + } else { + carp "No schema\n"; + for my $package (make_list($args{packages})) { + push @return, + Debbugs::Package->new(name => $package, + package_collection => $self->universe, + correspondent_collection => + $self->correspondent_collection->universe, ); - } } - delete $args{bugs}; } - return $class->$orig(%args); -}; + return @return; +} + +sub add_packages_and_versions { + my $self = shift; + $self->add($self->_member_constructor(packages => \@_)); +} + +# state $common_dists = [@{$config{distributions}}]; +# sub _get_packages { +# my %args = @_; +# my $s = $args{schema}; +# my %src_packages; +# my %src_ver_packages; +# my %bin_packages; +# my %bin_ver_packages; +# # split packages into src/ver, bin/ver, src, and bin so we can select them +# # from the database +# local $_; +# for my $pkg (@{$args{packages}}) { +# if (ref($pkg)) { +# if ($pkg->[0] =~ /^src:(.+)$/) { +# for my $ver (@{$pkg}[1..$#{$pkg}]) { +# $src_ver_packages{$1}{$ver} = 1; +# } +# } else { +# for my $ver (@{$pkg}[1..$#{$pkg}]) { +# $bin_ver_packages{$pkg->[0]}{$ver} = 1; +# } +# } +# } elsif ($pkg =~ /^src:(.+)$/) { +# $src_packages{$1} = 1; +# } else { +# $bin_packages{$pkg} = 1; +# } +# } +# my @src_ver_search; +# for my $sp (keys %src_ver_packages) { +# push @src_ver_search, +# (-and => {'src_pkg.pkg' => $sp, +# 'me.ver' => [keys %{$src_ver_packages{$sp}}], +# }, +# ); +# } +# my %packages; +# my $src_rs = $s->resultset('SrcVer')-> +# search({-or => [-and => {'src_pkg.pkg' => [keys %src_packages], +# -or => {'suite.codename' => $common_dists, +# 'suite.suite_name' => $common_dists, +# }, +# }, +# @src_ver_search, +# ], +# }, +# {join => ['src_pkg', +# {'src_associations' => 'suite'}, +# ], +# '+select' => [qw(src_pkg.pkg), +# qw(suite.codename), +# qw(src_associations.modified), +# q(CONCAT(src_pkg.pkg,'/',me.ver))], +# '+as' => [qw(src_pkg_name codename modified_time src_pkg_ver)], +# result_class => 'DBIx::Class::ResultClass::HashRefInflator', +# order_by => {-desc => 'me.ver'} +# }, +# ); +# while (my $pkg = $src_rs->next) { +# my $n = 'src:'.$pkg->{src_pkg_name}; +# if (exists $packages{$n}) { +# push @{$packages{$n}{versions}}, +# $pkg->{src_pkg_ver}; +# if (defined $pkg->{codename}) { +# push @{$packages{$n}{dists}{$pkg->{codename}}}, +# $#{$packages{$n}{versions}}; +# } +# } else { +# $packages{$n} = +# {name => $pkg->{src_pkg_name}, +# type => 'source', +# valid => 1, +# versions => [$pkg->{src_pkg_ver}], +# dists => {defined $pkg->{codename}?($pkg->{codename} => [1]):()}, +# }; +# } +# } +# return \%packages; +# } sub member_key { - return $_[1]->bug; + return $_[1]->qualified_name; } +has 'correspondent_collection' => + (is => 'ro', + isa => 'Debbugs::Collection::Correspondent', + default => sub {Debbugs::Collection::Correspondent->new()}, + ); + +has 'versiontree' => + (is => 'ro', + isa => 'Debbugs::VersionTree', + lazy => 1, + builder => '_build_versiontree', + ); + +sub _build_versiontree { + my $self = shift; + return Debbugs::VersionTree->new($self->has_schema?(schema => $self->schema):()); +} + + +sub get_source_versions_distributions { + my $self = shift; + my @return; + push @return, + $self->apply(sub {$_->get_source_version_distribution(@_)}); + return + Debbugs::Collection::Version->new(versions => \@return, + $self->has_schema?(schema => $self->schema):(), + package_collection => $self->universe, + ); +} + +# given a list of binary versions or src/versions, returns all of the versions +# in this package collection which are known to match. You'll have to be sure to +# load appropriate versions beforehand for this to actually work. +sub get_source_versions { + my $self = shift; + my @return; + for my $ver (@_) { + my $sv; + if ($ver =~ m{(.+?)/(?.+)$/}) { + my $sp = $self->get_or_add_by_key('src:'.$+{src}); + push @return, + $sp->get_source_version($ver); + next; + } else { + my $found_valid = 0; + for my $p ($self->members) { + local $_; + my @vs = + grep {$_->is_valid} + $p->get_source_version($ver); + if (@vs) { + $found_valid = 1; + push @return,@vs; + next; + } + } + if (not $found_valid) { + push @return, + Debbugs::Version::Binary->new(version => $ver, + package_collection => $self->universe, + valid => 0, + $self->schema_argument, + ); + } + } + } + return + Debbugs::Collection::Version->new(versions => \@return, + $self->schema_argument, + package_collection => $self->universe, + ); +} + + __PACKAGE__->meta->make_immutable; 1;