Repository
=title class Zef::Repository
=subtitle A configurable implementation of the Repository interface
Synopsis
use Zef::Fetch;
use Zef::Repository;
# Need a fetcher and cache for the backend repository to fetch and save to
my @fetching_backends = [
{ module => "Zef::Service::Shell::curl" },
{ module => "Zef::Service::Shell::wget" },
];
my $fetcher = Zef::Fetch.new(:backends(@fetching_backends));
my $cache = $*TMPDIR.child("{time}") andthen { mkdir $_ unless $_.IO.e };
# Create repo using a backend that is essentially just: Zef::Repository::Ecosystems.new(|%options-shown-below)
# Note usually options are all Str so they can be set in the config file, but for the time being the cache
# and fetcher objects need to be passed in here as well (currently auto-magically done in Zef::Client but could
# be done in Zef::Repository)
my $repo = Zef::Repository.new(
backends => [
[
{
module => "Zef::Repository::Ecosystems",
options => {
cache => $cache,
fetcher => $fetcher,
name => "cpan",
auto-update => 1,
mirrors => ["https://raw.githubusercontent.com/ugexe/Perl6-ecosystems/11efd9077b398df3766eaa7cf8e6a9519f63c272/cpan.json"]
}
},
],
]
);
# Print out all available distributions from all supplied backend repositories
say $_.dist.identity for $repo.available;
# Get the best match for 'Zef'
my @matches = $repo.candidates("Zef");
say "Best match: " ~ @matches.head.dist.identity;
Description
A Repository
that uses 1 or more other Repository
instances as backends. It abstracts the logic
for e.g. sorting by version from multiple repositories. Each Repository
(including this one and
whatever backends this may use) can be thought of as recommendation managers, where Zef::Repository
gives a recommendation based on recommendations it gets from its backends (i.e. fez, p6c, cpan, cached).
Methods
method candidates
method candidates(*@identities ($, *@) --> Array[Candidate])
Resolves each identity in @identities
to its best matching Candidate
, where the "best match" is generally
what is most consistent with how Raku
would otherwise load modules.
Each repository makes its own recommendations, and only then will the results be considered to make a single recommendation
for each of @identities
from. For instance one ecosystem might return a Foo:ver(1)
and Foo:ver(3)
, and another a Foo:ver(2)
for an identity of Foo
-- this module emulates Raku
internal module resolution logic and will choose the best match (in this case
Foo:ver(3)
.
This module purposely does not combine multiple ecosystems into a single list to make a recommendation from; by design it a recommendation manager for the results of recommendation managers. This allows more consistent resolution of dependencies and integration with MetaCPAN like services (which may not just provide an entire list of modules it has -- i.e. it makes it own recommendation for a name)
One difference in how recommendations are made from raku is that repos are grouped. Given pseudo backends [[Eco1,Eco2],[Eco3]]
we see three
repository backends in two different groups -- ecosystems in later groups are only searched if previous groups found no matches. This allows
users to avoid dependency confusion attacks by allowing custom ecosystems to be the preferred source for whatever namespaces it provides
regardless if another ecosystem later provides a module by the same name but higher version number.
Returns an Array
of Candidate
, where each Candidate
matches exactly one of the provided @identities
(and
each @identities
matches zero or one of the Candidate
).
method search
method search(:$max-results, Bool :$strict, *@identities ($, *@), *%fields --> Array[Candidate])
Resolves each identity in @identities
to all of its matching Candidates
from all backends (with $max-results
applying to
each individual backend). If $strict
is False
then it will consider partial matches on module short-names (i.e. 'zef search HTTP'
will get results for e.g. HTTP::UserAgent
).
method store
method store(*@dists --> Nil)
Attempts to store/save/cache each @dist
to each backend repository that provides a store
method. Generally this is used when
a module is fetched from e.g. fez so that Zef::Repository::LocalCache
can cache it for next time. Note distributions fetched from
local paths (i.e. `zef install .`) do not generally get passed to this method.
method available
method available(*@plugins --> Array[Candidate])
Returns an Array
of all Candidate
provided by all backend repositories that support the available
method (http-query-per-request
repositories may not be able to provide this) and have a 'name' (as defined in its entry in resources/config.json
) matching any of
those in @names
(i.e. zef list fez
will only show stuff from the 'fez' backend).
method update
method update(*@plugins, Supplier :$logger --> Hash)
Updates each ecosystem backend (generally downloading a p6c.json or cpan.json file, or updating the 'cached' index).
An optional :$logger
can be supplied to receive events about what is occurring.