Client

=title class Zef::Client
=subtitle Task coordinator for raku distribution installation workflows

Synopsis

    use Zef::Client;
    use Zef::Config;
    # Get default config (see resources/config.json for more details on config options)
    my $config-file = Zef::Config::guess-path();
    my $config      = Zef::Config::parse-file($config-file);
    # Create a client
    my $client = Zef::Client.new(:$config);
    # Add some basic logging so there is output to see
    my $logger = $client.logger.Supply;
    $logger.tap: -> $m { say $m.<message> }
    # Use the client to resolve the requested candidates
    my @requested-candidates    = $client.find-candidates('Distribution::Common::Remote');
    my @dependencies-candidates = $client.find-prereq-candidates(|@requested-candidates);
    my @candidates              = |@requested-candidates, |@dependencies-candidates;
    say "Found " ~ @candidates.elems ~ " candidates...";
    # Use the client to fetch/build/test/install candidates to the default raku repository
    my CompUnit::Repository @install-to = CompUnit::RepositoryRegistry.repository-for-name('site');
    $client.make-install(|@candidates, :to(@install-to));
    say "Installed candidates!";

Description

A class that coordinates the various stages of a raku distribution installation workflow based on various configuration parameters.

Additionally it provides slightly higher level facilities for fetching, extracting, etc, than the e.g. Zef::Fetch, Zef::Extract, etc modules it uses underneath. For example Zef::Client.fetch may run an extraction step unlike Zef::Fetch.fetch, since the former is in the context of a distribution (i.e. we want the distribution at the specific commit/tag, not the HEAD immediately after fetching).

Methods

method find-candidates

method find-candidates(*@identities ($, *@) --> Array[Candidate])

Searches all repositories via Zef::Repository and returns a matching Candidate / distribution for each supplied identity. Generally this is used to find the top level distributions requested, such as Foo in zef install Foo.

method find-candidates

method find-prereq-candidates(Bool :$skip-installed = True, *@candis ($, *@) --> Array[Candidate])

Similar to method find-candidates but returns matching a matching Candidate for each dependency of the supplied identities. Generally this is used to recursively discover and determine the dependencies of the identities requested. If $skip-installed is set to False it will potentially install a newer version of an already installed matching dependency (without uninstalling the previous version). It also skips any identity matching of @.ignore, which allows getting past an unresolvable dependency ala `zef install Inline::Perl5 --ignore="perl"`.

Returns an Array of Candidate that fulfill the dependency requirements of @identities.

method search(*@identities ($, *@), *%fields, Bool :$strict = False --> Array[Candidate])

Resolves each identity in @identities to all of its matching Candidates from all backends via Zef::Repository (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 fetch

method fetch(*@candidates ($, *@) --> Array[Candidate])

Fetches a distribution from some location, and unpacks/extracts it to a temporary location to be used be cached, tested, installed, etc. It effective combines the functionality of Zef::Fetch.fetch and Zef::Extract.extract into a single method as there isn't yet a useful reason to have workflows that work with compressed archives/packages. Fetches up to $.fetch-degree different @candidates in parallel.

Anytime a distribution is fetched it will call .store(@distributions) on any Zef::Repository that supports it (usually just Zef::Repository::LocalCache).

File are saved to the TempDir setting in resources/config.json, and extracted to the $.cache directory (the StoreDir setting in resources/config.json).

Returns an Array of Candidate containing the successfully fetched results.

method build

method build(*@candidates ($, *@) --> Array[Candidate])

Runs the build process on each @candidates that the backends for Zef::Build know how to process. Builds up to $.build-degree different @candidates in parallel.

Returns an Array of Candidate with each .build-results set appropriately.

method test

method test(*@candidates ($, *@) --> Array[Candidate])

Runs the test process on each @candidates via the backends of Zef::Test. Tests up to $.test-degree different @candidates in parallel.

Returns an Array of Candidate with each .test-results set appropriately.

method uninstall

method uninstall(CompUnit::Repository :@from!, *@identities --> Array[Candidate])

Searches each CompUnit::Repository in @from for each @identities and uninstalls any matching distributions. For instance uninstalling zef could potentially uninstall multiple versions, whereas uninstall zef:ver("0.9.4") would only uninstall that specific version.

Returns an Array containing each uninstalled Candidate.

method install

method install(:@curs, *@candidates ($, *@) --> Array[Candidate])

Install a Candidate containing a Distribution to each CompUnit::Repository in @curs.

Returns an Array containing each successfully installed Candidate.

method make-install

method make-install(CompUnit::Repository :@to!, Bool :$fetch = True, Bool :$build = True, Bool :$test  = True, Bool :$dry, Bool :$serial, *@candidates ($, *@), *%_)

The 'do everything but resolve dependencies' method. You essentially figure out all the Candidate you need to install (dependencies, etc) and pass them to this method. Its similar to method install except it also handles calling method fetch (if $fetch is True), method build (if $build is True), and method test (if <$test> is True). If $dry is True then the final step of calling method install (which moves the modules to where raku will see them) will be skipped. If <$serial> is True then each Candidate will be installed after it passes its own tests (instead of the default behavior of only installing if all Candidate, including dependencies, pass their tests).

method list-rev-depends

method list-rev-depends($identity, Bool :$indirect --> Array[Candidate])

Return an Array of Candidate of all distribution that directly depend on $identity. If $indirect is True then it additionally returns distributions that indirectly / transitively depend on $identity

method list-available

method list-available(*@recommendation-manager-names --> Array[Candidate])

Returns an Array of Candidate for every distribution from every repository / recommendation-manager with a name (as set in resources/config.json) matching any of those in @recommendation-manager-names (or all repositories if no names are supplied). Note some non-standard repositories may not support listing all available distributions.

method list-installed

method list-installed(*@curis --> Array[Candidate])

Returns an Array of Candidate for each Raku distribution installed to each CompUnit::Repository::Installation @curis (or all known CompUnit::Repository::Installation if no @curis are supplied).

method list-leaves

method list-leaves(--> Array[Candidate])

Returns an Array of Candidate for each installed distributions that nothing else appears to depend on.

method list-dependencies

method list-dependencies(*@candis --> Array[DependencySpecification])

Returns an Array of Zef::Distribution::DependencySpecification and // or Zef::Distribution::DependencySpecification::Any for each @candis distributions various dependency requirements.

If $.depends is set to False then runtime dependencies will be ignored. If $.test-depends is set to False then test dependencies will be ignored. If $.build-depends is set to False then build dependencies will be ignored.

method resolve

method resolve($spec, CompUnit::Repository :@at --> Array[Candidate])

Returns the best matching distributions from installed sources for the given $spec, in preferred order (highest api version and highest version) from each CompUnit::Repository in @at (or all known CompUnit::Repository if @at is not set). $spec should be either a Zef::Distribution::DependencySpecification or Zef::Distribution::DependencySpecification::Any.

method is-installed

multi method is-installed(Str $spec, |c --> Bool:D)
        multi method is-installed(Zef::Distribution::DependencySpecification::Any $spec, |c --> Bool:D)
        multi method is-installed(Zef::Distribution::DependencySpecification $spec, |c --> Bool:D)

Returns True if the requested $spec is installed. The logic it uses to decide if something is installed is based on the $spec.from-matcher: foo:from<bin> will search $PATH for foo, foo:from<native> will check if NativeCall can see an e.g. libfoo.so or foo.dll, and everything else will be looked up as a foo raku module.

method sort-candidates

method sort-candidates(@candis --> Array[Candidate])

Does a topological sort of @candis based on their various dependency fields and $.depends/$.test-depends/$.build-depends.

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