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.

The Camelia image is copyright 2009 by Larry Wall. "Raku" is trademark of the Yet Another Society. All rights reserved.