urpmi

 view release on metacpan or  search on metacpan

urpm/get_pkgs.pm  view on Meta::CPAN

package urpm::get_pkgs;


use strict;
use urpm::msg;
use urpm::sys;
use urpm::util qw(basename put_in_hash);
use urpm::media;
use urpm 'file_from_local_url';
# perl_checker: require urpm::select


=head1 NAME

urpm::get_pkgs - Package retrieving routines for urpmi

=head1 SYNOPSIS

=head1 DESCRIPTION

=over

=cut 

sub clean_all_cache {
    my ($urpm) = @_;
    #- clean download directory, do it here even if this is not the best moment.
    $urpm->{log}(N("cleaning %s and %s", "$urpm->{cachedir}/partial", "$urpm->{cachedir}/rpms"));
    urpm::sys::empty_dir("$urpm->{cachedir}/partial");
    urpm::sys::empty_dir("$urpm->{cachedir}/rpms");
}

sub cachedir_rpms {
    my ($urpm) = @_;

    #- examine the local repository, which is trusted (no gpg or pgp signature check but md5 is now done).
    my %fn2file;
    foreach my $filepath (glob("$urpm->{cachedir}/rpms/*")) {
	next if -d $filepath;

	if (! -s $filepath) {
	    unlink $filepath; #- this file should be removed or is already empty.
	} else {
	    my $filename = basename($filepath);
	    my ($fullname) = $filename =~ /(.*)\.rpm$/ or next;
	    $fn2file{$fullname} = $filepath;
	}
    }
    \%fn2file;
}

#- select sources for selected packages,
#- according to keys of the packages hash.
#- returns a list of lists containing the source description for each rpm,
#- matching the exact number of registered media; ignored media being
#- associated to a null list.
sub _selected2local_and_ids {
    my ($urpm, $packages, %options) = @_;
    my (%protected_files, %local_sources, %fullname2id);

    #- build association hash to retrieve id and examine all list files.
    foreach (keys %$packages) {
	foreach my $id (split /\|/, $_) {
	    if ($urpm->{source}{$_}) {
		my $file = $local_sources{$id} = $urpm->{source}{$id};
		$protected_files{$file} = undef;
	    } else {
		$fullname2id{$urpm->{depslist}[$id]->fullname} = $id;
	    }
	}
    }

    #- examine the local repository, which is trusted (no gpg or pgp signature check but md5 is now done).
    my $cachedir_rpms = cachedir_rpms($urpm);

    foreach my $fullname (keys %$cachedir_rpms) {
	    my $filepath = $cachedir_rpms->{$fullname};

	    if (my $id = delete $fullname2id{$fullname}) {
		$local_sources{$id} = $filepath;
	    } else {
		$options{clean_other} && ! exists $protected_files{$filepath} and unlink $filepath;
	    }
    }

    my %id2ids;
    foreach my $id (values %fullname2id) {
	my $pkg = $urpm->{depslist}[$id];
	my $fullname = $pkg->fullname;
	my @pkg_ids = $pkg->arch eq 'src' ? do {
	    # packages_by_name can't be used here since $urpm->{provides} doesn't have src.rpm
	    # so a full search is needed
	    my %requested;
	    urpm::select::search_packages($urpm, \%requested, [$pkg->name], src => 1);
	    map { split /\|/ } keys %requested;
	} : do {
	    map { $_->id } grep {
		$_->filename !~ /\.delta\.rpm$/ || $urpm->is_delta_installable($_, $urpm->{root});
	    } grep { $fullname eq $_->fullname } $urpm->packages_by_name($pkg->name);
	};

	$id2ids{$id} = \@pkg_ids;
    }

    (\%local_sources, \%id2ids);
}

sub selected2local_and_blists {
    my ($urpm, $selected, %options) = @_;

    my ($local_sources, $id2ids) = _selected2local_and_ids($urpm, $selected, %options);

    # id_map is a remapping of id.
    # it is needed because @list must be [ { id => pkg } ] where id is one the selected id,
    # not really the real package id
    my %id_map;
    foreach my $id (keys %$id2ids) {
	$id_map{$_} = $id foreach @{$id2ids->{$id}};
    }

    my @remaining_ids = sort { $a <=> $b } keys %id_map;

    my @blists = map {
	my $medium = $_;
	my %pkgs;
	if (urpm::media::is_valid_medium($medium) && !$medium->{ignore}) {
	    while (@remaining_ids) {
		my $id = $remaining_ids[0];
		$medium->{start} <= $id && $id <= $medium->{end} or last;
		shift @remaining_ids;

		my $pkg = $urpm->{depslist}[$id];
		$pkgs{$id_map{$id}} = $pkg;



( run in 1.372 second using v1.01-cache-2.11-cpan-1191d43216d )