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 )