App-cpan2arch

 view release on metacpan or  search on metacpan

lib/App/cpan2arch/MergePrereqs.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::MergePrereqs;  # For toolchain compatibility.
role App::cpan2arch::MergePrereqs;

use Scalar::Util qw< looks_like_number >;
use List::Util   qw< any >;

our $VERSION = 'v1.1.2';

field %_cpan_prereqs :reader :writer;
field @_fetch_errors :reader;
field @_prereq_dists;

# Merge CPAN prerequisites to PKGBUILD dependencies.
#
# References:
#   https://blogs.perl.org/users/neilb/2017/04/an-introduction-to-distribution-metadata.html
#   https://blogs.perl.org/users/neilb/2017/04/dependency-phases-in-cpan-distribution-metadata.html
#   https://blogs.perl.org/users/neilb/2017/04/specifying-the-type-of-your-cpan-dependencies.html
#   https://blogs.perl.org/users/neilb/2017/05/specifying-dependencies-for-your-cpan-distribution.html
#   https://neilb.org/2015/09/25/dependencies-model.html
#   https://github.com/Perl-Toolchain-Gang/toolchain-site/blob/master/cpan-packaging.md
#   https://metacpan.org/pod/CPAN::Meta::Spec#PREREQUISITES
#   https://wiki.archlinux.org/title/PKGBUILD#Dependencies
#   https://metacpan.org/pod/CPAN::Meta::Spec#Version-Ranges
#   https://man.archlinux.org/man/core/pacman/PKGBUILD.5.en#:~:text=depends%20(array
#   https://man.archlinux.org/man/alpm-package-relation.7
#   https://man.archlinux.org/man/alpm-comparison.7
method merge_prereqs ()
{
    $self->_psub;

    my %meta = $self->meta;

    %_cpan_prereqs = (
        depends      => undef,
        makedepends  => undef,
        checkdepends => undef,
        optdepends   => undef,
    );

    my $prereqs = $self->_get_dists;
    return 1 if looks_like_number($prereqs) && $prereqs == 1;
    $self->_pdump( '$prereqs', $prereqs, "\n" );

    foreach my $dep ( $prereqs->@* ) {
        my ( $module, $dist, $phase, $relationship, $version, $failed ) =
          $dep->@{ qw< module dist phase relationship version failed > };

        my $variable =
            $relationship eq 'recommends' || $relationship eq 'suggests' ? 'optdepends'
          : $phase eq 'configure' || $phase eq 'build'                   ? 'makedepends'
          : $phase eq 'runtime'                                          ? 'depends'
          : $phase eq 'test'                                             ? 'checkdepends'
          :                                                                ();

        $self->_pdump( '$module',  \$module,  '' );
        $self->_pdump( '$version', \$version, '' );

        # Version ranges are unsupported because no dist use it for its prereqs,
        # and some operators are inconsistent with PKGBUILD operators, e.g. ==, !=.
        my $is_version = do {
            try {
                version->parse($version);
            }
            catch ($e) {
                $self->_pdbg("version range is unsupported\n");
                undef;
            }
        };

        if ( !defined $is_version ) {
            $_cpan_prereqs{$variable}{$module}{dist}    = $dist if defined $dist;
            $_cpan_prereqs{$variable}{$module}{failed}  = true  if defined $failed;
            $_cpan_prereqs{$variable}{$module}{version} = 0;
        }
        # Numeric version
        else {
            # Skip duplicated distros but get the lesser version.
            if ( exists $_cpan_prereqs{$variable}{$module} ) {
                $self->_pdbg("found dupe\n");

                my $ret = $self->_comp_vers( $version, $_cpan_prereqs{$variable}{$module}{version}, '>=' );

                return 1 if defined $ret && $ret == 1;
                next     if defined $ret && $ret == 0;
            }

            $_cpan_prereqs{$variable}{$module}{dist}    = $dist if defined $dist;
            $_cpan_prereqs{$variable}{$module}{failed}  = true  if defined $failed;
            $_cpan_prereqs{$variable}{$module}{version} = $version;
        }

        $self->_pdbg("\n");
    }

    # Optionals must not exist in other variable phases.
    foreach my $opt ( keys $_cpan_prereqs{optdepends}->%* ) {
        foreach my ( $var, $deps ) (%_cpan_prereqs) {
            next if $var eq 'optdepends';

            if ( exists $_cpan_prereqs{$var}{$opt} ) {
                delete $_cpan_prereqs{optdepends}{$opt};



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