App-cpan2arch

 view release on metacpan or  search on metacpan

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


            # No need to fetch perl interpreter dist.
            if ( $dep->{module} eq 'perl' ) {
                $dep->{dist} = 'perl';
                push @ignored, $dep;

                next;
            }

            push @prereqs, $dep;
        }

        $self->_pdump( '@prereqs', \@prereqs, "\n" );
        $self->_pdump( '@ignored', \@ignored, "\n" );
    }

    # Fetch dists.
    {
        $self->_fetch(@prereqs) if scalar @prereqs;

        $self->_pdbg("\n");
        $self->_pdump( '@_prereq_dists', \@_prereq_dists, "\n" );

        if ( scalar @_fetch_errors ) {
            warn "$prog: failed to fetch distributions\n";
            $self->_pdump( '@_fetch_errors', \@_fetch_errors, "\n" );

            return 1;
        }
    }

    # Include the dists.
    {
        foreach my ( $idx, $dep ) ( indexed @prereqs ) {
            my $dist = $_prereq_dists[$idx];
            my $type = reftype $dist;

            if ( defined $type && $type eq 'HASH' && exists $dist->{failed} ) {
                $dep->{failed} = true;
                next;
            }

            $dep->{dist} = $dist;
        }

        push @prereqs, @ignored;
    }

    return \@prereqs;
}

# Fetch all modules distributions concurrently.
method _fetch (@prereqs)
{
    $self->_psub;

    require Mojo::Promise;

    my $prog      = $self->prog;
    my $mua_mcpan = $self->mua_mcpan;
    my %endpoints = $self->endpoints;

    my %env = $self->env;
    local $ENV{MUAC_NOCACHE} = true if $env{cache_ignore};

    # Fetch three dists at a time using the download_url endpoint.
    #
    # References:
    #   https://github.com/metacpan/metacpan-api/blob/master/docs/API-docs.md#download_urlmodule.
    #   https://metacpan.org/release/MIYAGAWA/App-cpanminus-1.7049/source/lib/App/cpanminus/fatscript.pm#L926
    #   https://github.com/metacpan/MetaCPAN-Client/blob/396ba371317f114db04967c90be64bb46fd7fd2c/lib/MetaCPAN/Client.pm#L217
    return Mojo::Promise->map(
        { concurrency => 3 },
        sub ($prereq) {
            my $module  = $prereq->{module};
            my $version = $prereq->{version};
            my $url     = $endpoints{download} . $module;
            my $query;

            $query  = 'version=' . $version if $version;       # Ignore 0 versions.
            $url   .= '?' . $query          if defined $query;

            $mua_mcpan->get_p($url);
        },
        @prereqs,
      )
      ->then(
          sub (@promises) {
              foreach my $tx (@promises) {
                  my $res = $tx->[0]->result;

                  if ( $res->is_success ) {
                      my $json = $res->json;
                      push @_prereq_dists, $json->{distribution};
                  }
                  # Do not exit but flag if MetaCPAN API fails to fetch a module,
                  # to avoid PKGBUILD not being generated when upstream metadata
                  # has wrong module name.
                  else {
                      my $req = $tx->[0]->req;
                      my $url = $req->url;
                      my $mod = $url->path->parts->[-1];
                      my $ver = $url->query->param('version');
                      my $msg = $res->message;

                      my $err = "$prog: failed to fetch $mod module";
                      $err .= " (query version: $ver)" if defined $ver;

                      warn "Failed to fetch '$url': $msg";
                      warn "$err\n";

                      push @_prereq_dists, {
                          failed  => true,
                          version => $ver,
                      };
                  }
              }
          }
      )
      ->catch(
          sub ($e) {
              warn $e;
              push @_fetch_errors, $e;
          }
      )->wait;
}

=encoding UTF-8

=for highlighter language=perl

=head1 NAME

App::cpan2arch::MergePrereqs - merge CPAN prerequisites to PKGBUILD dependencies

=head1 SYNOPSIS



( run in 1.416 second using v1.01-cache-2.11-cpan-2e0ccfb7a10 )