Carmel
view release on metacpan or search on metacpan
lib/Carmel/Resolver.pm view on Meta::CPAN
package Carmel::Resolver;
use strict;
use warnings;
use Class::Tiny qw( repo snapshot root seen found missing );
use Module::CoreList;
use Try::Tiny;
sub resolve {
my $self = shift;
my $clone = $self->root->clone;
my $seen = {};
my $depth = 0;
$self->resolve_recurse($clone, $seen, $depth);
}
sub resolve_recurse {
my($self, $requirements, $seen, $depth) = @_;
for my $module (sort $requirements->required_modules) {
next if $module eq 'perl';
my $want_version = $self->root->requirements_for_module($module);
my $dist = $self->find_in_snapshot($module);
$self->should_handle($module, $want_version, $dist)
or next;
my $artifact;
if ($dist) {
$artifact = $self->repo->find_dist($module, $dist->name);
} else {
$artifact = $self->repo->find_match($module, sub { $self->accepts_all($self->root, $_[0]) });
}
# FIXME there's a chance different version of the same module can be loaded here
if ($artifact) {
warn sprintf " %s (%s) in %s\n", $module, $artifact->version_for($module), $artifact->path if $Carmel::DEBUG;
next if $seen->{$artifact->path}++;
$self->found->($artifact, $depth);
my $reqs = $artifact->requirements;
$self->merge_requirements($self->root, $reqs, $artifact->distname);
$self->resolve_recurse($reqs, $seen, $depth + 1);
} else {
if ($dist) {
# TODO pass $dist->distfile to cpanfile
$want_version = $dist->version_for($module);
}
$self->missing->($module, $want_version, $depth);
}
}
}
sub should_handle {
my($self, $module, $version, $dist) = @_;
# not in core
return 1 unless $self->is_core($module);
# core version doesn't satisfy the version
return 1 unless $self->core_satisfies($module, $version);
# core, pinned, and the pinned version is lower than the core version:
( run in 1.419 second using v1.01-cache-2.11-cpan-d8267643d1d )