#!/usr/bin/env perl

# This chunk of stuff was generated by App::FatPacker. To find the original
# file's code, look for the end of this BEGIN block or the string 'FATPACK'
BEGIN {
my %fatpacked;

$fatpacked{"MetaCPAN/API/Tiny.pm"} = <<'METACPAN_API_TINY';
  package MetaCPAN::API::Tiny;
  {
    $MetaCPAN::API::Tiny::VERSION = '1.131730';
  }
  use strict;
  use warnings;
  # ABSTRACT: A Tiny API client for MetaCPAN

  use Carp;
  use JSON::PP 'encode_json', 'decode_json';
  use HTTP::Tiny;


  sub new {
      my ($class, @args) = @_;

      $#_ % 2 == 0
          or croak 'Arguments must be provided as name/value pairs';

      my %params = @args;

      die 'ua_args must be an array reference'
          if $params{ua_args} && ref($params{ua_args}) ne 'ARRAY';

      my $self = +{
          base_url => $params{base_url} || 'http://api.metacpan.org/v0',
          ua => $params{ua} || HTTP::Tiny->new(
              $params{ua_args}
                  ? @{$params{ua_args}}
                  : (agent => 'MetaCPAN::API::Tiny/'
                      . ($MetaCPAN::API::VERSION || 'xx'))),
      };

      return bless($self, $class);
  }

  sub _build_extra_params {
      my $self = shift;

      @_ % 2 == 0
          or croak 'Incorrect number of params, must be key/value';

      my %extra = @_;
      my $ua = $self->{ua};

      foreach my $key (keys %extra)
      {
          # The implementation in HTTP::Tiny uses + instead of %20, fix that
          $extra{$key} = $ua->_uri_escape($extra{$key});
          $extra{$key} =~ s/\+/%20/g;
      }

      my $params = join '&', map { "$_=" . $extra{$_} } sort keys %extra;

      return $params;
  }


  # /source/{author}/{release}/{path}
  sub source {
      my $self  = shift;
      my %opts  = @_ ? @_ : ();
      my $url   = '';
      my $error = "Provide 'author' and 'release' and 'path'";

      %opts or croak $error;

      if (
          defined ( my $author  = $opts{'author'}  ) &&
          defined ( my $release = $opts{'release'} ) &&
          defined ( my $path    = $opts{'path'}    )
        ) {
          $url = "source/$author/$release/$path";
      } else {
          croak $error;
      }

      $url = $self->{base_url} . "/$url";

      my $result = $self->{ua}->get($url);
      $result->{'success'}
          or croak "Failed to fetch '$url': " . $result->{'reason'};

      return $result->{'content'};
  }


  # /release/{distribution}
  # /release/{author}/{release}
  sub release {
      my $self  = shift;
      my %opts  = @_ ? @_ : ();
      my $url   = '';
      my $error = "Either provide 'distribution', or 'author' and 'release', " .
                  "or 'search'";

      %opts or croak $error;

      my %extra_opts = ();

      if ( defined ( my $dist = $opts{'distribution'} ) ) {
          $url = "release/$dist";
      } elsif (
          defined ( my $author  = $opts{'author'}  ) &&
          defined ( my $release = $opts{'release'} )
        ) {
          $url = "release/$author/$release";
      } elsif ( defined ( my $search_opts = $opts{'search'} ) ) {
          ref $search_opts && ref $search_opts eq 'HASH'
              or croak $error;

          %extra_opts = %{$search_opts};
          $url        = 'release/_search';
      } else {
          croak $error;
      }

      return $self->fetch( $url, %extra_opts );
  }


  # /pod/{module}
  # /pod/{author}/{release}/{path}
  sub pod {
      my $self  = shift;
      my %opts  = @_ ? @_ : ();
      my $url   = '';
      my $error = "Either provide 'module' or 'author and 'release' and 'path'";

      %opts or croak $error;

      if ( defined ( my $module = $opts{'module'} ) ) {
          $url = "pod/$module";
      } elsif (
          defined ( my $author  = $opts{'author'}  ) &&
          defined ( my $release = $opts{'release'} ) &&
          defined ( my $path    = $opts{'path'}    )
        ) {
          $url = "pod/$author/$release/$path";
      } else {
          croak $error;
      }

      # check content-type
      my %extra = ();
      if ( defined ( my $type = $opts{'content-type'} ) ) {
          $type =~ m{^ text/ (?: html|plain|x-pod|x-markdown ) $}x
              or croak 'Incorrect content-type provided';

          $extra{headers}{'content-type'} = $type;
      }

      $url = $self->{base_url}. "/$url";

      my $result = $self->{ua}->get( $url, \%extra );
      $result->{'success'}
          or croak "Failed to fetch '$url': " . $result->{'reason'};

      return $result->{'content'};
  }


  # /module/{module}
  sub module {
      my $self = shift;
      my $name = shift;

      $name or croak 'Please provide a module name';

      return $self->fetch("module/$name");
  }


  # file() is a synonym of module
  sub file { goto &module }


  # /author/{author}
  sub author {
      my $self = shift;
      my ( $pause_id, $url, %extra_opts );

      if ( @_ == 1 ) {
          $url = 'author/' . shift;
      } elsif ( @_ == 2 ) {
          my %opts = @_;

          if ( defined $opts{'pauseid'} ) {
              $url = "author/" . $opts{'pauseid'};
          } elsif ( defined $opts{'search'} ) {
              my $search_opts = $opts{'search'};

              ref $search_opts && ref $search_opts eq 'HASH'
                  or croak "'search' key must be hashref";

              %extra_opts = %{$search_opts};
              $url        = 'author/_search';
          } else {
              croak 'Unknown option given';
          }
      } else {
          croak 'Please provide an author PAUSEID or a "search"';
      }

      return $self->fetch( $url, %extra_opts );
  }



  sub fetch {
      my $self    = shift;
      my $url     = shift;
      my $extra   = $self->_build_extra_params(@_);
      my $base    = $self->{base_url};
      my $req_url = $extra ? "$base/$url?$extra" : "$base/$url";

      my $result  = $self->{ua}->get($req_url);
      return $self->_decode_result( $result, $req_url );
  }


  sub post {
      my $self  = shift;
      my $url   = shift;
      my $query = shift;
      my $base  = $self->{base_url};

      defined $url
          or croak 'First argument of URL must be provided';

      ref $query and ref $query eq 'HASH'
          or croak 'Second argument of query hashref must be provided';

      my $query_json = encode_json( $query );
      my $result     = $self->{ua}->request(
          'POST',
          "$base/$url",
          {
              headers => { 'Content-Type' => 'application/json' },
              content => $query_json,
          }
      );

      return $self->_decode_result( $result, $url, $query_json );
  }

  sub _decode_result {
      my $self = shift;
      my ( $result, $url, $original ) = @_;
      my $decoded_result;

      ref $result and ref $result eq 'HASH'
          or croak 'First argument must be hashref';

      defined $url
          or croak 'Second argument of a URL must be provided';

      if ( defined ( my $success = $result->{'success'} ) ) {
          my $reason = $result->{'reason'} || '';
          $reason .= ( defined $original ? " (request: $original)" : '' );

          $success or croak "Failed to fetch '$url': $reason";
      } else {
          croak 'Missing success in return value';
      }

      defined ( my $content = $result->{'content'} )
          or croak 'Missing content in return value';

      eval { $decoded_result = decode_json $content; 1 }
      or do { croak "Couldn't decode '$content': $@" };

      return $decoded_result;
  }

  1;

  __END__

  =pod

  =head1 NAME

  MetaCPAN::API::Tiny - A Tiny API client for MetaCPAN

  =head1 VERSION

  version 1.131730

  =head1 DESCRIPTION

  This is the Tiny version of L<MetaCPAN::API>. It implements a compatible API
  with a few notable exceptions:

  =over 4

  =item Attributes are direct hash access

  The attributes defined using Mo(o|u)se are now accessed via the blessed hash
  directly. There are no accessors defined to access this elements.

  =item Exception handling

  Instead of using Try::Tiny, raw evals are used. This could potentially cause
  issues, so just be aware.

  =item Testing

  Test::Fatal was replaced with an eval implementation of exception().
  Test::TinyMocker usage is retained, but may be absorbed since it is pure perl

  =back

  =head1 CLASS_METHODS

  =head2 new

  new is the constructor for MetaCPAN::API::Tiny. In the non-tiny version of this
  module, this is provided via Any::Moose built from the attributes defined. In
  the tiny version, we define our own constructor. It takes the same arguments
  and provides similar checks to MetaCPAN::API with regards to arguments passed.

  =head1 PUBLIC_METHODS

  =head2 source

      my $source = $mcpan->source(
          author  => 'DOY',
          release => 'Moose-2.0201',
          path    => 'lib/Moose.pm',
      );

  Searches MetaCPAN for a module or a specific release and returns the plain source.

  =head2 release

      my $result = $mcpan->release( distribution => 'Moose' );

      # or
      my $result = $mcpan->release( author => 'DOY', release => 'Moose-2.0001' );

  Searches MetaCPAN for a dist.

  You can do complex searches using 'search' parameter:

      # example lifted from MetaCPAN docs
      my $result = $mcpan->release(
          search => {
              author => "OALDERS AND ",
              filter => "status:latest",
              fields => "name",
              size   => 1,
          },
      );

  =head2 pod

      my $result = $mcpan->pod( module => 'Moose' );

      # or
      my $result = $mcpan->pod(
          author  => 'DOY',
          release => 'Moose-2.0201',
          path    => 'lib/Moose.pm',
      );

  Searches MetaCPAN for a module or a specific release and returns the POD.

  =head2 module

      my $result = $mcpan->module('MetaCPAN::API');

  Searches MetaCPAN and returns a module's ".pm" file.

  =head2 file

  A synonym of L</module>

  =head2 author

      my $result1 = $mcpan->author('XSAWYERX');
      my $result2 = $mcpan->author( pauseid => 'XSAWYERX' );

  Searches MetaCPAN for a specific author.

  You can do complex searches using 'search' parameter:

      # example lifted from MetaCPAN docs
      my $result = $mcpan->author(
          search => {
              q    => 'profile.name:twitter',
              size => 1,
          },
      );

  =head2 fetch

      my $result = $mcpan->fetch('/release/distribution/Moose');

      # with parameters
      my $more = $mcpan->fetch(
          '/release/distribution/Moose',
          param => 'value',
      );

  This is a helper method for API implementations. It fetches a path from MetaCPAN, decodes the JSON from the content variable and returns it.

  You don't really need to use it, but you can in case you want to write your own extension implementation to MetaCPAN::API.

  It accepts an additional hash as "GET" parameters.

  =head2 post

      # /release&content={"query":{"match_all":{}},"filter":{"prefix":{"archive":"Cache-Cache-1.06"}}}
      my $result = $mcpan->post(
          'release',
          {
              query  => { match_all => {} },
              filter => { prefix => { archive => 'Cache-Cache-1.06' } },
          },
      );

  The POST equivalent of the "fetch()" method. It gets the path and JSON request.

  =head1 THANKS

  Overall the tests and code were ripped directly from MetaCPAN::API and
  tiny-fied. A big thanks to Sawyer X for writing the original module.

  =head1 AUTHOR

  Nicholas R. Perez <nperez@cpan.org>

  =head1 COPYRIGHT AND LICENSE

  This software is copyright (c) 2013 by Nicholas R. Perez <nperez@cpan.org>.

  This is free software; you can redistribute it and/or modify it under
  the same terms as the Perl 5 programming language system itself.

  =cut
METACPAN_API_TINY

s/^  //mg for values %fatpacked;

unshift @INC, sub {
  if (my $fat = $fatpacked{$_[1]}) {
    if ($] < 5.008) {
      return sub {
        return 0 unless length $fat;
        $fat =~ s/^([^\n]*\n?)//;
        $_ = $1;
        return 1;
      };
    }
    open my $fh, '<', \$fat
      or die "FatPacker error loading $_[1] (could be a perl installation issue?)";
    return $fh;
  }
  return
};

} # END OF FATPACK CODE


