App-cpan2arch

 view release on metacpan or  search on metacpan

lib/App/cpan2arch/GetMetadata.pm  view on Meta::CPAN

use v5.42.0;

use strict;
use warnings;
no source::encoding;  # Avoid dying on v5.42.0 (non-ASCII char in POD).

use Object::Pad 0.825;

package App::cpan2arch::GetMetadata;  # For toolchain compatibility.
role App::cpan2arch::GetMetadata;

use File::Spec::Functions qw< catdir splitdir >;
use Scalar::Util          qw< looks_like_number >;

our $VERSION = 'v1.1.2';

field %_endpoints :reader :writer = (
    module   => 'https://fastapi.metacpan.org/v1/module/',
    release  => 'https://fastapi.metacpan.org/v1/release/',
    download => 'https://fastapi.metacpan.org/v1/download_url/',
);
field $_mua_mcpan :reader;
field %_optionals :reader;
field %_meta      :reader :writer;

# Get CPAN metadata from MetaCPAN's API.
#
# References:
#   https://github.com/metacpan/metacpan-api/blob/master/docs/API-docs.md
method get_metadata ()
{
    $self->_psub;

    $self->_init_mua_mcpan;

    # Get the module/distribution and its release.
    my $dist;
    my $rel;
    {
        my %args    = $self->args;
        my $module  = $args{module};
        my $version = $args{version};
        my $mod;

        # Only request for a module if it does not look like a dist and no version
        # argument is passed, otherwise treat it as dist.
        if ( $module !~ /-/ && !defined $version ) {
            $mod = $self->_get_module($module);
            $self->_pdbg("found module\n\n") if defined $mod;
        }

        # Since modules and dists names can be ambiguous, e.g. Reply, do not exit
        # if a module request fails, but fallback as dist.
        $dist = defined $mod ? $mod->{distribution} : $module;

        $self->_pdbg("Dist\n");
        $self->_pdump( '$dist', \$dist, "\n" );

        $rel = $self->_get_release($dist);
        return 1 if $rel == 1;

        $self->_pdbg("Release\n");
        $self->_pdump( '$rel', \$rel, "\n" );
    }

    # Find Module::Install, license, and XS files in the dist.
    my $ret = $self->_find_files( $dist, $rel->{download_url} );
    return 1 if looks_like_number($ret) && $ret == 1;
    my %files = $ret->%*;

    # Get 'optionals_features' descriptions (will be added to the optdepends array).
    # See https://metacpan.org/pod/CPAN::Meta::Spec#optional_features.
    {
        foreach my ( $feature, $feat_info ) ( $rel->{metadata}{optional_features}->%* ) {

            foreach my ( $phase, $phase_info ) ( $feat_info->{prereqs}->%* ) {

                foreach my ( $relation, $rel_info ) ( $phase_info->%* ) {

                    foreach my ( $module, $version ) ( $rel_info->%* ) {
                        push $_optionals{$module}->@*, $feat_info->{description};
                    }
                }
            }
        }

        $self->_pdump( '%_optionals', \%_optionals, "\n" );
    }

    %_meta = (
        author             => $rel->{author},
        name               => $rel->{name},
        dist               => $rel->{distribution},
        version            => $rel->{version},
        abstract           => $rel->{abstract},
        license            => $rel->{license},
        spdx_expression    => $rel->{metadata}{x_spdx_expression},
        dependency         => $rel->{dependency},
        download_url       => $rel->{download_url},
        checksum           => $rel->{checksum_sha256},
        has_module_install => $files{mi},
        has_license        => $files{license},
        has_multi_licenses => $files{has_multi_licenses},
        has_xs             => $files{xs},
    );
    $self->_pdump( '%_meta', \%_meta, "\n" );

    return 0;
}

method _init_mua_mcpan ()
{
    $self->_psub;

    $_mua_mcpan = $self->_get_mua('mcpan');

    return $self;
}

# Create a Mojo::UserAgent instance.
method _get_mua ($type)
{
    return undef if $type ne 'mcpan' && $type ne 'arch';

    # Caching support
    my $has_muac = do {
        try {
            require Mojo::UserAgent::Cached;



( run in 1.679 second using v1.01-cache-2.11-cpan-6aa56a78535 )