use 5.010;
use strict;
use warnings;
use Fatal qw(open close);

use Getopt::Long;
use Pod::Usage;
use File::Basename;
use Module::CoreList;
use HTTP::Tiny;
use Safe;
use MetaCPAN::API::Tiny;

# Below, 5.024 should be aligned with the version of perl actually
# bundled in Buildroot:
die <<"MSG" if $] < 5.024;
This script needs a host perl with the same major version as Buildroot target perl.

Your current host perl is:
    $^X
    version $]

You may install a local one by running:
    perlbrew install perl-5.24.0
MSG

my ($help, $man, $quiet, $force, $recommend, $test, $host);
my $target = 1;
GetOptions( 'help|?' => \$help,
            'man' => \$man,
            'quiet|q' => \$quiet,
            'force|f' => \$force,
            'host!' => \$host,
            'target!' => \$target,
            'recommend' => \$recommend,
            'test' => \$test
) or pod2usage(-exitval => 1);
pod2usage(-exitval => 0) if $help;
pod2usage(-exitval => 0, -verbose => 2) if $man;
pod2usage(-exitval => 1) if scalar @ARGV == 0;

my %dist;               # name -> metacpan data
my %need_target;        # name -> 1 if target package is needed
my %need_host;          # name -> 1 if host package is needed
my %need_dlopen;        # name -> 1 if requires dynamic library
my %deps_build;         # name -> list of host dependencies
my %deps_runtime;       # name -> list of target dependencies
my %deps_optional;      # name -> list of optional target dependencies
my %license_files;      # name -> list of license files
my %checksum;           # author -> list of checksum
my $mcpan = MetaCPAN::API::Tiny->new(base_url => 'http://fastapi.metacpan.org/v1');
my $ua = HTTP::Tiny->new();

sub get_checksum {
    my ($url) = @_;
    my($path) = $url =~ m|^[^:/?#]+://[^/?#]*([^?#]*)|;
    my($basename, $dirname) = fileparse( $path );
    unless ($checksum{$dirname}) {
        my $response = $ua->get(qq{http://cpan.metacpan.org${dirname}CHECKSUMS});
        $checksum{$dirname} = $response->{content};
    }
    my $chksum = Safe->new->reval($checksum{$dirname});
    return $chksum->{$basename}, $basename;
}

sub get_manifest {
    my ($author, $distname, $version) = @_;
    my $url = qq{http://fastapi.metacpan.org/source/${author}/${distname}-${version}/MANIFEST};
    my $response = $ua->get($url);
    return $response->{content};
}

sub is_xs {
    my ($manifest) = @_;
    # This heuristic determines if a module is a native extension, by searching
    # some file extension types in the MANIFEST of the distribution.
    # It was inspired by http://deps.cpantesters.org/static/purity.html
    return $manifest =~ m/\.(swg|xs|c|h|i)[\n\s]/;
}

sub find_license_files {
    my ($manifest) = @_;
    my @license_files;
    foreach (split /\n/, $manifest) {
        next if m|/|;
        push @license_files, $_ if m/(ARTISTIC|COPYING|COPYRIGHT|LICENSE)/i;
    }
    if (scalar @license_files == 0 && $manifest =~ m/(README)[\n\s]/i) {
        @license_files = ($1);
    }
    return \@license_files;
}

sub fetch {
    my ($name, $need_target, $need_host, $top) = @_;
    $need_target{$name} = $need_target if $need_target;
    $need_host{$name} = $need_host if $need_host;
    unless ($dist{$name} && !$top) {
        say qq{fetch ${name}} unless $quiet;
        my $result = $mcpan->release( distribution => $name );
        $dist{$name} = $result;
        my $manifest = get_manifest( $result->{author}, $name, $result->{version} );
        $need_dlopen{$name} = is_xs( $manifest );
        $license_files{$name} = find_license_files( $manifest );
        my %build = ();
        my %runtime = ();
        my %optional = ();
        foreach my $dep (@{$result->{dependency}}) {
            my $modname = ${$dep}{module};
            next if $modname eq q{perl};
            next if $modname =~ m|^Alien|;
            next if $modname =~ m|^Win32|;
            next if !($test && $top) && $modname =~ m|^Test|;
            next if Module::CoreList::is_core( $modname, undef, $] );
            # we could use the host Module::CoreList data, because host perl and
            # target perl have the same major version
            next if ${$dep}{phase} eq q{develop};
            next if !($test && $top) && ${$dep}{phase} eq q{test};
            my $distname = $mcpan->module( $modname )->{distribution};
            if (${$dep}{phase} eq q{runtime}) {
                if (${$dep}{relationship} eq q{requires}) {
                    $runtime{$distname} = 1;
                }
                else {
                    $optional{$distname} = 1 if $recommend && $top;
                }
            }
            else { # configure, build
                $build{$distname} = 1;
            }
        }
        $deps_build{$name} = [keys %build];
        $deps_runtime{$name} = [keys %runtime];
        $deps_optional{$name} = [keys %optional];
        foreach my $distname (@{$deps_build{$name}}) {
            fetch( $distname, 0, 1 );
        }
        foreach my $distname (@{$deps_runtime{$name}}) {
            fetch( $distname, $need_target, $need_host );
            $need_dlopen{$name} ||= $need_dlopen{$distname};
        }
        foreach my $distname (@{$deps_optional{$name}}) {
            fetch( $distname, $need_target, $need_host );
        }
    }
    return;
}

foreach my $distname (@ARGV) {
    # Command-line's distributions
    fetch( $distname, !!$target, !!$host, 1 );
}
say scalar keys %dist, q{ packages fetched.} unless $quiet;

# Buildroot package name: lowercase
sub fsname {
    my $name = shift;
    $name =~ s|_|-|g;
    return q{perl-} . lc $name;
}

# Buildroot variable name: uppercase
sub brname {
    my $name = shift;
    $name =~ s|-|_|g;
    return uc $name;
}

while (my ($distname, $dist) = each %dist) {
    my $fsname = fsname( $distname );
    my $dirname = q{package/} . $fsname;
    my $cfgname = $dirname . q{/Config.in};
    my $mkname = $dirname . q{/} . $fsname . q{.mk};
    my $hashname = $dirname . q{/} . $fsname . q{.hash};
    my $brname = brname( $fsname );
    mkdir $dirname unless -d $dirname;
    if ($need_target{$distname} && ($force || !-f $cfgname)) {
        my $abstract = $dist->{abstract};
        my $homepage = $dist->{resources}->{homepage} || qq{https://metacpan.org/release/${distname}};
        say qq{write ${cfgname}} unless $quiet;
        open my $fh, q{>}, $cfgname;
        say {$fh} qq{config BR2_PACKAGE_${brname}};
        say {$fh} qq{\tbool "${fsname}"};
        say {$fh} qq{\tdepends on !BR2_STATIC_LIBS} if $need_dlopen{$distname};
        foreach my $dep (sort @{$deps_runtime{$distname}}) {
            my $brdep = brname( fsname( $dep ) );
            say {$fh} qq{\tselect BR2_PACKAGE_${brdep}};
        }
        say {$fh} qq{\thelp};
        say {$fh} qq{\t  ${abstract}\n} if $abstract;
        say {$fh} qq{\t  ${homepage}};
        if ($need_dlopen{$distname}) {
            say {$fh} qq{\ncomment "${fsname} needs a toolchain w/ dynamic library"};
            say {$fh} qq{\tdepends on BR2_STATIC_LIBS};
        }
        close $fh;
    }
    if ($force || !-f $mkname) {
        my $version = $dist->{version};
        my($path) = $dist->{download_url} =~ m|^[^:/?#]+://[^/?#]*([^?#]*)|;
        # this URL contains only the scheme, auth and path parts (but no query and fragment parts)
        # the scheme is not used, because the job is done by the BR download infrastructure
        # the auth part is not used, because we use $(BR2_CPAN_MIRROR)
        my($filename, $directories, $suffix) = fileparse( $path, q{tar.gz}, q{tgz} );
        $directories =~ s|/$||;
        my $dependencies = join q{ }, map( { q{host-} . fsname( $_ ); } sort @{$deps_build{$distname}} ),
                                      map( { fsname( $_ ); } sort @{$deps_runtime{$distname}} );
        my $host_dependencies = join q{ }, map { q{host-} . fsname( $_ ); } sort( @{$deps_build{$distname}},
                                                                                  @{$deps_runtime{$distname}} );
        my $license = ref $dist->{license} eq 'ARRAY'
                    ? join q{ or }, @{$dist->{license}}
                    : $dist->{license};
        # BR requires license name as in http://spdx.org/licenses/
        $license =~ s|apache_2_0|Apache-2.0|;
        $license =~ s|artistic_2|Artistic-2.0|;
        $license =~ s|mit|MIT|;
        $license =~ s|openssl|OpenSSL|;
        $license =~ s|perl_5|Artistic or GPLv1+|;
        my $license_files = join q{ }, @{$license_files{$distname}};
        say qq{write ${mkname}} unless $quiet;
        open my $fh, q{>}, $mkname;
        say {$fh} qq{################################################################################};
        say {$fh} qq{#};
        say {$fh} qq{# ${fsname}};
        say {$fh} qq{#};
        say {$fh} qq{################################################################################};
        say {$fh} qq{};
        say {$fh} qq{${brname}_VERSION = ${version}};
        say {$fh} qq{${brname}_SOURCE = ${distname}-\$(${brname}_VERSION).${suffix}};
        say {$fh} qq{${brname}_SITE = \$(BR2_CPAN_MIRROR)${directories}};
        say {$fh} qq{${brname}_DEPENDENCIES = ${dependencies}} if $need_target{$distname} && $dependencies;
        say {$fh} qq{HOST_${brname}_DEPENDENCIES = ${host_dependencies}} if $need_host{$distname} && $host_dependencies;
        say {$fh} qq{${brname}_LICENSE = ${license}} if $license && $license ne q{unknown};
        say {$fh} qq{${brname}_LICENSE_FILES = ${license_files}} if $license_files;
        say {$fh} qq{};
        foreach (sort @{$deps_optional{$distname}}) {
            next if grep { $_ eq $distname; } @{$deps_runtime{$_}};     # avoid cyclic dependencies
            my $opt_brname = brname( $_ );
            my $opt_fsname = fsname( $_ );
            say {$fh} qq{ifeq (\$(BR2_PACKAGE_PERL_${opt_brname}),y)};
            say {$fh} qq{${brname}_DEPENDENCIES += ${opt_fsname}};
            say {$fh} qq{endif};
            say {$fh} qq{};
        }
        say {$fh} qq{\$(eval \$(perl-package))} if $need_target{$distname};
        say {$fh} qq{\$(eval \$(host-perl-package))} if $need_host{$distname};
        close $fh;
    }
    if ($force || !-f $hashname) {
        my($checksum, $filename) = get_checksum($dist->{download_url});
        my $md5 = $checksum->{md5};
        my $sha256 = $checksum->{sha256};
        say qq{write ${hashname}} unless $quiet;
        open my $fh, q{>}, $hashname;
        say {$fh} qq{# retrieved by scancpan from http://cpan.metacpan.org/};
        say {$fh} qq{md5    ${md5} ${filename}};
        say {$fh} qq{sha256 ${sha256} ${filename}};
        close $fh;
    }
}

my %pkg;
my $cfgname = q{package/Config.in};
if (-f $cfgname) {
    open my $fh, q{<}, $cfgname;
    while (<$fh>) {
        chomp;
        $pkg{$_} = 1 if m|package/perl-|;
    }
    close $fh;
}

foreach my $distname (keys %need_target) {
    my $fsname = fsname( $distname );
    $pkg{qq{\tsource "package/${fsname}/Config.in"}} = 1;
}

say qq{${cfgname} must contain the following lines:};
say join qq{\n}, sort keys %pkg;

__END__

=head1 NAME

support/scripts/scancpan Try-Tiny Moo

=head1 SYNOPSIS

supports/scripts/scancpan [options] [distname ...]

 Options:
   -help
   -man
   -quiet
   -force
   -target/-notarget
   -host/-nohost
   -recommend
   -test

=head1 OPTIONS

=over 8

=item B<-help>

Prints a brief help message and exits.

=item B<-man>

Prints the manual page and exits.

=item B<-quiet>

Executes without output

=item B<-force>

Forces the overwriting of existing files.

=item B<-target/-notarget>

Switches package generation for the target variant (the default is C<-target>).

=item B<-host/-nohost>

Switches package generation for the host variant (the default is C<-nohost>).

=item B<-recommend>

Adds I<recommended> dependencies.

=item B<-test>

Adds dependencies for test.

=back

=head1 DESCRIPTION

This script creates templates of the Buildroot package files for all the
Perl/CPAN distributions required by the specified distnames. The
dependencies and metadata are fetched from https://metacpan.org/.

After running this script, it is necessary to check the generated files.
You have to manually add the license files (PERL_FOO_LICENSE_FILES variable).
For distributions that link against a target library, you have to add the
buildroot package name for that library to the DEPENDENCIES variable.

See the Buildroot documentation for details on the usage of the Perl
infrastructure.

The major version of the host perl must be aligned on the target one,
in order to work with the right CoreList data.

=head1 LICENSE

Copyright (C) 2013-2016 by Francois Perrad <francois.perrad@gadz.org>

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

This script is a part of Buildroot.

This script requires the module C<MetaCPAN::API::Tiny> (version 1.131730)
which was included at the beginning of this file by the tool C<fatpack>.

See L<http://search.cpan.org/~nperez/MetaCPAN-API-Tiny-1.131730/>.

See L<http://search.cpan.org/search?query=App-FatPacker&mode=dist>.

These both libraries are free software and may be distributed under the same
terms as perl itself.

And perl may be distributed under the terms of Artistic v1 or GPL v1 license.

=cut
