aboutsummaryrefslogtreecommitdiffstats
path: root/perl-external
diff options
context:
space:
mode:
Diffstat (limited to 'perl-external')
-rw-r--r--perl-external/.gitignore1
-rwxr-xr-xperl-external/bin/cpanm5748
-rwxr-xr-xperl-external/bin/module-manage.pl265
-rw-r--r--perl-external/files.txt261
-rw-r--r--perl-external/lib/perl5/local/lib.pm1030
-rw-r--r--perl-external/minicpan/.gitignore3
-rw-r--r--perl-external/minicpan/modules/02packages.details.txt.gzbin20439 -> 0 bytes
-rw-r--r--perl-external/minicpan/modules/03modlist.data.gzbin222 -> 0 bytes
-rw-r--r--perl-external/modules.txt62
9 files changed, 0 insertions, 7370 deletions
diff --git a/perl-external/.gitignore b/perl-external/.gitignore
deleted file mode 100644
index 8db64e38e..000000000
--- a/perl-external/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-local-lib
diff --git a/perl-external/bin/cpanm b/perl-external/bin/cpanm
deleted file mode 100755
index 9aeb9c906..000000000
--- a/perl-external/bin/cpanm
+++ /dev/null
@@ -1,5748 +0,0 @@
-#!/usr/bin/env perl
-
-eval 'exec /usr/bin/env perl -S $0 ${1+"$@"}'
- if 0; # not running under some shell
-#
-# You want to install cpanminus? Run the following command and it will
-# install itself for you. You might want to run it as a root with sudo
-# if you want to install to places like /usr/local/bin.
-#
-# % curl -L http://cpanmin.us | perl - --self-upgrade
-#
-# If you don't have curl but wget, replace `curl -L` with `wget -O -`.
-#
-# For more details about this program, visit http://search.cpan.org/dist/App-cpanminus
-#
-# DO NOT EDIT -- this is an auto generated file
-# 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{"App/cpanminus.pm"} = <<'APP_CPANMINUS';
- package App::cpanminus;
- our $VERSION = "1.4007";
-
- =head1 NAME
-
- App::cpanminus - get, unpack, build and install modules from CPAN
-
- =head1 SYNOPSIS
-
- cpanm Module
-
- Run C<cpanm -h> for more options.
-
- =head1 DESCRIPTION
-
- cpanminus is a script to get, unpack, build and install modules from
- CPAN and does nothing else.
-
- It's dependency free (can bootstrap itself), requires zero
- configuration, and stands alone. When running, it requires only 10MB
- of RAM.
-
- =head1 INSTALLATION
-
- There are several ways to install cpanminus to your system.
-
- =head2 Package management system
-
- There are Debian packages, RPMs, FreeBSD ports, and packages for other
- operation systems available. If you want to use the package management system,
- search for cpanminus and use the appropriate command to install. This makes it
- easy to install C<cpanm> to your system without thinking about where to
- install, and later upgrade.
-
- =head2 Installing to system perl
-
- You can also use the latest cpanminus to install cpanminus itself:
-
- curl -L http://cpanmin.us | perl - --sudo App::cpanminus
-
- This will install C<cpanm> to your bin directory like
- C</usr/local/bin> (unless you configured C<INSTALL_BASE> with
- L<local::lib>), so you probably need the C<--sudo> option.
-
- =head2 Installing to local perl (perlbrew)
-
- If you have perl in your home directory, which is the case if you use
- tools like L<perlbrew>, you don't need the C<--sudo> option, since
- you're most likely to have a write permission to the perl's library
- path. You can just do:
-
- curl -L http://cpanmin.us | perl - App::cpanminus
-
- to install the C<cpanm> executable to the perl's bin path, like
- C<~/perl5/perlbrew/bin/cpanm>.
-
- =head2 Downloading the standalone executable
-
- You can also copy the standalone executable to whatever location you'd like.
-
- cd ~/bin
- curl -LO http://xrl.us/cpanm
- chmod +x cpanm
- # edit shebang if you don't have /usr/bin/env
-
- This just works, but be sure to grab the new version manually when you
- upgrade because C<--self-upgrade> might not work for this.
-
- =head1 DEPENDENCIES
-
- perl 5.8 or later.
-
- =over 4
-
- =item *
-
- 'tar' executable (bsdtar or GNU tar version 1.22 are rcommended) or Archive::Tar to unpack files.
-
- =item *
-
- C compiler, if you want to build XS modules.
-
- =item *
-
- make
-
- =item *
-
- Module::Build (core in 5.10)
-
- =back
-
- =head1 QUESTIONS
-
- =head2 Another CPAN installer?
-
- OK, the first motivation was this: the CPAN shell runs out of memory (or swaps
- heavily and gets really slow) on Slicehost/linode's most affordable plan with
- only 256MB RAM. Should I pay more to install perl modules from CPAN? I don't
- think so.
-
- =head2 But why a new client?
-
- First of all, let me be clear that CPAN and CPANPLUS are great tools
- I've used for I<literally> years (you know how many modules I have on
- CPAN, right?). I really respect their efforts of maintaining the most
- important tools in the CPAN toolchain ecosystem.
-
- However, for less experienced users (mostly from outside the Perl community),
- or even really experienced Perl developers who know how to shoot themselves in
- their feet, setting up the CPAN toolchain often feels like yak shaving,
- especially when all they want to do is just install some modules and start
- writing code.
-
- =head2 Zero-conf? How does this module get/parse/update the CPAN index?
-
- It queries the CPAN Meta DB site running on Google AppEngine at
- L<http://cpanmetadb.appspot.com/>. The site is updated every hour to reflect
- the latest changes from fast syncing mirrors. The script then also falls back
- to scrape the site L<http://search.cpan.org/>.
-
- Fetched files are unpacked in C<~/.cpanm> and automatically cleaned up
- periodically. You can configure the location of this with the
- C<PERL_CPANM_HOME> environment variable.
-
- =head2 Where does this install modules to? Do I need root access?
-
- It installs to wherever ExtUtils::MakeMaker and Module::Build are
- configured to (via C<PERL_MM_OPT> and C<PERL_MB_OPT>). So if you're
- using local::lib, then it installs to your local perl5
- directory. Otherwise it installs to the site_perl directory that
- belongs to your perl.
-
- cpanminus at a boot time checks whether you have configured
- local::lib, or have the permission to install modules to the site_perl
- directory. If neither, it automatically sets up local::lib compatible
- installation path in a C<perl5> directory under your home
- directory. To avoid this, run the script as the root user, with
- C<--sudo> option or with C<--local-lib> option.
-
- =head2 cpanminus can't install the module XYZ. Is it a bug?
-
- It is more likely a problem with the distribution itself. cpanminus
- doesn't support or is known to have issues with distributions like as
- follows:
-
- =over 4
-
- =item *
-
- Tests that require input from STDIN.
-
- =item *
-
- Tests that might fail when C<AUTOMATED_TESTING> is enabled.
-
- =item *
-
- Modules that have invalid numeric values as VERSION (such as C<1.1a>)
-
- =back
-
- These failures can be reported back to the author of the module so
- that they can fix it accordingly, rather than me.
-
- =head2 Does cpanm support the feature XYZ of L<CPAN> and L<CPANPLUS>?
-
- Most likely not. Here are the things that cpanm doesn't do by
- itself. And it's a feature - you got that from the name I<minus>,
- right?
-
- If you need these features, use L<CPAN>, L<CPANPLUS> or the standalone
- tools that are mentioned.
-
- =over 4
-
- =item *
-
- Bundle:: module dependencies
-
- =item *
-
- CPAN testers reporting
-
- =item *
-
- Building RPM packages from CPAN modules
-
- =item *
-
- Listing the outdated modules that needs upgrading. See L<cpan-outdated>
-
- =item *
-
- Uninstalling modules. See L<pm-uninstall>.
-
- =item *
-
- Showing the changes of the modules you're about to upgrade. See L<cpan-listchanges>
-
- =item *
-
- Patching CPAN modules with distroprefs.
-
- =back
-
- See L<cpanm> or C<cpanm -h> to see what cpanminus I<can> do :)
-
- =head1 COPYRIGHT
-
- Copyright 2010- Tatsuhiko Miyagawa
-
- The standalone executable contains the following modules embedded.
-
- =over 4
-
- =item L<CPAN::DistnameInfo> Copyright 2003 Graham Barr
-
- =item L<Parse::CPAN::Meta> Copyright 2006-2009 Adam Kennedy
-
- =item L<local::lib> Copyright 2007-2009 Matt S Trout
-
- =item L<HTTP::Tiny> Copyright 2011 Christian Hansen
-
- =item L<Module::Metadata> Copyright 2001-2006 Ken Williams. 2010 Matt S Trout
-
- =item L<version> Copyright 2004-2010 John Peacock
-
- =back
-
- =head1 LICENSE
-
- Same as Perl.
-
- =head1 CREDITS
-
- =head2 CONTRIBUTORS
-
- Patches and code improvements were contributed by:
-
- Goro Fuji, Kazuhiro Osawa, Tokuhiro Matsuno, Kenichi Ishigaki, Ian
- Wells, Pedro Melo, Masayoshi Sekimura, Matt S Trout, squeeky, horus
- and Ingy dot Net.
-
- =head2 ACKNOWLEDGEMENTS
-
- Bug reports, suggestions and feedbacks were sent by, or general
- acknowledgement goes to:
-
- Jesse Vincent, David Golden, Andreas Koenig, Jos Boumans, Chris
- Williams, Adam Kennedy, Audrey Tang, J. Shirley, Chris Prather, Jesse
- Luehrs, Marcus Ramberg, Shawn M Moore, chocolateboy, Chirs Nehren,
- Jonathan Rockway, Leon Brocard, Simon Elliott, Ricardo Signes, AEvar
- Arnfjord Bjarmason, Eric Wilhelm, Florian Ragwitz and xaicron.
-
- =head1 COMMUNITY
-
- =over 4
-
- =item L<http://github.com/miyagawa/cpanminus> - source code repository, issue tracker
-
- =item L<irc://irc.perl.org/#toolchain> - discussions about Perl toolchain. I'm there.
-
- =back
-
- =head1 NO WARRANTY
-
- This software is provided "as-is," without any express or implied
- warranty. In no event shall the author be held liable for any damages
- arising from the use of the software.
-
- =head1 SEE ALSO
-
- L<CPAN> L<CPANPLUS> L<pip>
-
- =cut
-
- 1;
-APP_CPANMINUS
-
-$fatpacked{"App/cpanminus/script.pm"} = <<'APP_CPANMINUS_SCRIPT';
- package App::cpanminus::script;
- use strict;
- use Config;
- use Cwd ();
- use File::Basename ();
- use File::Find ();
- use File::Path ();
- use File::Spec ();
- use File::Copy ();
- use Getopt::Long ();
- use Parse::CPAN::Meta;
- use Symbol ();
-
- use constant WIN32 => $^O eq 'MSWin32';
- use constant SUNOS => $^O eq 'solaris';
-
- our $VERSION = "1.4007";
-
- my $quote = WIN32 ? q/"/ : q/'/;
-
- sub new {
- my $class = shift;
-
- bless {
- home => "$ENV{HOME}/.cpanm",
- cmd => 'install',
- seen => {},
- notest => undef,
- installdeps => undef,
- force => undef,
- sudo => undef,
- make => undef,
- verbose => undef,
- quiet => undef,
- interactive => undef,
- log => undef,
- mirrors => [],
- mirror_only => undef,
- perl => $^X,
- argv => [],
- local_lib => undef,
- self_contained => undef,
- prompt_timeout => 0,
- prompt => undef,
- configure_timeout => 60,
- try_lwp => 1,
- try_wget => 1,
- try_curl => 1,
- uninstall_shadows => ($] < 5.012),
- skip_installed => 1,
- auto_cleanup => 7, # days
- pod2man => 1,
- installed_dists => 0,
- scandeps => 0,
- scandeps_tree => [],
- format => 'tree',
- save_dists => undef,
- @_,
- }, $class;
- }
-
- sub env {
- my($self, $key) = @_;
- $ENV{"PERL_CPANM_" . $key};
- }
-
- sub parse_options {
- my $self = shift;
-
- local @ARGV = @{$self->{argv}};
- push @ARGV, split /\s+/, $self->env('OPT');
- push @ARGV, @_;
-
- Getopt::Long::Configure("bundling");
- Getopt::Long::GetOptions(
- 'f|force' => sub { $self->{skip_installed} = 0; $self->{force} = 1 },
- 'n|notest!' => \$self->{notest},
- 'S|sudo!' => \$self->{sudo},
- 'v|verbose' => sub { $self->{verbose} = $self->{interactive} = 1 },
- 'q|quiet' => \$self->{quiet},
- 'h|help' => sub { $self->{action} = 'show_help' },
- 'V|version' => sub { $self->{action} = 'show_version' },
- 'perl=s' => \$self->{perl},
- 'l|local-lib=s' => sub { $self->{local_lib} = $self->maybe_abs($_[1]) },
- 'L|local-lib-contained=s' => sub {
- $self->{local_lib} = $self->maybe_abs($_[1]);
- $self->{self_contained} = 1;
- $self->{pod2man} = undef;
- },
- 'mirror=s@' => $self->{mirrors},
- 'mirror-only!' => \$self->{mirror_only},
- 'prompt!' => \$self->{prompt},
- 'installdeps' => \$self->{installdeps},
- 'skip-installed!' => \$self->{skip_installed},
- 'reinstall' => sub { $self->{skip_installed} = 0 },
- 'interactive!' => \$self->{interactive},
- 'i|install' => sub { $self->{cmd} = 'install' },
- 'info' => sub { $self->{cmd} = 'info' },
- 'look' => sub { $self->{cmd} = 'look'; $self->{skip_installed} = 0 },
- 'self-upgrade' => sub { $self->{cmd} = 'install'; $self->{skip_installed} = 1; push @ARGV, 'App::cpanminus' },
- 'uninst-shadows!' => \$self->{uninstall_shadows},
- 'lwp!' => \$self->{try_lwp},
- 'wget!' => \$self->{try_wget},
- 'curl!' => \$self->{try_curl},
- 'auto-cleanup=s' => \$self->{auto_cleanup},
- 'man-pages!' => \$self->{pod2man},
- 'scandeps' => \$self->{scandeps},
- 'format=s' => \$self->{format},
- 'save-dists=s' => sub {
- $self->{save_dists} = $self->maybe_abs($_[1]);
- },
- );
-
- if (!@ARGV && $0 ne '-' && !-t STDIN){ # e.g. # cpanm < author/requires.cpanm
- push @ARGV, $self->load_argv_from_fh(\*STDIN);
- $self->{load_from_stdin} = 1;
- }
-
- $self->{argv} = \@ARGV;
- }
-
- sub check_libs {
- my $self = shift;
- return if $self->{_checked}++;
-
- $self->bootstrap_local_lib;
- if (@{$self->{bootstrap_deps} || []}) {
- local $self->{notest} = 1; # test failure in bootstrap should be tolerated
- local $self->{scandeps} = 0;
- $self->install_deps(Cwd::cwd, 0, @{$self->{bootstrap_deps}});
- }
- }
-
- sub doit {
- my $self = shift;
-
- $self->setup_home;
- $self->init_tools;
-
- if (my $action = $self->{action}) {
- $self->$action() and return 1;
- }
-
- $self->show_help(1)
- unless @{$self->{argv}} or $self->{load_from_stdin};
-
- $self->configure_mirrors;
-
- my @fail;
- for my $module (@{$self->{argv}}) {
- if ($module =~ s/\.pm$//i) {
- my ($volume, $dirs, $file) = File::Spec->splitpath($module);
- $module = join '::', grep { $_ } File::Spec->splitdir($dirs), $file;
- }
- $self->install_module($module, 0)
- or push @fail, $module;
- }
-
- if ($self->{base} && $self->{auto_cleanup}) {
- $self->cleanup_workdirs;
- }
-
- if ($self->{installed_dists}) {
- my $dists = $self->{installed_dists} > 1 ? "distributions" : "distribution";
- $self->diag("$self->{installed_dists} $dists installed\n", 1);
- }
-
- if ($self->{scandeps}) {
- $self->dump_scandeps();
- }
-
- return !@fail;
- }
-
- sub setup_home {
- my $self = shift;
-
- $self->{home} = $self->env('HOME') if $self->env('HOME');
-
- unless (_writable($self->{home})) {
- die "Can't write to cpanm home '$self->{home}': You should fix it with chown/chmod first.\n";
- }
-
- $self->{base} = "$self->{home}/work/" . time . ".$$";
- File::Path::mkpath([ $self->{base} ], 0, 0777);
-
- my $link = "$self->{home}/latest-build";
- eval { unlink $link; symlink $self->{base}, $link };
-
- $self->{log} = File::Spec->catfile($self->{home}, "build.log"); # because we use shell redirect
-
- {
- my $log = $self->{log}; my $base = $self->{base};
- $self->{at_exit} = sub {
- my $self = shift;
- File::Copy::copy($self->{log}, "$self->{base}/build.log");
- };
- }
-
- { open my $out, ">$self->{log}" or die "$self->{log}: $!" }
-
- $self->chat("cpanm (App::cpanminus) $VERSION on perl $] built for $Config{archname}\n" .
- "Work directory is $self->{base}\n");
- }
-
- sub fetch_meta_sco {
- my($self, $dist) = @_;
- return if $self->{mirror_only};
-
- my $meta_yml = $self->get("http://search.cpan.org/meta/$dist->{distvname}/META.yml");
- return $self->parse_meta_string($meta_yml);
- }
-
- sub package_index_for {
- my ($self, $mirror) = @_;
- return $self->source_for($mirror) . "/02packages.details.txt";
- }
-
- sub generate_mirror_index {
- my ($self, $mirror) = @_;
- my $file = $self->package_index_for($mirror);
- my $gz_file = $file . '.gz';
- my $index_mtime = (stat $gz_file)[9];
-
- unless (-e $file && (stat $file)[9] >= $index_mtime) {
- $self->chat("Uncompressing index file...\n");
- if (eval {require Compress::Zlib}) {
- my $gz = Compress::Zlib::gzopen($gz_file, "rb")
- or do { $self->diag_fail("$Compress::Zlib::gzerrno opening compressed index"); return};
- open my $fh, '>', $file
- or do { $self->diag_fail("$! opening uncompressed index for write"); return };
- my $buffer;
- while (my $status = $gz->gzread($buffer)) {
- if ($status < 0) {
- $self->diag_fail($gz->gzerror . " reading compressed index");
- return;
- }
- print $fh $buffer;
- }
- } else {
- if (system("gunzip -c $gz_file > $file")) {
- $self->diag_fail("Cannot uncompress -- please install gunzip or Compress::Zlib");
- return;
- }
- }
- utime $index_mtime, $index_mtime, $file;
- }
- return 1;
- }
-
- sub search_mirror_index {
- my ($self, $mirror, $module) = @_;
-
- open my $fh, '<', $self->package_index_for($mirror) or return;
- while (<$fh>) {
- if (m!^\Q$module\E\s+([\w\.]+)\s+(.*)!m) {
- return $self->cpan_module($module, $2, $1);
- }
- }
-
- return;
- }
-
- sub search_module {
- my($self, $module) = @_;
-
- unless ($self->{mirror_only}) {
- $self->chat("Searching $module on cpanmetadb ...\n");
- my $uri = "http://cpanmetadb.appspot.com/v1.0/package/$module";
- my $yaml = $self->get($uri);
- my $meta = $self->parse_meta_string($yaml);
- if ($meta && $meta->{distfile}) {
- return $self->cpan_module($module, $meta->{distfile}, $meta->{version});
- }
-
- $self->diag_fail("Finding $module on cpanmetadb failed.");
-
- $self->chat("Searching $module on search.cpan.org ...\n");
- my $uri = "http://search.cpan.org/perldoc?$module";
- my $html = $self->get($uri);
- $html =~ m!<a href="/CPAN/authors/id/(.*?\.(?:tar\.gz|tgz|tar\.bz2|zip))">!
- and return $self->cpan_module($module, $1);
-
- $self->diag_fail("Finding $module on search.cpan.org failed.");
- }
-
- MIRROR: for my $mirror (@{ $self->{mirrors} }) {
- $self->chat("Searching $module on mirror $mirror ...\n");
- my $name = '02packages.details.txt.gz';
- my $uri = "$mirror/modules/$name";
- my $gz_file = $self->package_index_for($mirror) . '.gz';
-
- unless ($self->{pkgs}{$uri}) {
- $self->chat("Downloading index file $uri ...\n");
- $self->mirror($uri, $gz_file);
- $self->generate_mirror_index($mirror) or next MIRROR;
- $self->{pkgs}{$uri} = "!!retrieved!!";
- }
-
- my $pkg = $self->search_mirror_index($mirror, $module);
- return $pkg if $pkg;
-
- $self->diag_fail("Finding $module on mirror $mirror failed.");
- }
-
- return;
- }
-
- sub source_for {
- my($self, $mirror) = @_;
- $mirror =~ s/[^\w\.\-]+/%/g;
-
- my $dir = "$self->{home}/sources/$mirror";
- File::Path::mkpath([ $dir ], 0, 0777);
-
- return $dir;
- }
-
- sub load_argv_from_fh {
- my($self, $fh) = @_;
-
- my @argv;
- while(defined(my $line = <$fh>)){
- chomp $line;
- $line =~ s/#.+$//; # comment
- $line =~ s/^\s+//; # trim spaces
- $line =~ s/\s+$//; # trim spaces
-
- push @argv, split ' ', $line if $line;
- }
- return @argv;
- }
-
- sub show_version {
- print "cpanm (App::cpanminus) version $VERSION\n";
- return 1;
- }
-
- sub show_help {
- my $self = shift;
-
- if ($_[0]) {
- die <<USAGE;
- Usage: cpanm [options] Module [...]
-
- Try `cpanm --help` or `man cpanm` for more options.
- USAGE
- }
-
- print <<HELP;
- Usage: cpanm [options] Module [...]
-
- Options:
- -v,--verbose Turns on chatty output
- -q,--quiet Turns off the most output
- --interactive Turns on interactive configure (required for Task:: modules)
- -f,--force force install
- -n,--notest Do not run unit tests
- -S,--sudo sudo to run install commands
- --installdeps Only install dependencies
- --reinstall Reinstall the distribution even if you already have the latest version installed
- --mirror Specify the base URL for the mirror (e.g. http://cpan.cpantesters.org/)
- --mirror-only Use the mirror's index file instead of the CPAN Meta DB
- --prompt Prompt when configure/build/test fails
- -l,--local-lib Specify the install base to install modules
- -L,--local-lib-contained Specify the install base to install all non-core modules
- --auto-cleanup Number of days that cpanm's work directories expire in. Defaults to 7
-
- Commands:
- --self-upgrade upgrades itself
- --info Displays distribution info on CPAN
- --look Opens the distribution with your SHELL
- -V,--version Displays software version
-
- Examples:
-
- cpanm Test::More # install Test::More
- cpanm MIYAGAWA/Plack-0.99_05.tar.gz # full distribution path
- cpanm http://example.org/LDS/CGI.pm-3.20.tar.gz # install from URL
- cpanm ~/dists/MyCompany-Enterprise-1.00.tar.gz # install from a local file
- cpanm --interactive Task::Kensho # Configure interactively
- cpanm . # install from local directory
- cpanm --installdeps . # install all the deps for the current directory
- cpanm -L extlib Plack # install Plack and all non-core deps into extlib
- cpanm --mirror http://cpan.cpantesters.org/ DBI # use the fast-syncing mirror
-
- You can also specify the default options in PERL_CPANM_OPT environment variable in the shell rc:
-
- export PERL_CPANM_OPT="--prompt --reinstall -l ~/perl --mirror http://cpan.cpantesters.org"
-
- Type `man cpanm` or `perldoc cpanm` for the more detailed explanation of the options.
-
- HELP
-
- return 1;
- }
-
- sub _writable {
- my $dir = shift;
- my @dir = File::Spec->splitdir($dir);
- while (@dir) {
- $dir = File::Spec->catdir(@dir);
- if (-e $dir) {
- return -w _;
- }
- pop @dir;
- }
-
- return;
- }
-
- sub maybe_abs {
- my($self, $lib) = @_;
- $lib =~ /^[~\/]/ ? $lib : Cwd::abs_path($lib);
- }
-
- sub bootstrap_local_lib {
- my $self = shift;
-
- # If -l is specified, use that.
- if ($self->{local_lib}) {
- return $self->setup_local_lib($self->{local_lib});
- }
-
- # root, locally-installed perl or --sudo: don't care about install_base
- return if $self->{sudo} or (_writable($Config{installsitelib}) and _writable($Config{installsitebin}));
-
- # local::lib is configured in the shell -- yay
- if ($ENV{PERL_MM_OPT} and ($ENV{MODULEBUILDRC} or $ENV{PERL_MB_OPT})) {
- $self->bootstrap_local_lib_deps;
- return;
- }
-
- $self->setup_local_lib;
-
- $self->diag(<<DIAG);
- !
- ! Can't write to $Config{installsitelib} and $Config{installsitebin}: Installing modules to $ENV{HOME}/perl5
- ! To turn off this warning, you have to do one of the following:
- ! - run me as a root or with --sudo option (to install to $Config{installsitelib} and $Config{installsitebin})
- | - run me with --local-lib option e.g. cpanm --local-lib=~/perl5
- ! - Set PERL_CPANM_OPT="--local-lib=~/perl5" environment variable (in your shell rc file)
- ! - Configure local::lib in your shell to set PERL_MM_OPT etc.
- !
- DIAG
- sleep 2;
- }
-
- sub _core_only_inc {
- my($self, $base) = @_;
- require local::lib;
- (
- local::lib->install_base_perl_path($base),
- local::lib->install_base_arch_path($base),
- @Config{qw(privlibexp archlibexp)},
- );
- }
-
- sub _dump_inc {
- my($self, $inc, $std_inc) = @_;
-
- # $self->{base} for ModuleBuildPatch.pm, . for inc/Module/Install.pm
- my @new_inc = map { qq('$_') } (@$inc, $self->{base}, '.');
- my @exclude_inc = map { qq('$_') } grep { $_ ne '.' && !ref } $self->_diff($inc, $std_inc);
-
- open my $out, ">$self->{base}/DumpedINC.pm" or die $!;
- local $" = ",";
- print $out <<EOF;
- package DumpedINC;
- my \%exclude = map { \$_ => 1 } (@exclude_inc);
- sub import {
- if (\$_[1] eq "tests") {
- \@INC = grep !\$exclude{\$_}, \@INC;
- } else {
- \@INC = (@new_inc);
- }
- }
- 1;
- EOF
- }
-
- sub _diff {
- my($self, $old, $new) = @_;
-
- my @diff;
- my %old = map { $_ => 1 } @$old;
- for my $n (@$new) {
- push @diff, $n unless exists $old{$n};
- }
-
- @diff;
- }
-
- sub _setup_local_lib_env {
- my($self, $base) = @_;
- local $SIG{__WARN__} = sub { }; # catch 'Attempting to write ...'
- local::lib->setup_env_hash_for($base);
- }
-
- sub setup_local_lib {
- my($self, $base) = @_;
-
- require local::lib;
- {
- local $0 = 'cpanm'; # so curl/wget | perl works
- $base ||= "~/perl5";
- if ($self->{self_contained}) {
- my @inc = $self->_core_only_inc($base);
- $self->_dump_inc(\@inc, \@INC);
- $self->{search_inc} = [ @inc ];
- } else {
- $self->{search_inc} = [
- local::lib->install_base_arch_path($base),
- local::lib->install_base_perl_path($base),
- @INC,
- ];
- }
- $self->_setup_local_lib_env($base);
- }
-
- $self->bootstrap_local_lib_deps;
- }
-
- sub bootstrap_local_lib_deps {
- my $self = shift;
- push @{$self->{bootstrap_deps}},
- 'ExtUtils::MakeMaker' => 6.31,
- 'ExtUtils::Install' => 1.46,
- 'Module::Build' => 0.36;
- }
-
- sub prompt_bool {
- my($self, $mess, $def) = @_;
-
- my $val = $self->prompt($mess, $def);
- return lc $val eq 'y';
- }
-
- sub prompt {
- my($self, $mess, $def) = @_;
-
- my $isa_tty = -t STDIN && (-t STDOUT || !(-f STDOUT || -c STDOUT)) ;
- my $dispdef = defined $def ? "[$def] " : " ";
- $def = defined $def ? $def : "";
-
- if (!$self->{prompt} || (!$isa_tty && eof STDIN)) {
- return $def;
- }
-
- local $|=1;
- local $\;
- my $ans;
- eval {
- local $SIG{ALRM} = sub { undef $ans; die "alarm\n" };
- print STDOUT "$mess $dispdef";
- alarm $self->{prompt_timeout} if $self->{prompt_timeout};
- $ans = <STDIN>;
- alarm 0;
- };
- if ( defined $ans ) {
- chomp $ans;
- } else { # user hit ctrl-D or alarm timeout
- print STDOUT "\n";
- }
-
- return (!defined $ans || $ans eq '') ? $def : $ans;
- }
-
- sub diag_ok {
- my($self, $msg) = @_;
- chomp $msg;
- $msg ||= "OK";
- if ($self->{in_progress}) {
- $self->_diag("$msg\n");
- $self->{in_progress} = 0;
- }
- $self->log("-> $msg\n");
- }
-
- sub diag_fail {
- my($self, $msg, $always) = @_;
- chomp $msg;
- if ($self->{in_progress}) {
- $self->_diag("FAIL\n");
- $self->{in_progress} = 0;
- }
-
- if ($msg) {
- $self->_diag("! $msg\n", $always);
- $self->log("-> FAIL $msg\n");
- }
- }
-
- sub diag_progress {
- my($self, $msg) = @_;
- chomp $msg;
- $self->{in_progress} = 1;
- $self->_diag("$msg ... ");
- $self->log("$msg\n");
- }
-
- sub _diag {
- my($self, $msg, $always) = @_;
- print STDERR $msg if $always or $self->{verbose} or !$self->{quiet};
- }
-
- sub diag {
- my($self, $msg, $always) = @_;
- $self->_diag($msg, $always);
- $self->log($msg);
- }
-
- sub chat {
- my $self = shift;
- print STDERR @_ if $self->{verbose};
- $self->log(@_);
- }
-
- sub log {
- my $self = shift;
- open my $out, ">>$self->{log}";
- print $out @_;
- }
-
- sub run {
- my($self, $cmd) = @_;
-
- if (WIN32 && ref $cmd eq 'ARRAY') {
- $cmd = join q{ }, map { $self->shell_quote($_) } @$cmd;
- }
-
- if (ref $cmd eq 'ARRAY') {
- my $pid = fork;
- if ($pid) {
- waitpid $pid, 0;
- return !$?;
- } else {
- $self->run_exec($cmd);
- }
- } else {
- unless ($self->{verbose}) {
- $cmd .= " >> " . $self->shell_quote($self->{log}) . " 2>&1";
- }
- !system $cmd;
- }
- }
-
- sub run_exec {
- my($self, $cmd) = @_;
-
- if (ref $cmd eq 'ARRAY') {
- unless ($self->{verbose}) {
- open my $logfh, ">>", $self->{log};
- open STDERR, '>&', $logfh;
- open STDOUT, '>&', $logfh;
- close $logfh;
- }
- exec @$cmd;
- } else {
- unless ($self->{verbose}) {
- $cmd .= " >> " . $self->shell_quote($self->{log}) . " 2>&1";
- }
- exec $cmd;
- }
- }
-
- sub run_timeout {
- my($self, $cmd, $timeout) = @_;
- return $self->run($cmd) if WIN32 || $self->{verbose} || !$timeout;
-
- my $pid = fork;
- if ($pid) {
- eval {
- local $SIG{ALRM} = sub { die "alarm\n" };
- alarm $timeout;
- waitpid $pid, 0;
- alarm 0;
- };
- if ($@ && $@ eq "alarm\n") {
- $self->diag_fail("Timed out (> ${timeout}s). Use --verbose to retry.");
- local $SIG{TERM} = 'IGNORE';
- kill TERM => 0;
- waitpid $pid, 0;
- return;
- }
- return !$?;
- } elsif ($pid == 0) {
- $self->run_exec($cmd);
- } else {
- $self->chat("! fork failed: falling back to system()\n");
- $self->run($cmd);
- }
- }
-
- sub configure {
- my($self, $cmd) = @_;
-
- # trick AutoInstall
- local $ENV{PERL5_CPAN_IS_RUNNING} = local $ENV{PERL5_CPANPLUS_IS_RUNNING} = $$;
-
- # e.g. skip CPAN configuration on local::lib
- local $ENV{PERL5_CPANM_IS_RUNNING} = $$;
-
- my $use_default = !$self->{interactive};
- local $ENV{PERL_MM_USE_DEFAULT} = $use_default;
-
- # skip man page generation
- local $ENV{PERL_MM_OPT} = $ENV{PERL_MM_OPT};
- unless ($self->{pod2man}) {
- $ENV{PERL_MM_OPT} .= " INSTALLMAN1DIR=none INSTALLMAN3DIR=none";
- }
-
- local $self->{verbose} = $self->{verbose} || $self->{interactive};
- $self->run_timeout($cmd, $self->{configure_timeout});
- }
-
- sub build {
- my($self, $cmd, $distname) = @_;
-
- return 1 if $self->run_timeout($cmd, $self->{build_timeout});
- while (1) {
- my $ans = lc $self->prompt("Building $distname failed.\nYou can s)kip, r)etry or l)ook ?", "s");
- return if $ans eq 's';
- return $self->build($cmd, $distname) if $ans eq 'r';
- $self->look if $ans eq 'l';
- }
- }
-
- sub test {
- my($self, $cmd, $distname) = @_;
- return 1 if $self->{notest};
-
- # http://www.nntp.perl.org/group/perl.perl5.porters/2009/10/msg152656.html
- local $ENV{AUTOMATED_TESTING} = 1
- unless $self->env('NO_AUTOMATED_TESTING');
-
- local $ENV{PERL5OPT} = "-I$self->{base} -MDumpedINC=tests"
- if $self->{self_contained};
-
- return 1 if $self->run_timeout($cmd, $self->{test_timeout});
- if ($self->{force}) {
- $self->diag_fail("Testing $distname failed but installing it anyway.");
- return 1;
- } else {
- $self->diag_fail;
- while (1) {
- my $ans = lc $self->prompt("Testing $distname failed.\nYou can s)kip, r)etry, f)orce install or l)ook ?", "s");
- return if $ans eq 's';
- return $self->test($cmd, $distname) if $ans eq 'r';
- return 1 if $ans eq 'f';
- $self->look if $ans eq 'l';
- }
- }
- }
-
- sub install {
- my($self, $cmd, $uninst_opts) = @_;
-
- if ($self->{sudo}) {
- unshift @$cmd, "sudo";
- }
-
- if ($self->{uninstall_shadows} && !$ENV{PERL_MM_OPT}) {
- push @$cmd, @$uninst_opts;
- }
-
- $self->run($cmd);
- }
-
- sub look {
- my $self = shift;
-
- my $shell = $ENV{SHELL};
- $shell ||= $ENV{COMSPEC} if WIN32;
- if ($shell) {
- my $cwd = Cwd::cwd;
- $self->diag("Entering $cwd with $shell\n");
- system $shell;
- } else {
- $self->diag_fail("You don't seem to have a SHELL :/");
- }
- }
-
- sub chdir {
- my $self = shift;
- chdir(File::Spec->canonpath($_[0])) or die "$_[0]: $!";
- }
-
- sub configure_mirrors {
- my $self = shift;
- unless (@{$self->{mirrors}}) {
- $self->{mirrors} = [ 'http://search.cpan.org/CPAN' ];
- }
- for (@{$self->{mirrors}}) {
- s!^/!file:///!;
- s!/$!!;
- }
- }
-
- sub self_upgrade {
- my $self = shift;
- $self->{argv} = [ 'App::cpanminus' ];
- return; # continue
- }
-
- sub install_module {
- my($self, $module, $depth) = @_;
-
- if ($self->{seen}{$module}++) {
- $self->chat("Already tried $module. Skipping.\n");
- return 1;
- }
-
- my $dist = $self->resolve_name($module);
- unless ($dist) {
- $self->diag_fail("Couldn't find module or a distribution $module", 1);
- return;
- }
-
- if ($dist->{distvname} && $self->{seen}{$dist->{distvname}}++) {
- $self->chat("Already tried $dist->{distvname}. Skipping.\n");
- return 1;
- }
-
- if ($self->{cmd} eq 'info') {
- print $self->format_dist($dist), "\n";
- return 1;
- }
-
- $self->check_libs;
- $self->setup_module_build_patch unless $self->{pod2man};
-
- if ($dist->{module}) {
- my($ok, $local) = $self->check_module($dist->{module}, $dist->{module_version} || 0);
- if ($self->{skip_installed} && $ok) {
- $self->diag("$dist->{module} is up to date. ($local)\n", 1);
- return 1;
- }
- }
-
- if ($dist->{dist} eq 'perl'){
- $self->diag("skipping $dist->{pathname}\n");
- return 1;
- }
-
- $self->diag("--> Working on $module\n");
-
- $dist->{dir} ||= $self->fetch_module($dist);
-
- unless ($dist->{dir}) {
- $self->diag_fail("Failed to fetch distribution $dist->{distvname}", 1);
- return;
- }
-
- $self->chat("Entering $dist->{dir}\n");
- $self->chdir($self->{base});
- $self->chdir($dist->{dir});
-
- if ($self->{cmd} eq 'look') {
- $self->look;
- return 1;
- }
-
- return $self->build_stuff($module, $dist, $depth);
- }
-
- sub format_dist {
- my($self, $dist) = @_;
-
- # TODO support --dist-format?
- return "$dist->{cpanid}/$dist->{filename}";
- }
-
- sub fetch_module {
- my($self, $dist) = @_;
-
- $self->chdir($self->{base});
-
- for my $uri (@{$dist->{uris}}) {
- $self->diag_progress("Fetching $uri");
-
- # Ugh, $dist->{filename} can contain sub directory
- my $filename = $dist->{filename} || $uri;
- my $name = File::Basename::basename($filename);
-
- my $cancelled;
- my $fetch = sub {
- my $file;
- eval {
- local $SIG{INT} = sub { $cancelled = 1; die "SIGINT\n" };
- $self->mirror($uri, $name);
- $file = $name if -e $name;
- };
- $self->chat("$@") if $@ && $@ ne "SIGINT\n";
- return $file;
- };
-
- my($try, $file);
- while ($try++ < 3) {
- $file = $fetch->();
- last if $cancelled or $file;
- $self->diag_fail("Download $uri failed. Retrying ... ");
- }
-
- if ($cancelled) {
- $self->diag_fail("Download cancelled.");
- return;
- }
-
- unless ($file) {
- $self->diag_fail("Failed to download $uri");
- next;
- }
-
- $self->diag_ok;
- $dist->{local_path} = File::Spec->rel2abs($name);
-
- my $dir = $self->unpack($file);
- next unless $dir; # unpack failed
-
- if (my $save = $self->{save_dists}) {
- my $path = "$save/authors/id/$dist->{pathname}";
- $self->chat("Copying $name to $path\n");
- File::Path::mkpath([ File::Basename::dirname($path) ], 0, 0777);
- File::Copy::copy($file, $path) or warn $!;
- }
-
- return $dist, $dir;
- }
- }
-
- sub unpack {
- my($self, $file) = @_;
- $self->chat("Unpacking $file\n");
- my $dir = $file =~ /\.zip/i ? $self->unzip($file) : $self->untar($file);
- unless ($dir) {
- $self->diag_fail("Failed to unpack $file: no directory");
- }
- return $dir;
- }
-
- sub resolve_name {
- my($self, $module) = @_;
-
- # URL
- if ($module =~ /^(ftp|https?|file):/) {
- if ($module =~ m!authors/id/!) {
- return $self->cpan_dist($module, $module);
- } else {
- return { uris => [ $module ] };
- }
- }
-
- # Directory
- if ($module =~ m!^[\./]! && -d $module) {
- return {
- source => 'local',
- dir => Cwd::abs_path($module),
- };
- }
-
- # File
- if (-f $module) {
- return {
- source => 'local',
- uris => [ "file://" . Cwd::abs_path($module) ],
- };
- }
-
- # cpan URI
- if ($module =~ s!^cpan:///distfile/!!) {
- return $self->cpan_dist($module);
- }
-
- # PAUSEID/foo
- if ($module =~ m!([A-Z]{3,})/!) {
- return $self->cpan_dist($module);
- }
-
- # Module name
- return $self->search_module($module);
- }
-
- sub cpan_module {
- my($self, $module, $dist, $version) = @_;
-
- my $dist = $self->cpan_dist($dist);
- $dist->{module} = $module;
- $dist->{module_version} = $version if $version && $version ne 'undef';
-
- return $dist;
- }
-
- sub cpan_dist {
- my($self, $dist, $url) = @_;
-
- $dist =~ s!^([A-Z]{3})!substr($1,0,1)."/".substr($1,0,2)."/".$1!e;
-
- require CPAN::DistnameInfo;
- my $d = CPAN::DistnameInfo->new($dist);
-
- if ($url) {
- $url = [ $url ] unless ref $url eq 'ARRAY';
- } else {
- my $id = $d->cpanid;
- my $fn = substr($id, 0, 1) . "/" . substr($id, 0, 2) . "/" . $id . "/" . $d->filename;
-
- my @mirrors = @{$self->{mirrors}};
- my @urls = map "$_/authors/id/$fn", @mirrors;
-
- $url = \@urls,
- }
-
- return {
- $d->properties,
- source => 'cpan',
- uris => $url,
- };
- }
-
- sub setup_module_build_patch {
- my $self = shift;
-
- open my $out, ">$self->{base}/ModuleBuildSkipMan.pm" or die $!;
- print $out <<EOF;
- package ModuleBuildSkipMan;
- CHECK {
- if (%Module::Build::) {
- no warnings 'redefine';
- *Module::Build::Base::ACTION_manpages = sub {};
- *Module::Build::Base::ACTION_docs = sub {};
- }
- }
- 1;
- EOF
- }
-
- sub check_module {
- my($self, $mod, $want_ver) = @_;
-
- require Module::Metadata;
- my $meta = Module::Metadata->new_from_module($mod, inc => $self->{search_inc})
- or return 0, undef;
-
- my $version = $meta->version;
-
- # When -L is in use, the version loaded from 'perl' library path
- # might be newer than the version that is shipped with the current perl
- if ($self->{self_contained} && $self->loaded_from_perl_lib($meta)) {
- my $core_version = eval {
- require Module::CoreList;
- $Module::CoreList::version{$]+0}{$mod};
- };
-
- # HACK: Module::Build 0.3622 or later has non-core module
- # dependencies such as Perl::OSType and CPAN::Meta, and causes
- # issues when a newer version is loaded from 'perl' while deps
- # are loaded from the 'site' library path. Just assume it's
- # not in the core, and install to the new local library path.
- if ($mod eq 'Module::Build' && $core_version != $version) {
- return 0, undef;
- }
-
- $version = $core_version if $core_version;
- }
-
- $self->{local_versions}{$mod} = $version;
-
- if ($self->is_deprecated($meta)){
- return 0, $version;
- } elsif (!$want_ver or $version >= version->new($want_ver)) {
- return 1, ($version || 'undef');
- } else {
- return 0, $version;
- }
- }
-
- sub is_deprecated {
- my($self, $meta) = @_;
-
- my $deprecated = eval {
- require Module::CoreList;
- Module::CoreList::is_deprecated($meta->{module});
- };
-
- return unless $deprecated;
- return $self->loaded_from_perl_lib($meta);
- }
-
- sub loaded_from_perl_lib {
- my($self, $meta) = @_;
-
- require Config;
- for my $dir (qw(archlibexp privlibexp)) {
- my $confdir = $Config{$dir};
- if ($confdir eq substr($meta->filename, 0, length($confdir))) {
- return 1;
- }
- }
-
- return;
- }
-
- sub should_install {
- my($self, $mod, $ver) = @_;
-
- $self->chat("Checking if you have $mod $ver ... ");
- my($ok, $local) = $self->check_module($mod, $ver);
-
- if ($ok) { $self->chat("Yes ($local)\n") }
- elsif ($local) { $self->chat("No ($local < $ver)\n") }
- else { $self->chat("No\n") }
-
- return $mod unless $ok;
- return;
- }
-
- sub install_deps {
- my($self, $dir, $depth, @deps) = @_;
-
- my(@install, %seen);
- while (my($mod, $ver) = splice @deps, 0, 2) {
- next if $seen{$mod} or $mod eq 'perl' or $mod eq 'Config';
- if ($self->should_install($mod, $ver)) {
- push @install, $mod;
- $seen{$mod} = 1;
- }
- }
-
- if (@install) {
- $self->diag("==> Found dependencies: " . join(", ", @install) . "\n");
- }
-
- my @fail;
- for my $mod (@install) {
- $self->install_module($mod, $depth + 1)
- or push @fail, $mod;
- }
-
- $self->chdir($self->{base});
- $self->chdir($dir) if $dir;
-
- return @fail;
- }
-
- sub install_deps_bailout {
- my($self, $target, $dir, $depth, @deps) = @_;
-
- my @fail = $self->install_deps($dir, $depth, @deps);
- if (@fail) {
- unless ($self->prompt_bool("Installing the following dependencies failed:\n==> " .
- join(", ", @fail) . "\nDo you want to continue building $target anyway?", "n")) {
- $self->diag_fail("Bailing out the installation for $target. Retry with --prompt or --force.", 1);
- return;
- }
- }
-
- return 1;
- }
-
- sub build_stuff {
- my($self, $stuff, $dist, $depth) = @_;
-
- my @config_deps;
- if (!%{$dist->{meta} || {}} && -e 'META.yml') {
- $self->chat("Checking configure dependencies from META.yml\n");
- $dist->{meta} = $self->parse_meta('META.yml');
- }
-
- if (!$dist->{meta} && $dist->{source} eq 'cpan') {
- $self->chat("META.yml not found or unparsable. Fetching META.yml from search.cpan.org\n");
- $dist->{meta} = $self->fetch_meta_sco($dist);
- }
-
- $dist->{meta} ||= {};
-
- push @config_deps, %{$dist->{meta}{configure_requires} || {}};
-
- my $target = $dist->{meta}{name} ? "$dist->{meta}{name}-$dist->{meta}{version}" : $dist->{dir};
-
- $self->install_deps_bailout($target, $dist->{dir}, $depth, @config_deps)
- or return;
-
- $self->diag_progress("Configuring $target");
-
- my $configure_state = $self->configure_this($dist);
-
- $self->diag_ok($configure_state->{configured_ok} ? "OK" : "N/A");
-
- my @deps = $self->find_prereqs($dist);
-
- my $distname = $dist->{meta}{name} ? "$dist->{meta}{name}-$dist->{meta}{version}" : $stuff;
-
- my $walkup;
- if ($self->{scandeps}) {
- $walkup = $self->scandeps_append_child($dist);
- }
-
- $self->install_deps_bailout($distname, $dist->{dir}, $depth, @deps)
- or return;
-
- if ($self->{scandeps}) {
- unless ($configure_state->{configured_ok}) {
- my $diag = <<DIAG;
- ! Configuring $distname failed. See $self->{log} for details.
- ! You might have to install the following modules first to get --scandeps working correctly.
- DIAG
- if (@config_deps) {
- my @tree = @{$self->{scandeps_tree}};
- $diag .= "!\n" . join("", map "! * $_->[0]{module}\n", @tree[0..$#tree-1]) if @tree;
- }
- $self->diag("!\n$diag!\n", 1);
- }
- $walkup->();
- return 1;
- }
-
- if ($self->{installdeps} && $depth == 0) {
- $self->diag("<== Installed dependencies for $stuff. Finishing.\n");
- return 1;
- }
-
- my $installed;
- if ($configure_state->{use_module_build} && -e 'Build' && -f _) {
- my @switches = $self->{pod2man} ? () : ("-I$self->{base}", "-MModuleBuildSkipMan");
- $self->diag_progress("Building " . ($self->{notest} ? "" : "and testing ") . $distname);
- $self->build([ $self->{perl}, @switches, "./Build" ], $distname) &&
- $self->test([ $self->{perl}, "./Build", "test" ], $distname) &&
- $self->install([ $self->{perl}, @switches, "./Build", "install" ], [ "--uninst", 1 ]) &&
- $installed++;
- } elsif ($self->{make} && -e 'Makefile') {
- $self->diag_progress("Building " . ($self->{notest} ? "" : "and testing ") . $distname);
- $self->build([ $self->{make} ], $distname) &&
- $self->test([ $self->{make}, "test" ], $distname) &&
- $self->install([ $self->{make}, "install" ], [ "UNINST=1" ]) &&
- $installed++;
- } else {
- my $why;
- my $configure_failed = $configure_state->{configured} && !$configure_state->{configured_ok};
- if ($configure_failed) { $why = "Configure failed for $distname." }
- elsif ($self->{make}) { $why = "The distribution doesn't have a proper Makefile.PL/Build.PL" }
- else { $why = "Can't configure the distribution. You probably need to have 'make'." }
-
- $self->diag_fail("$why See $self->{log} for details.", 1);
- return;
- }
-
- if ($installed) {
- my $local = $self->{local_versions}{$dist->{module} || ''};
- my $version = $dist->{module_version} || $dist->{meta}{version} || $dist->{version};
- my $reinstall = $local && ($local eq $version);
-
- my $how = $reinstall ? "reinstalled $distname"
- : $local ? "installed $distname (upgraded from $local)"
- : "installed $distname" ;
- my $msg = "Successfully $how";
- $self->diag_ok;
- $self->diag("$msg\n", 1);
- $self->{installed_dists}++;
- return 1;
- } else {
- my $msg = "Building $distname failed";
- $self->diag_fail("Installing $stuff failed. See $self->{log} for details.", 1);
- return;
- }
- }
-
- sub configure_this {
- my($self, $dist) = @_;
-
- my @switches;
- @switches = ("-I$self->{base}", "-MDumpedINC") if $self->{self_contained};
- local $ENV{PERL5LIB} = '' if $self->{self_contained};
-
- my @mb_switches = @switches;
- unless ($self->{pod2man}) {
- # it has to be push, so Module::Build is loaded from the adjusted path when -L is in use
- push @mb_switches, ("-I$self->{base}", "-MModuleBuildSkipMan");
- }
-
- my $state = {};
-
- my $try_eumm = sub {
- if (-e 'Makefile.PL') {
- $self->chat("Running Makefile.PL\n");
- local $ENV{X_MYMETA} = 'YAML';
-
- # NOTE: according to Devel::CheckLib, most XS modules exit
- # with 0 even if header files are missing, to avoid receiving
- # tons of FAIL reports in such cases. So exit code can't be
- # trusted if it went well.
- if ($self->configure([ $self->{perl}, @switches, "Makefile.PL" ])) {
- $state->{configured_ok} = -e 'Makefile';
- }
- $state->{configured}++;
- }
- };
-
- my $try_mb = sub {
- if (-e 'Build.PL') {
- $self->chat("Running Build.PL\n");
- if ($self->configure([ $self->{perl}, @mb_switches, "Build.PL" ])) {
- $state->{configured_ok} = -e 'Build' && -f _;
- }
- $state->{use_module_build}++;
- $state->{configured}++;
- }
- };
-
- # Module::Build deps should use MakeMaker because that causes circular deps and fail
- # Otherwise we should prefer Build.PL
- my %should_use_mm = map { $_ => 1 } qw( version ExtUtils-ParseXS ExtUtils-Install ExtUtils-Manifest );
-
- my @try;
- if ($dist->{dist} && $should_use_mm{$dist->{dist}}) {
- @try = ($try_eumm, $try_mb);
- } else {
- @try = ($try_mb, $try_eumm);
- }
-
- for my $try (@try) {
- $try->();
- last if $state->{configured_ok};
- }
-
- unless ($state->{configured_ok}) {
- while (1) {
- my $ans = lc $self->prompt("Configuring $dist->{dist} failed.\nYou can s)kip, r)etry or l)ook ?", "s");
- last if $ans eq 's';
- return $self->configure_this($dist) if $ans eq 'r';
- $self->look if $ans eq 'l';
- }
- }
-
- return $state;
- }
-
- sub safe_eval {
- my($self, $code) = @_;
- eval $code;
- }
-
- sub find_prereqs {
- my($self, $dist) = @_;
-
- my @deps;
-
- my $meta = $dist->{meta};
- if (-e 'MYMETA.yml') {
- $self->chat("Checking dependencies from MYMETA.yml ...\n");
- my $mymeta = $self->parse_meta('MYMETA.yml');
- if ($mymeta) {
- @deps = $self->extract_requires($mymeta);
- $meta->{$_} = $mymeta->{$_} for keys %$mymeta; # merge
- }
- } elsif (-e '_build/prereqs') {
- $self->chat("Checking dependencies from _build/prereqs ...\n");
- my $mymeta = do { open my $in, "_build/prereqs"; $self->safe_eval(join "", <$in>) };
- @deps = $self->extract_requires($mymeta);
- }
-
- if (-e 'Makefile') {
- $self->chat("Finding PREREQ from Makefile ...\n");
- open my $mf, "Makefile";
- while (<$mf>) {
- if (/^\#\s+PREREQ_PM => {\s*(.*?)\s*}/) {
- my @all;
- my @pairs = split ', ', $1;
- for (@pairs) {
- my ($pkg, $v) = split '=>', $_;
- push @all, [ $pkg, $v ];
- }
- my $list = join ", ", map { "'$_->[0]' => $_->[1]" } @all;
- my $prereq = $self->safe_eval("no strict; +{ $list }");
- push @deps, %$prereq if $prereq;
- last;
- }
- }
- }
-
- if ($dist->{module} =~ /^Bundle::/i) {
- push @deps, $self->bundle_deps($dist);
- }
-
- # No need to remove, but this gets in the way of signature testing :/
- unlink $_ for qw(MYMETA.json MYMETA.yml);
-
- return @deps;
- }
-
- sub bundle_deps {
- my($self, $dist) = @_;
-
- my @files;
- File::Find::find({
- wanted => sub { push @files, File::Spec->rel2abs($_) if /\.pm/i },
- no_chdir => 1,
- }, '.');
-
- my @deps;
-
- for my $file (@files) {
- open my $pod, "<", $file or next;
- my $in_contents;
- while (<$pod>) {
- if (/^=head\d\s+CONTENTS/) {
- $in_contents = 1;
- } elsif (/^=/) {
- $in_contents = 0;
- } elsif ($in_contents) {
- /^(\S+)\s*(\S+)?/
- and push @deps, $1, $self->maybe_version($2);
- }
- }
- }
-
- return @deps;
- }
-
- sub maybe_version {
- my($self, $string) = @_;
- return $string && $string =~ /^\.?\d/ ? $string : undef;
- }
-
- sub extract_requires {
- my($self, $meta) = @_;
-
- my @deps;
- push @deps, %{$meta->{requires}} if $meta->{requires};
- push @deps, %{$meta->{build_requires}} if $meta->{build_requires};
-
- return @deps;
- }
-
- sub cleanup_workdirs {
- my $self = shift;
-
- my $expire = time - 24 * 60 * 60 * $self->{auto_cleanup};
- my @targets;
-
- opendir my $dh, "$self->{home}/work";
- while (my $e = readdir $dh) {
- next if $e !~ /^(\d+)\.\d+$/; # {UNIX time}.{PID}
- my $time = $1;
- if ($time < $expire) {
- push @targets, "$self->{home}/work/$e";
- }
- }
-
- if (@targets) {
- $self->chat("Expiring ", scalar(@targets), " work directories.\n");
- File::Path::rmtree(\@targets, 0, 0); # safe = 0, since blib usually doesn't have write bits
- }
- }
-
- sub scandeps_append_child {
- my($self, $dist) = @_;
-
- my $new_node = [ $dist, [] ];
-
- my $curr_node = $self->{scandeps_current} || [ undef, $self->{scandeps_tree} ];
- push @{$curr_node->[1]}, $new_node;
-
- $self->{scandeps_current} = $new_node;
-
- return sub { $self->{scandeps_current} = $curr_node };
- }
-
- sub dump_scandeps {
- my $self = shift;
-
- if ($self->{format} eq 'tree') {
- $self->walk_down(sub {
- my($dist, $depth) = @_;
- if ($depth == 0) {
- print "$dist->{distvname}\n";
- } else {
- print " " x ($depth - 1);
- print "\\_ $dist->{distvname}\n";
- }
- }, 1);
- } elsif ($self->{format} =~ /^dists?$/) {
- $self->walk_down(sub {
- my($dist, $depth) = @_;
- print $self->format_dist($dist), "\n";
- }, 0);
- } elsif ($self->{format} eq 'json') {
- require JSON;
- print JSON::encode_json($self->{scandeps_tree});
- } elsif ($self->{format} eq 'yaml') {
- require YAML;
- print YAML::Dump($self->{scandeps_tree});
- } else {
- $self->diag("Unknown format: $self->{format}\n");
- }
- }
-
- sub walk_down {
- my($self, $cb, $pre) = @_;
- $self->_do_walk_down($self->{scandeps_tree}, $cb, 0, $pre);
- }
-
- sub _do_walk_down {
- my($self, $children, $cb, $depth, $pre) = @_;
-
- # DFS - $pre determines when we call the callback
- for my $node (@$children) {
- $cb->($node->[0], $depth) if $pre;
- $self->_do_walk_down($node->[1], $cb, $depth + 1, $pre);
- $cb->($node->[0], $depth) unless $pre;
- }
- }
-
- sub DESTROY {
- my $self = shift;
- $self->{at_exit}->($self) if $self->{at_exit};
- }
-
- # Utils
-
- sub shell_quote {
- my($self, $stuff) = @_;
- $stuff =~ /^${quote}.+${quote}$/ ? $stuff : ($quote . $stuff . $quote);
- }
-
- sub which {
- my($self, $name) = @_;
- my $exe_ext = $Config{_exe};
- for my $dir (File::Spec->path) {
- my $fullpath = File::Spec->catfile($dir, $name);
- if (-x $fullpath || -x ($fullpath .= $exe_ext)) {
- if ($fullpath =~ /\s/ && $fullpath !~ /^$quote/) {
- $fullpath = $self->shell_quote($fullpath);
- }
- return $fullpath;
- }
- }
- return;
- }
-
- sub get { $_[0]->{_backends}{get}->(@_) };
- sub mirror { $_[0]->{_backends}{mirror}->(@_) };
- sub untar { $_[0]->{_backends}{untar}->(@_) };
- sub unzip { $_[0]->{_backends}{unzip}->(@_) };
-
- sub file_get {
- my($self, $uri) = @_;
- open my $fh, "<$uri" or return;
- join '', <$fh>;
- }
-
- sub file_mirror {
- my($self, $uri, $path) = @_;
- File::Copy::copy($uri, $path);
- }
-
- sub init_tools {
- my $self = shift;
-
- return if $self->{initialized}++;
-
- if ($self->{make} = $self->which($Config{make})) {
- $self->chat("You have make $self->{make}\n");
- }
-
- # use --no-lwp if they have a broken LWP, to upgrade LWP
- if ($self->{try_lwp} && eval { require LWP::UserAgent; LWP::UserAgent->VERSION(5.802) }) {
- $self->chat("You have LWP $LWP::VERSION\n");
- my $ua = sub {
- LWP::UserAgent->new(
- parse_head => 0,
- env_proxy => 1,
- agent => "cpanminus/$VERSION",
- timeout => 30,
- @_,
- );
- };
- $self->{_backends}{get} = sub {
- my $self = shift;
- my $res = $ua->()->request(HTTP::Request->new(GET => $_[0]));
- return unless $res->is_success;
- return $res->decoded_content;
- };
- $self->{_backends}{mirror} = sub {
- my $self = shift;
- my $res = $ua->()->mirror(@_);
- $res->code;
- };
- } elsif ($self->{try_wget} and my $wget = $self->which('wget')) {
- $self->chat("You have $wget\n");
- $self->{_backends}{get} = sub {
- my($self, $uri) = @_;
- return $self->file_get($uri) if $uri =~ s!^file:/+!/!;
- $self->safeexec( my $fh, $wget, $uri, ( $self->{verbose} ? () : '-q' ), '-O', '-' ) or die "wget $uri: $!";
- local $/;
- <$fh>;
- };
- $self->{_backends}{mirror} = sub {
- my($self, $uri, $path) = @_;
- return $self->file_mirror($uri, $path) if $uri =~ s!^file:/+!/!;
- $self->safeexec( my $fh, $wget, '--retry-connrefused', $uri, ( $self->{verbose} ? () : '-q' ), '-O', $path ) or die "wget $uri: $!";
- local $/;
- <$fh>;
- };
- } elsif ($self->{try_curl} and my $curl = $self->which('curl')) {
- $self->chat("You have $curl\n");
- $self->{_backends}{get} = sub {
- my($self, $uri) = @_;
- return $self->file_get($uri) if $uri =~ s!^file:/+!/!;
- $self->safeexec( my $fh, $curl, '-L', ( $self->{verbose} ? () : '-s' ), $uri ) or die "curl $uri: $!";
- local $/;
- <$fh>;
- };
- $self->{_backends}{mirror} = sub {
- my($self, $uri, $path) = @_;
- return $self->file_mirror($uri, $path) if $uri =~ s!^file:/+!/!;
- $self->safeexec( my $fh, $curl, '-L', $uri, ( $self->{verbose} ? () : '-s' ), '-#', '-o', $path ) or die "curl $uri: $!";
- local $/;
- <$fh>;
- };
- } else {
- require HTTP::Tiny;
- $self->chat("Falling back to HTTP::Tiny $HTTP::Tiny::VERSION\n");
-
- $self->{_backends}{get} = sub {
- my $self = shift;
- my $res = HTTP::Tiny->new->get($_[0]);
- return unless $res->{success};
- return $res->{content};
- };
- $self->{_backends}{mirror} = sub {
- my $self = shift;
- my $res = HTTP::Tiny->new->mirror(@_);
- return $res->{status};
- };
- }
-
- my $tar = $self->which('tar');
- my $tar_ver;
- my $maybe_bad_tar = sub { WIN32 || SUNOS || (($tar_ver = `$tar --version 2>/dev/null`) =~ /GNU.*1\.13/i) };
-
- if ($tar && !$maybe_bad_tar->()) {
- chomp $tar_ver;
- $self->chat("You have $tar: $tar_ver\n");
- $self->{_backends}{untar} = sub {
- my($self, $tarfile) = @_;
-
- my $xf = "xf" . ($self->{verbose} ? 'v' : '');
- my $ar = $tarfile =~ /bz2$/ ? 'j' : 'z';
-
- my($root, @others) = `$tar tf$ar $tarfile`
- or return undef;
-
- chomp $root;
- $root =~ s!^\./!!;
- $root =~ s{^(.+?)/.*$}{$1};
-
- system "$tar $xf$ar $tarfile";
- return $root if -d $root;
-
- $self->diag_fail("Bad archive: $tarfile");
- return undef;
- }
- } elsif ( $tar
- and my $gzip = $self->which('gzip')
- and my $bzip2 = $self->which('bzip2')) {
- $self->chat("You have $tar, $gzip and $bzip2\n");
- $self->{_backends}{untar} = sub {
- my($self, $tarfile) = @_;
-
- my $x = "x" . ($self->{verbose} ? 'v' : '') . "f -";
- my $ar = $tarfile =~ /bz2$/ ? $bzip2 : $gzip;
-
- my($root, @others) = `$ar -dc $tarfile | $tar tf -`
- or return undef;
-
- chomp $root;
- $root =~ s{^(.+?)/.*$}{$1};
-
- system "$ar -dc $tarfile | $tar $x";
- return $root if -d $root;
-
- $self->diag_fail("Bad archive: $tarfile");
- return undef;
- }
- } elsif (eval { require Archive::Tar }) { # uses too much memory!
- $self->chat("Falling back to Archive::Tar $Archive::Tar::VERSION\n");
- $self->{_backends}{untar} = sub {
- my $self = shift;
- my $t = Archive::Tar->new($_[0]);
- my $root = ($t->list_files)[0];
- $root =~ s{^(.+?)/.*$}{$1};
- $t->extract;
- return -d $root ? $root : undef;
- };
- } else {
- $self->{_backends}{untar} = sub {
- die "Failed to extract $_[1] - You need to have tar or Archive::Tar installed.\n";
- };
- }
-
- if (my $unzip = $self->which('unzip')) {
- $self->chat("You have $unzip\n");
- $self->{_backends}{unzip} = sub {
- my($self, $zipfile) = @_;
-
- my $opt = $self->{verbose} ? '' : '-q';
- my(undef, $root, @others) = `$unzip -t $zipfile`
- or return undef;
-
- chomp $root;
- $root =~ s{^\s+testing:\s+(.+?)/\s+OK$}{$1};
-
- system "$unzip $opt $zipfile";
- return $root if -d $root;
-
- $self->diag_fail("Bad archive: [$root] $zipfile");
- return undef;
- }
- } else {
- $self->{_backends}{unzip} = sub {
- eval { require Archive::Zip }
- or die "Failed to extract $_[1] - You need to have unzip or Archive::Zip installed.\n";
- my($self, $file) = @_;
- my $zip = Archive::Zip->new();
- my $status;
- $status = $zip->read($file);
- $self->diag_fail("Read of file[$file] failed")
- if $status != Archive::Zip::AZ_OK();
- my @members = $zip->members();
- my $root;
- for my $member ( @members ) {
- my $af = $member->fileName();
- next if ($af =~ m!^(/|\.\./)!);
- $root = $af unless $root;
- $status = $member->extractToFileNamed( $af );
- $self->diag_fail("Extracting of file[$af] from zipfile[$file failed")
- if $status != Archive::Zip::AZ_OK();
- }
- return -d $root ? $root : undef;
- };
- }
- }
-
- sub safeexec {
- my $self = shift;
- my $rdr = $_[0] ||= Symbol::gensym();
-
- if (WIN32) {
- my $cmd = join q{ }, map { $self->shell_quote($_) } @_[ 1 .. $#_ ];
- return open( $rdr, "$cmd |" );
- }
-
- if ( my $pid = open( $rdr, '-|' ) ) {
- return $pid;
- }
- elsif ( defined $pid ) {
- exec( @_[ 1 .. $#_ ] );
- exit 1;
- }
- else {
- return;
- }
- }
-
- sub parse_meta {
- my($self, $file) = @_;
- return eval { (Parse::CPAN::Meta::LoadFile($file))[0] } || undef;
- }
-
- sub parse_meta_string {
- my($self, $yaml) = @_;
- return eval { (Parse::CPAN::Meta::Load($yaml))[0] } || undef;
- }
-
- 1;
-APP_CPANMINUS_SCRIPT
-
-$fatpacked{"CPAN/DistnameInfo.pm"} = <<'CPAN_DISTNAMEINFO';
-
- package CPAN::DistnameInfo;
-
- $VERSION = "0.11";
- use strict;
-
- sub distname_info {
- my $file = shift or return;
-
- my ($dist, $version) = $file =~ /^
- ((?:[-+.]*(?:[A-Za-z0-9]+|(?<=\D)_|_(?=\D))*
- (?:
- [A-Za-z](?=[^A-Za-z]|$)
- |
- \d(?=-)
- )(?<![._-][vV])
- )+)(.*)
- $/xs or return ($file,undef,undef);
-
- if ($dist =~ /-undef\z/ and ! length $version) {
- $dist =~ s/-undef\z//;
- }
-
- # Remove potential -withoutworldwriteables suffix
- $version =~ s/-withoutworldwriteables$//;
-
- if ($version =~ /^(-[Vv].*)-(\d.*)/) {
-
- # Catch names like Unicode-Collate-Standard-V3_1_1-0.1
- # where the V3_1_1 is part of the distname
- $dist .= $1;
- $version = $2;
- }
-
- # Normalize the Dist.pm-1.23 convention which CGI.pm and
- # a few others use.
- $dist =~ s{\.pm$}{};
-
- $version = $1
- if !length $version and $dist =~ s/-(\d+\w)$//;
-
- $version = $1 . $version
- if $version =~ /^\d+$/ and $dist =~ s/-(\w+)$//;
-
- if ($version =~ /\d\.\d/) {
- $version =~ s/^[-_.]+//;
- }
- else {
- $version =~ s/^[-_]+//;
- }
-
- my $dev;
- if (length $version) {
- if ($file =~ /^perl-?\d+\.(\d+)(?:\D(\d+))?(-(?:TRIAL|RC)\d+)?$/) {
- $dev = 1 if (($1 > 6 and $1 & 1) or ($2 and $2 >= 50)) or $3;
- }
- elsif ($version =~ /\d\D\d+_\d/ or $version =~ /-TRIAL/) {
- $dev = 1;
- }
- }
- else {
- $version = undef;
- }
-
- ($dist, $version, $dev);
- }
-
- sub new {
- my $class = shift;
- my $distfile = shift;
-
- $distfile =~ s,//+,/,g;
-
- my %info = ( pathname => $distfile );
-
- ($info{filename} = $distfile) =~ s,^(((.*?/)?authors/)?id/)?([A-Z])/(\4[A-Z])/(\5[-A-Z0-9]*)/,,
- and $info{cpanid} = $6;
-
- if ($distfile =~ m,([^/]+)\.(tar\.(?:g?z|bz2)|zip|tgz)$,i) { # support more ?
- $info{distvname} = $1;
- $info{extension} = $2;
- }
-
- @info{qw(dist version beta)} = distname_info($info{distvname});
- $info{maturity} = delete $info{beta} ? 'developer' : 'released';
-
- return bless \%info, $class;
- }
-
- sub dist { shift->{dist} }
- sub version { shift->{version} }
- sub maturity { shift->{maturity} }
- sub filename { shift->{filename} }
- sub cpanid { shift->{cpanid} }
- sub distvname { shift->{distvname} }
- sub extension { shift->{extension} }
- sub pathname { shift->{pathname} }
-
- sub properties { %{ $_[0] } }
-
- 1;
-
- __END__
-
-CPAN_DISTNAMEINFO
-
-$fatpacked{"HTTP/Tiny.pm"} = <<'HTTP_TINY';
- # vim: ts=4 sts=4 sw=4 et:
- #
- # This file is part of HTTP-Tiny
- #
- # This software is copyright (c) 2011 by Christian Hansen.
- #
- # This is free software; you can redistribute it and/or modify it under
- # the same terms as the Perl 5 programming language system itself.
- #
- package HTTP::Tiny;
- BEGIN {
- $HTTP::Tiny::VERSION = '0.009';
- }
- use strict;
- use warnings;
- # ABSTRACT: A small, simple, correct HTTP/1.1 client
-
- use Carp ();
-
-
- my @attributes;
- BEGIN {
- @attributes = qw(agent default_headers max_redirect max_size proxy timeout);
- no strict 'refs';
- for my $accessor ( @attributes ) {
- *{$accessor} = sub {
- @_ > 1 ? $_[0]->{$accessor} = $_[1] : $_[0]->{$accessor};
- };
- }
- }
-
- sub new {
- my($class, %args) = @_;
- (my $agent = $class) =~ s{::}{-}g;
- my $self = {
- agent => $agent . "/" . ($class->VERSION || 0),
- max_redirect => 5,
- timeout => 60,
- };
- for my $key ( @attributes ) {
- $self->{$key} = $args{$key} if exists $args{$key}
- }
- return bless $self, $class;
- }
-
-
- sub get {
- my ($self, $url, $args) = @_;
- @_ == 2 || (@_ == 3 && ref $args eq 'HASH')
- or Carp::croak(q/Usage: $http->get(URL, [HASHREF])/);
- return $self->request('GET', $url, $args || {});
- }
-
-
- sub mirror {
- my ($self, $url, $file, $args) = @_;
- @_ == 3 || (@_ == 4 && ref $args eq 'HASH')
- or Carp::croak(q/Usage: $http->mirror(URL, FILE, [HASHREF])/);
- if ( -e $file and my $mtime = (stat($file))[9] ) {
- $args->{headers}{'if-modified-since'} ||= $self->_http_date($mtime);
- }
- my $tempfile = $file . int(rand(2**31));
- open my $fh, ">", $tempfile
- or Carp::croak(qq/Error: Could not open temporary file $tempfile for downloading: $!/);
- $args->{data_callback} = sub { print {$fh} $_[0] };
- my $response = $self->request('GET', $url, $args);
- close $fh
- or Carp::croak(qq/Error: Could not close temporary file $tempfile: $!/);
- if ( $response->{success} ) {
- rename $tempfile, $file
- or Carp::croak "Error replacing $file with $tempfile: $!\n";
- my $lm = $response->{headers}{'last-modified'};
- if ( $lm and my $mtime = $self->_parse_http_date($lm) ) {
- utime $mtime, $mtime, $file;
- }
- }
- $response->{success} ||= $response->{status} eq '304';
- unlink $tempfile;
- return $response;
- }
-
-
- my %idempotent = map { $_ => 1 } qw/GET HEAD PUT DELETE OPTIONS TRACE/;
-
- sub request {
- my ($self, $method, $url, $args) = @_;
- @_ == 3 || (@_ == 4 && ref $args eq 'HASH')
- or Carp::croak(q/Usage: $http->request(METHOD, URL, [HASHREF])/);
- $args ||= {}; # we keep some state in this during _request
-
- # RFC 2616 Section 8.1.4 mandates a single retry on broken socket
- my $response;
- for ( 0 .. 1 ) {
- $response = eval { $self->_request($method, $url, $args) };
- last unless $@ && $idempotent{$method}
- && $@ =~ m{^(?:Socket closed|Unexpected end)};
- }
-
- if (my $e = "$@") {
- $response = {
- success => q{},
- status => 599,
- reason => 'Internal Exception',
- content => $e,
- headers => {
- 'content-type' => 'text/plain',
- 'content-length' => length $e,
- }
- };
- }
- return $response;
- }
-
- my %DefaultPort = (
- http => 80,
- https => 443,
- );
-
- sub _request {
- my ($self, $method, $url, $args) = @_;
-
- my ($scheme, $host, $port, $path_query) = $self->_split_url($url);
-
- my $request = {
- method => $method,
- scheme => $scheme,
- host_port => ($port == $DefaultPort{$scheme} ? $host : "$host:$port"),
- uri => $path_query,
- headers => {},
- };
-
- my $handle = HTTP::Tiny::Handle->new(timeout => $self->{timeout});
-
- if ($self->{proxy}) {
- $request->{uri} = "$scheme://$request->{host_port}$path_query";
- croak(qq/HTTPS via proxy is not supported/)
- if $request->{scheme} eq 'https';
- $handle->connect(($self->_split_url($self->{proxy}))[0..2]);
- }
- else {
- $handle->connect($scheme, $host, $port);
- }
-
- $self->_prepare_headers_and_cb($request, $args);
- $handle->write_request($request);
-
- my $response;
- do { $response = $handle->read_response_header }
- until (substr($response->{status},0,1) ne '1');
-
- if ( my @redir_args = $self->_maybe_redirect($request, $response, $args) ) {
- $handle->close;
- return $self->_request(@redir_args, $args);
- }
-
- if ($method eq 'HEAD' || $response->{status} =~ /^[23]04/) {
- # response has no message body
- }
- else {
- my $data_cb = $self->_prepare_data_cb($response, $args);
- $handle->read_body($data_cb, $response);
- }
-
- $handle->close;
- $response->{success} = substr($response->{status},0,1) eq '2';
- return $response;
- }
-
- sub _prepare_headers_and_cb {
- my ($self, $request, $args) = @_;
-
- for ($self->{default_headers}, $args->{headers}) {
- next unless defined;
- while (my ($k, $v) = each %$_) {
- $request->{headers}{lc $k} = $v;
- }
- }
- $request->{headers}{'host'} = $request->{host_port};
- $request->{headers}{'connection'} = "close";
- $request->{headers}{'user-agent'} ||= $self->{agent};
-
- if (defined $args->{content}) {
- $request->{headers}{'content-type'} ||= "application/octet-stream";
- if (ref $args->{content} eq 'CODE') {
- $request->{headers}{'transfer-encoding'} = 'chunked'
- unless $request->{headers}{'content-length'}
- || $request->{headers}{'transfer-encoding'};
- $request->{cb} = $args->{content};
- }
- else {
- my $content = $args->{content};
- if ( $] ge '5.008' ) {
- utf8::downgrade($content, 1)
- or Carp::croak(q/Wide character in request message body/);
- }
- $request->{headers}{'content-length'} = length $content
- unless $request->{headers}{'content-length'}
- || $request->{headers}{'transfer-encoding'};
- $request->{cb} = sub { substr $content, 0, length $content, '' };
- }
- $request->{trailer_cb} = $args->{trailer_callback}
- if ref $args->{trailer_callback} eq 'CODE';
- }
- return;
- }
-
- sub _prepare_data_cb {
- my ($self, $response, $args) = @_;
- my $data_cb = $args->{data_callback};
- $response->{content} = '';
-
- if (!$data_cb || $response->{status} !~ /^2/) {
- if (defined $self->{max_size}) {
- $data_cb = sub {
- $_[1]->{content} .= $_[0];
- die(qq/Size of response body exceeds the maximum allowed of $self->{max_size}\n/)
- if length $_[1]->{content} > $self->{max_size};
- };
- }
- else {
- $data_cb = sub { $_[1]->{content} .= $_[0] };
- }
- }
- return $data_cb;
- }
-
- sub _maybe_redirect {
- my ($self, $request, $response, $args) = @_;
- my $headers = $response->{headers};
- my ($status, $method) = ($response->{status}, $request->{method});
- if (($status eq '303' or ($status =~ /^30[127]/ && $method =~ /^GET|HEAD$/))
- and $headers->{location}
- and ++$args->{redirects} <= $self->{max_redirect}
- ) {
- my $location = ($headers->{location} =~ /^\//)
- ? "$request->{scheme}://$request->{host_port}$headers->{location}"
- : $headers->{location} ;
- return (($status eq '303' ? 'GET' : $method), $location);
- }
- return;
- }
-
- sub _split_url {
- my $url = pop;
-
- # URI regex adapted from the URI module
- my ($scheme, $authority, $path_query) = $url =~ m<\A([^:/?#]+)://([^/?#]*)([^#]*)>
- or Carp::croak(qq/Cannot parse URL: '$url'/);
-
- $scheme = lc $scheme;
- $path_query = "/$path_query" unless $path_query =~ m<\A/>;
-
- my $host = (length($authority)) ? lc $authority : 'localhost';
- $host =~ s/\A[^@]*@//; # userinfo
- my $port = do {
- $host =~ s/:([0-9]*)\z// && length $1
- ? $1
- : ($scheme eq 'http' ? 80 : $scheme eq 'https' ? 443 : undef);
- };
-
- return ($scheme, $host, $port, $path_query);
- }
-
- # Date conversions adapted from HTTP::Date
- my $DoW = "Sun|Mon|Tue|Wed|Thu|Fri|Sat";
- my $MoY = "Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec";
- sub _http_date {
- my ($sec, $min, $hour, $mday, $mon, $year, $wday) = gmtime($_[1]);
- return sprintf("%s, %02d %s %04d %02d:%02d:%02d GMT",
- substr($DoW,$wday*4,3),
- $mday, substr($MoY,$mon*4,3), $year+1900,
- $hour, $min, $sec
- );
- }
-
- sub _parse_http_date {
- my ($self, $str) = @_;
- require Time::Local;
- my @tl_parts;
- if ($str =~ /^[SMTWF][a-z]+, +(\d{1,2}) ($MoY) +(\d\d\d\d) +(\d\d):(\d\d):(\d\d) +GMT$/) {
- @tl_parts = ($6, $5, $4, $1, (index($MoY,$2)/4), $3);
- }
- elsif ($str =~ /^[SMTWF][a-z]+, +(\d\d)-($MoY)-(\d{2,4}) +(\d\d):(\d\d):(\d\d) +GMT$/ ) {
- @tl_parts = ($6, $5, $4, $1, (index($MoY,$2)/4), $3);
- }
- elsif ($str =~ /^[SMTWF][a-z]+ +($MoY) +(\d{1,2}) +(\d\d):(\d\d):(\d\d) +(?:[^0-9]+ +)?(\d\d\d\d)$/ ) {
- @tl_parts = ($5, $4, $3, $2, (index($MoY,$1)/4), $6);
- }
- return eval {
- my $t = @tl_parts ? Time::Local::timegm(@tl_parts) : -1;
- $t < 0 ? undef : $t;
- };
- }
-
- package
- HTTP::Tiny::Handle; # hide from PAUSE/indexers
- use strict;
- use warnings;
-
- use Carp qw[croak];
- use Errno qw[EINTR EPIPE];
- use IO::Socket qw[SOCK_STREAM];
-
- sub BUFSIZE () { 32768 }
-
- my $Printable = sub {
- local $_ = shift;
- s/\r/\\r/g;
- s/\n/\\n/g;
- s/\t/\\t/g;
- s/([^\x20-\x7E])/sprintf('\\x%.2X', ord($1))/ge;
- $_;
- };
-
- my $Token = qr/[\x21\x23-\x27\x2A\x2B\x2D\x2E\x30-\x39\x41-\x5A\x5E-\x7A\x7C\x7E]/;
-
- sub new {
- my ($class, %args) = @_;
- return bless {
- rbuf => '',
- timeout => 60,
- max_line_size => 16384,
- max_header_lines => 64,
- %args
- }, $class;
- }
-
- my $ssl_verify_args = {
- check_cn => "when_only",
- wildcards_in_alt => "anywhere",
- wildcards_in_cn => "anywhere"
- };
-
- sub connect {
- @_ == 4 || croak(q/Usage: $handle->connect(scheme, host, port)/);
- my ($self, $scheme, $host, $port) = @_;
-
- if ( $scheme eq 'https' ) {
- eval "require IO::Socket::SSL"
- unless exists $INC{'IO/Socket/SSL.pm'};
- croak(qq/IO::Socket::SSL must be installed for https support\n/)
- unless $INC{'IO/Socket/SSL.pm'};
- }
- elsif ( $scheme ne 'http' ) {
- croak(qq/Unsupported URL scheme '$scheme'/);
- }
-
- $self->{fh} = 'IO::Socket::INET'->new(
- PeerHost => $host,
- PeerPort => $port,
- Proto => 'tcp',
- Type => SOCK_STREAM,
- Timeout => $self->{timeout}
- ) or croak(qq/Could not connect to '$host:$port': $@/);
-
- binmode($self->{fh})
- or croak(qq/Could not binmode() socket: '$!'/);
-
- if ( $scheme eq 'https') {
- IO::Socket::SSL->start_SSL($self->{fh});
- ref($self->{fh}) eq 'IO::Socket::SSL'
- or die(qq/SSL connection failed for $host\n/);
- $self->{fh}->verify_hostname( $host, $ssl_verify_args )
- or die(qq/SSL certificate not valid for $host\n/);
- }
-
- $self->{host} = $host;
- $self->{port} = $port;
-
- return $self;
- }
-
- sub close {
- @_ == 1 || croak(q/Usage: $handle->close()/);
- my ($self) = @_;
- CORE::close($self->{fh})
- or croak(qq/Could not close socket: '$!'/);
- }
-
- sub write {
- @_ == 2 || croak(q/Usage: $handle->write(buf)/);
- my ($self, $buf) = @_;
-
- if ( $] ge '5.008' ) {
- utf8::downgrade($buf, 1)
- or croak(q/Wide character in write()/);
- }
-
- my $len = length $buf;
- my $off = 0;
-
- local $SIG{PIPE} = 'IGNORE';
-
- while () {
- $self->can_write
- or croak(q/Timed out while waiting for socket to become ready for writing/);
- my $r = syswrite($self->{fh}, $buf, $len, $off);
- if (defined $r) {
- $len -= $r;
- $off += $r;
- last unless $len > 0;
- }
- elsif ($! == EPIPE) {
- croak(qq/Socket closed by remote server: $!/);
- }
- elsif ($! != EINTR) {
- croak(qq/Could not write to socket: '$!'/);
- }
- }
- return $off;
- }
-
- sub read {
- @_ == 2 || @_ == 3 || croak(q/Usage: $handle->read(len [, allow_partial])/);
- my ($self, $len, $allow_partial) = @_;
-
- my $buf = '';
- my $got = length $self->{rbuf};
-
- if ($got) {
- my $take = ($got < $len) ? $got : $len;
- $buf = substr($self->{rbuf}, 0, $take, '');
- $len -= $take;
- }
-
- while ($len > 0) {
- $self->can_read
- or croak(q/Timed out while waiting for socket to become ready for reading/);
- my $r = sysread($self->{fh}, $buf, $len, length $buf);
- if (defined $r) {
- last unless $r;
- $len -= $r;
- }
- elsif ($! != EINTR) {
- croak(qq/Could not read from socket: '$!'/);
- }
- }
- if ($len && !$allow_partial) {
- croak(q/Unexpected end of stream/);
- }
- return $buf;
- }
-
- sub readline {
- @_ == 1 || croak(q/Usage: $handle->readline()/);
- my ($self) = @_;
-
- while () {
- if ($self->{rbuf} =~ s/\A ([^\x0D\x0A]* \x0D?\x0A)//x) {
- return $1;
- }
- if (length $self->{rbuf} >= $self->{max_line_size}) {
- croak(qq/Line size exceeds the maximum allowed size of $self->{max_line_size}/);
- }
- $self->can_read
- or croak(q/Timed out while waiting for socket to become ready for reading/);
- my $r = sysread($self->{fh}, $self->{rbuf}, BUFSIZE, length $self->{rbuf});
- if (defined $r) {
- last unless $r;
- }
- elsif ($! != EINTR) {
- croak(qq/Could not read from socket: '$!'/);
- }
- }
- croak(q/Unexpected end of stream while looking for line/);
- }
-
- sub read_header_lines {
- @_ == 1 || @_ == 2 || croak(q/Usage: $handle->read_header_lines([headers])/);
- my ($self, $headers) = @_;
- $headers ||= {};
- my $lines = 0;
- my $val;
-
- while () {
- my $line = $self->readline;
-
- if (++$lines >= $self->{max_header_lines}) {
- croak(qq/Header lines exceeds maximum number allowed of $self->{max_header_lines}/);
- }
- elsif ($line =~ /\A ([^\x00-\x1F\x7F:]+) : [\x09\x20]* ([^\x0D\x0A]*)/x) {
- my ($field_name) = lc $1;
- if (exists $headers->{$field_name}) {
- for ($headers->{$field_name}) {
- $_ = [$_] unless ref $_ eq "ARRAY";
- push @$_, $2;
- $val = \$_->[-1];
- }
- }
- else {
- $val = \($headers->{$field_name} = $2);
- }
- }
- elsif ($line =~ /\A [\x09\x20]+ ([^\x0D\x0A]*)/x) {
- $val
- or croak(q/Unexpected header continuation line/);
- next unless length $1;
- $$val .= ' ' if length $$val;
- $$val .= $1;
- }
- elsif ($line =~ /\A \x0D?\x0A \z/x) {
- last;
- }
- else {
- croak(q/Malformed header line: / . $Printable->($line));
- }
- }
- return $headers;
- }
-
- sub write_request {
- @_ == 2 || croak(q/Usage: $handle->write_request(request)/);
- my($self, $request) = @_;
- $self->write_request_header(@{$request}{qw/method uri headers/});
- $self->write_body($request) if $request->{cb};
- return;
- }
-
- my %HeaderCase = (
- 'content-md5' => 'Content-MD5',
- 'etag' => 'ETag',
- 'te' => 'TE',
- 'www-authenticate' => 'WWW-Authenticate',
- 'x-xss-protection' => 'X-XSS-Protection',
- );
-
- sub write_header_lines {
- (@_ == 2 && ref $_[1] eq 'HASH') || croak(q/Usage: $handle->write_header_lines(headers)/);
- my($self, $headers) = @_;
-
- my $buf = '';
- while (my ($k, $v) = each %$headers) {
- my $field_name = lc $k;
- if (exists $HeaderCase{$field_name}) {
- $field_name = $HeaderCase{$field_name};
- }
- else {
- $field_name =~ /\A $Token+ \z/xo
- or croak(q/Invalid HTTP header field name: / . $Printable->($field_name));
- $field_name =~ s/\b(\w)/\u$1/g;
- $HeaderCase{lc $field_name} = $field_name;
- }
- for (ref $v eq 'ARRAY' ? @$v : $v) {
- /[^\x0D\x0A]/
- or croak(qq/Invalid HTTP header field value ($field_name): / . $Printable->($_));
- $buf .= "$field_name: $_\x0D\x0A";
- }
- }
- $buf .= "\x0D\x0A";
- return $self->write($buf);
- }
-
- sub read_body {
- @_ == 3 || croak(q/Usage: $handle->read_body(callback, response)/);
- my ($self, $cb, $response) = @_;
- my $te = $response->{headers}{'transfer-encoding'} || '';
- if ( grep { /chunked/i } ( ref $te eq 'ARRAY' ? @$te : $te ) ) {
- $self->read_chunked_body($cb, $response);
- }
- else {
- $self->read_content_body($cb, $response);
- }
- return;
- }
-
- sub write_body {
- @_ == 2 || croak(q/Usage: $handle->write_body(request)/);
- my ($self, $request) = @_;
- if ($request->{headers}{'content-length'}) {
- return $self->write_content_body($request);
- }
- else {
- return $self->write_chunked_body($request);
- }
- }
-
- sub read_content_body {
- @_ == 3 || @_ == 4 || croak(q/Usage: $handle->read_content_body(callback, response, [read_length])/);
- my ($self, $cb, $response, $content_length) = @_;
- $content_length ||= $response->{headers}{'content-length'};
-
- if ( $content_length ) {
- my $len = $content_length;
- while ($len > 0) {
- my $read = ($len > BUFSIZE) ? BUFSIZE : $len;
- $cb->($self->read($read, 0), $response);
- $len -= $read;
- }
- }
- else {
- my $chunk;
- $cb->($chunk, $response) while length( $chunk = $self->read(BUFSIZE, 1) );
- }
-
- return;
- }
-
- sub write_content_body {
- @_ == 2 || croak(q/Usage: $handle->write_content_body(request)/);
- my ($self, $request) = @_;
-
- my ($len, $content_length) = (0, $request->{headers}{'content-length'});
- while () {
- my $data = $request->{cb}->();
-
- defined $data && length $data
- or last;
-
- if ( $] ge '5.008' ) {
- utf8::downgrade($data, 1)
- or croak(q/Wide character in write_content()/);
- }
-
- $len += $self->write($data);
- }
-
- $len == $content_length
- or croak(qq/Content-Length missmatch (got: $len expected: $content_length)/);
-
- return $len;
- }
-
- sub read_chunked_body {
- @_ == 3 || croak(q/Usage: $handle->read_chunked_body(callback, $response)/);
- my ($self, $cb, $response) = @_;
-
- while () {
- my $head = $self->readline;
-
- $head =~ /\A ([A-Fa-f0-9]+)/x
- or croak(q/Malformed chunk head: / . $Printable->($head));
-
- my $len = hex($1)
- or last;
-
- $self->read_content_body($cb, $response, $len);
-
- $self->read(2) eq "\x0D\x0A"
- or croak(q/Malformed chunk: missing CRLF after chunk data/);
- }
- $self->read_header_lines($response->{headers});
- return;
- }
-
- sub write_chunked_body {
- @_ == 2 || croak(q/Usage: $handle->write_chunked_body(request)/);
- my ($self, $request) = @_;
-
- my $len = 0;
- while () {
- my $data = $request->{cb}->();
-
- defined $data && length $data
- or last;
-
- if ( $] ge '5.008' ) {
- utf8::downgrade($data, 1)
- or croak(q/Wide character in write_chunked_body()/);
- }
-
- $len += length $data;
-
- my $chunk = sprintf '%X', length $data;
- $chunk .= "\x0D\x0A";
- $chunk .= $data;
- $chunk .= "\x0D\x0A";
-
- $self->write($chunk);
- }
- $self->write("0\x0D\x0A");
- $self->write_header_lines($request->{trailer_cb}->())
- if ref $request->{trailer_cb} eq 'CODE';
- return $len;
- }
-
- sub read_response_header {
- @_ == 1 || croak(q/Usage: $handle->read_response_header()/);
- my ($self) = @_;
-
- my $line = $self->readline;
-
- $line =~ /\A (HTTP\/(0*\d+\.0*\d+)) [\x09\x20]+ ([0-9]{3}) [\x09\x20]+ ([^\x0D\x0A]*) \x0D?\x0A/x
- or croak(q/Malformed Status-Line: / . $Printable->($line));
-
- my ($protocol, $version, $status, $reason) = ($1, $2, $3, $4);
-
- croak (qq/Unsupported HTTP protocol: $protocol/)
- unless $version =~ /0*1\.0*[01]/;
-
- return {
- status => $status,
- reason => $reason,
- headers => $self->read_header_lines,
- protocol => $protocol,
- };
- }
-
- sub write_request_header {
- @_ == 4 || croak(q/Usage: $handle->write_request_header(method, request_uri, headers)/);
- my ($self, $method, $request_uri, $headers) = @_;
-
- return $self->write("$method $request_uri HTTP/1.1\x0D\x0A")
- + $self->write_header_lines($headers);
- }
-
- sub _do_timeout {
- my ($self, $type, $timeout) = @_;
- $timeout = $self->{timeout}
- unless defined $timeout && $timeout >= 0;
-
- my $fd = fileno $self->{fh};
- defined $fd && $fd >= 0
- or croak(q/select(2): 'Bad file descriptor'/);
-
- my $initial = time;
- my $pending = $timeout;
- my $nfound;
-
- vec(my $fdset = '', $fd, 1) = 1;
-
- while () {
- $nfound = ($type eq 'read')
- ? select($fdset, undef, undef, $pending)
- : select(undef, $fdset, undef, $pending) ;
- if ($nfound == -1) {
- $! == EINTR
- or croak(qq/select(2): '$!'/);
- redo if !$timeout || ($pending = $timeout - (time - $initial)) > 0;
- $nfound = 0;
- }
- last;
- }
- $! = 0;
- return $nfound;
- }
-
- sub can_read {
- @_ == 1 || @_ == 2 || croak(q/Usage: $handle->can_read([timeout])/);
- my $self = shift;
- return $self->_do_timeout('read', @_)
- }
-
- sub can_write {
- @_ == 1 || @_ == 2 || croak(q/Usage: $handle->can_write([timeout])/);
- my $self = shift;
- return $self->_do_timeout('write', @_)
- }
-
- 1;
-
-
-
- __END__
- =pod
-
-HTTP_TINY
-
-$fatpacked{"Module/Metadata.pm"} = <<'MODULE_METADATA';
- # -*- mode: cperl; tab-width: 8; indent-tabs-mode: nil; basic-offset: 2 -*-
- # vim:ts=8:sw=2:et:sta:sts=2
- package Module::Metadata;
-
- # Adapted from Perl-licensed code originally distributed with
- # Module-Build by Ken Williams
-
- # This module provides routines to gather information about
- # perl modules (assuming this may be expanded in the distant
- # parrot future to look at other types of modules).
-
- use strict;
- use vars qw($VERSION);
- $VERSION = '1.000003';
- $VERSION = eval $VERSION;
-
- use File::Spec;
- use IO::File;
- use version 0.87;
- BEGIN {
- if ($INC{'Log/Contextual.pm'}) {
- Log::Contextual->import('log_info');
- } else {
- *log_info = sub (&) { warn $_[0]->() };
- }
- }
- use File::Find qw(find);
-
- my $V_NUM_REGEXP = qr{v?[0-9._]+}; # crudely, a v-string or decimal
-
- my $PKG_REGEXP = qr{ # match a package declaration
- ^[\s\{;]* # intro chars on a line
- package # the word 'package'
- \s+ # whitespace
- ([\w:]+) # a package name
- \s* # optional whitespace
- ($V_NUM_REGEXP)? # optional version number
- \s* # optional whitesapce
- ; # semicolon line terminator
- }x;
-
- my $VARNAME_REGEXP = qr{ # match fully-qualified VERSION name
- ([\$*]) # sigil - $ or *
- (
- ( # optional leading package name
- (?:::|\')? # possibly starting like just :: (Ì la $::VERSION)
- (?:\w+(?:::|\'))* # Foo::Bar:: ...
- )?
- VERSION
- )\b
- }x;
-
- my $VERS_REGEXP = qr{ # match a VERSION definition
- (?:
- \(\s*$VARNAME_REGEXP\s*\) # with parens
- |
- $VARNAME_REGEXP # without parens
- )
- \s*
- =[^=~] # = but not ==, nor =~
- }x;
-
-
- sub new_from_file {
- my $class = shift;
- my $filename = File::Spec->rel2abs( shift );
-
- return undef unless defined( $filename ) && -f $filename;
- return $class->_init(undef, $filename, @_);
- }
-
- sub new_from_module {
- my $class = shift;
- my $module = shift;
- my %props = @_;
-
- $props{inc} ||= \@INC;
- my $filename = $class->find_module_by_name( $module, $props{inc} );
- return undef unless defined( $filename ) && -f $filename;
- return $class->_init($module, $filename, %props);
- }
-
- {
-
- my $compare_versions = sub {
- my ($v1, $op, $v2) = @_;
- $v1 = version->new($v1)
- unless UNIVERSAL::isa($v1,'version');
-
- my $eval_str = "\$v1 $op \$v2";
- my $result = eval $eval_str;
- log_info { "error comparing versions: '$eval_str' $@" } if $@;
-
- return $result;
- };
-
- my $normalize_version = sub {
- my ($version) = @_;
- if ( $version =~ /[=<>!,]/ ) { # logic, not just version
- # take as is without modification
- }
- elsif ( ref $version eq 'version' ) { # version objects
- $version = $version->is_qv ? $version->normal : $version->stringify;
- }
- elsif ( $version =~ /^[^v][^.]*\.[^.]+\./ ) { # no leading v, multiple dots
- # normalize string tuples without "v": "1.2.3" -> "v1.2.3"
- $version = "v$version";
- }
- else {
- # leave alone
- }
- return $version;
- };
-
- # separate out some of the conflict resolution logic
-
- my $resolve_module_versions = sub {
- my $packages = shift;
-
- my( $file, $version );
- my $err = '';
- foreach my $p ( @$packages ) {
- if ( defined( $p->{version} ) ) {
- if ( defined( $version ) ) {
- if ( $compare_versions->( $version, '!=', $p->{version} ) ) {
- $err .= " $p->{file} ($p->{version})\n";
- } else {
- # same version declared multiple times, ignore
- }
- } else {
- $file = $p->{file};
- $version = $p->{version};
- }
- }
- $file ||= $p->{file} if defined( $p->{file} );
- }
-
- if ( $err ) {
- $err = " $file ($version)\n" . $err;
- }
-
- my %result = (
- file => $file,
- version => $version,
- err => $err
- );
-
- return \%result;
- };
-
- sub package_versions_from_directory {
- my ( $class, $dir, $files ) = @_;
-
- my @files;
-
- if ( $files ) {
- @files = @$files;
- } else {
- find( {
- wanted => sub {
- push @files, $_ if -f $_ && /\.pm$/;
- },
- no_chdir => 1,
- }, $dir );
- }
-
- # First, we enumerate all packages & versions,
- # separating into primary & alternative candidates
- my( %prime, %alt );
- foreach my $file (@files) {
- my $mapped_filename = File::Spec->abs2rel( $file, $dir );
- my @path = split( /\//, $mapped_filename );
- (my $prime_package = join( '::', @path )) =~ s/\.pm$//;
-
- my $pm_info = $class->new_from_file( $file );
-
- foreach my $package ( $pm_info->packages_inside ) {
- next if $package eq 'main'; # main can appear numerous times, ignore
- next if $package eq 'DB'; # special debugging package, ignore
- next if grep /^_/, split( /::/, $package ); # private package, ignore
-
- my $version = $pm_info->version( $package );
-
- if ( $package eq $prime_package ) {
- if ( exists( $prime{$package} ) ) {
- # M::B::ModuleInfo will handle this conflict
- die "Unexpected conflict in '$package'; multiple versions found.\n";
- } else {
- $prime{$package}{file} = $mapped_filename;
- $prime{$package}{version} = $version if defined( $version );
- }
- } else {
- push( @{$alt{$package}}, {
- file => $mapped_filename,
- version => $version,
- } );
- }
- }
- }
-
- # Then we iterate over all the packages found above, identifying conflicts
- # and selecting the "best" candidate for recording the file & version
- # for each package.
- foreach my $package ( keys( %alt ) ) {
- my $result = $resolve_module_versions->( $alt{$package} );
-
- if ( exists( $prime{$package} ) ) { # primary package selected
-
- if ( $result->{err} ) {
- # Use the selected primary package, but there are conflicting
- # errors among multiple alternative packages that need to be
- # reported
- log_info {
- "Found conflicting versions for package '$package'\n" .
- " $prime{$package}{file} ($prime{$package}{version})\n" .
- $result->{err}
- };
-
- } elsif ( defined( $result->{version} ) ) {
- # There is a primary package selected, and exactly one
- # alternative package
-
- if ( exists( $prime{$package}{version} ) &&
- defined( $prime{$package}{version} ) ) {
- # Unless the version of the primary package agrees with the
- # version of the alternative package, report a conflict
- if ( $compare_versions->(
- $prime{$package}{version}, '!=', $result->{version}
- )
- ) {
-
- log_info {
- "Found conflicting versions for package '$package'\n" .
- " $prime{$package}{file} ($prime{$package}{version})\n" .
- " $result->{file} ($result->{version})\n"
- };
- }
-
- } else {
- # The prime package selected has no version so, we choose to
- # use any alternative package that does have a version
- $prime{$package}{file} = $result->{file};
- $prime{$package}{version} = $result->{version};
- }
-
- } else {
- # no alt package found with a version, but we have a prime
- # package so we use it whether it has a version or not
- }
-
- } else { # No primary package was selected, use the best alternative
-
- if ( $result->{err} ) {
- log_info {
- "Found conflicting versions for package '$package'\n" .
- $result->{err}
- };
- }
-
- # Despite possible conflicting versions, we choose to record
- # something rather than nothing
- $prime{$package}{file} = $result->{file};
- $prime{$package}{version} = $result->{version}
- if defined( $result->{version} );
- }
- }
-
- # Normalize versions. Can't use exists() here because of bug in YAML::Node.
- # XXX "bug in YAML::Node" comment seems irrelvant -- dagolden, 2009-05-18
- for (grep defined $_->{version}, values %prime) {
- $_->{version} = $normalize_version->( $_->{version} );
- }
-
- return \%prime;
- }
- }
-
-
- sub _init {
- my $class = shift;
- my $module = shift;
- my $filename = shift;
- my %props = @_;
-
- my( %valid_props, @valid_props );
- @valid_props = qw( collect_pod inc );
- @valid_props{@valid_props} = delete( @props{@valid_props} );
- warn "Unknown properties: @{[keys %props]}\n" if scalar( %props );
-
- my %data = (
- module => $module,
- filename => $filename,
- version => undef,
- packages => [],
- versions => {},
- pod => {},
- pod_headings => [],
- collect_pod => 0,
-
- %valid_props,
- );
-
- my $self = bless(\%data, $class);
-
- $self->_parse_file();
-
- unless($self->{module} and length($self->{module})) {
- my ($v, $d, $f) = File::Spec->splitpath($self->{filename});
- if($f =~ /\.pm$/) {
- $f =~ s/\..+$//;
- my @candidates = grep /$f$/, @{$self->{packages}};
- $self->{module} = shift(@candidates); # punt
- }
- else {
- if(grep /main/, @{$self->{packages}}) {
- $self->{module} = 'main';
- }
- else {
- $self->{module} = $self->{packages}[0] || '';
- }
- }
- }
-
- $self->{version} = $self->{versions}{$self->{module}}
- if defined( $self->{module} );
-
- return $self;
- }
-
- # class method
- sub _do_find_module {
- my $class = shift;
- my $module = shift || die 'find_module_by_name() requires a package name';
- my $dirs = shift || \@INC;
-
- my $file = File::Spec->catfile(split( /::/, $module));
- foreach my $dir ( @$dirs ) {
- my $testfile = File::Spec->catfile($dir, $file);
- return [ File::Spec->rel2abs( $testfile ), $dir ]
- if -e $testfile and !-d _; # For stuff like ExtUtils::xsubpp
- return [ File::Spec->rel2abs( "$testfile.pm" ), $dir ]
- if -e "$testfile.pm";
- }
- return;
- }
-
- # class method
- sub find_module_by_name {
- my $found = shift()->_do_find_module(@_) or return;
- return $found->[0];
- }
-
- # class method
- sub find_module_dir_by_name {
- my $found = shift()->_do_find_module(@_) or return;
- return $found->[1];
- }
-
-
- # given a line of perl code, attempt to parse it if it looks like a
- # $VERSION assignment, returning sigil, full name, & package name
- sub _parse_version_expression {
- my $self = shift;
- my $line = shift;
-
- my( $sig, $var, $pkg );
- if ( $line =~ $VERS_REGEXP ) {
- ( $sig, $var, $pkg ) = $2 ? ( $1, $2, $3 ) : ( $4, $5, $6 );
- if ( $pkg ) {
- $pkg = ($pkg eq '::') ? 'main' : $pkg;
- $pkg =~ s/::$//;
- }
- }
-
- return ( $sig, $var, $pkg );
- }
-
- sub _parse_file {
- my $self = shift;
-
- my $filename = $self->{filename};
- my $fh = IO::File->new( $filename )
- or die( "Can't open '$filename': $!" );
-
- $self->_parse_fh($fh);
- }
-
- sub _parse_fh {
- my ($self, $fh) = @_;
-
- my( $in_pod, $seen_end, $need_vers ) = ( 0, 0, 0 );
- my( @pkgs, %vers, %pod, @pod );
- my $pkg = 'main';
- my $pod_sect = '';
- my $pod_data = '';
-
- while (defined( my $line = <$fh> )) {
- my $line_num = $.;
-
- chomp( $line );
- next if $line =~ /^\s*#/;
-
- $in_pod = ($line =~ /^=(?!cut)/) ? 1 : ($line =~ /^=cut/) ? 0 : $in_pod;
-
- # Would be nice if we could also check $in_string or something too
- last if !$in_pod && $line =~ /^__(?:DATA|END)__$/;
-
- if ( $in_pod || $line =~ /^=cut/ ) {
-
- if ( $line =~ /^=head\d\s+(.+)\s*$/ ) {
- push( @pod, $1 );
- if ( $self->{collect_pod} && length( $pod_data ) ) {
- $pod{$pod_sect} = $pod_data;
- $pod_data = '';
- }
- $pod_sect = $1;
-
-
- } elsif ( $self->{collect_pod} ) {
- $pod_data .= "$line\n";
-
- }
-
- } else {
-
- $pod_sect = '';
- $pod_data = '';
-
- # parse $line to see if it's a $VERSION declaration
- my( $vers_sig, $vers_fullname, $vers_pkg ) =
- $self->_parse_version_expression( $line );
-
- if ( $line =~ $PKG_REGEXP ) {
- $pkg = $1;
- push( @pkgs, $pkg ) unless grep( $pkg eq $_, @pkgs );
- $vers{$pkg} = (defined $2 ? $2 : undef) unless exists( $vers{$pkg} );
- $need_vers = defined $2 ? 0 : 1;
-
- # VERSION defined with full package spec, i.e. $Module::VERSION
- } elsif ( $vers_fullname && $vers_pkg ) {
- push( @pkgs, $vers_pkg ) unless grep( $vers_pkg eq $_, @pkgs );
- $need_vers = 0 if $vers_pkg eq $pkg;
-
- unless ( defined $vers{$vers_pkg} && length $vers{$vers_pkg} ) {
- $vers{$vers_pkg} =
- $self->_evaluate_version_line( $vers_sig, $vers_fullname, $line );
- } else {
- # Warn unless the user is using the "$VERSION = eval
- # $VERSION" idiom (though there are probably other idioms
- # that we should watch out for...)
- warn <<"EOM" unless $line =~ /=\s*eval/;
- Package '$vers_pkg' already declared with version '$vers{$vers_pkg}',
- ignoring subsequent declaration on line $line_num.
- EOM
- }
-
- # first non-comment line in undeclared package main is VERSION
- } elsif ( !exists($vers{main}) && $pkg eq 'main' && $vers_fullname ) {
- $need_vers = 0;
- my $v =
- $self->_evaluate_version_line( $vers_sig, $vers_fullname, $line );
- $vers{$pkg} = $v;
- push( @pkgs, 'main' );
-
- # first non-comment line in undeclared package defines package main
- } elsif ( !exists($vers{main}) && $pkg eq 'main' && $line =~ /\w+/ ) {
- $need_vers = 1;
- $vers{main} = '';
- push( @pkgs, 'main' );
-
- # only keep if this is the first $VERSION seen
- } elsif ( $vers_fullname && $need_vers ) {
- $need_vers = 0;
- my $v =
- $self->_evaluate_version_line( $vers_sig, $vers_fullname, $line );
-
-
- unless ( defined $vers{$pkg} && length $vers{$pkg} ) {
- $vers{$pkg} = $v;
- } else {
- warn <<"EOM";
- Package '$pkg' already declared with version '$vers{$pkg}'
- ignoring new version '$v' on line $line_num.
- EOM
- }
-
- }
-
- }
-
- }
-
- if ( $self->{collect_pod} && length($pod_data) ) {
- $pod{$pod_sect} = $pod_data;
- }
-
- $self->{versions} = \%vers;
- $self->{packages} = \@pkgs;
- $self->{pod} = \%pod;
- $self->{pod_headings} = \@pod;
- }
-
- {
- my $pn = 0;
- sub _evaluate_version_line {
- my $self = shift;
- my( $sigil, $var, $line ) = @_;
-
- # Some of this code came from the ExtUtils:: hierarchy.
-
- # We compile into $vsub because 'use version' would cause
- # compiletime/runtime issues with local()
- my $vsub;
- $pn++; # everybody gets their own package
- my $eval = qq{BEGIN { q# Hide from _packages_inside()
- #; package Module::Metadata::_version::p$pn;
- use version;
- no strict;
-
- local $sigil$var;
- \$$var=undef;
- \$vsub = sub {
- $line;
- \$$var
- };
- }};
-
- local $^W;
- # Try to get the $VERSION
- eval $eval;
- # some modules say $VERSION = $Foo::Bar::VERSION, but Foo::Bar isn't
- # installed, so we need to hunt in ./lib for it
- if ( $@ =~ /Can't locate/ && -d 'lib' ) {
- local @INC = ('lib',@INC);
- eval $eval;
- }
- warn "Error evaling version line '$eval' in $self->{filename}: $@\n"
- if $@;
- (ref($vsub) eq 'CODE') or
- die "failed to build version sub for $self->{filename}";
- my $result = eval { $vsub->() };
- die "Could not get version from $self->{filename} by executing:\n$eval\n\nThe fatal error was: $@\n"
- if $@;
-
- # Upgrade it into a version object
- my $version = eval { _dwim_version($result) };
-
- die "Version '$result' from $self->{filename} does not appear to be valid:\n$eval\n\nThe fatal error was: $@\n"
- unless defined $version; # "0" is OK!
-
- return $version;
- }
- }
-
- # Try to DWIM when things fail the lax version test in obvious ways
- {
- my @version_prep = (
- # Best case, it just works
- sub { return shift },
-
- # If we still don't have a version, try stripping any
- # trailing junk that is prohibited by lax rules
- sub {
- my $v = shift;
- $v =~ s{([0-9])[a-z-].*$}{$1}i; # 1.23-alpha or 1.23b
- return $v;
- },
-
- # Activestate apparently creates custom versions like '1.23_45_01', which
- # cause version.pm to think it's an invalid alpha. So check for that
- # and strip them
- sub {
- my $v = shift;
- my $num_dots = () = $v =~ m{(\.)}g;
- my $num_unders = () = $v =~ m{(_)}g;
- my $leading_v = substr($v,0,1) eq 'v';
- if ( ! $leading_v && $num_dots < 2 && $num_unders > 1 ) {
- $v =~ s{_}{}g;
- $num_unders = () = $v =~ m{(_)}g;
- }
- return $v;
- },
-
- # Worst case, try numifying it like we would have before version objects
- sub {
- my $v = shift;
- no warnings 'numeric';
- return 0 + $v;
- },
-
- );
-
- sub _dwim_version {
- my ($result) = shift;
-
- return $result if ref($result) eq 'version';
-
- my ($version, $error);
- for my $f (@version_prep) {
- $result = $f->($result);
- $version = eval { version->new($result) };
- $error ||= $@ if $@; # capture first failure
- last if defined $version;
- }
-
- die $error unless defined $version;
-
- return $version;
- }
- }
-
- ############################################################
-
- # accessors
- sub name { $_[0]->{module} }
-
- sub filename { $_[0]->{filename} }
- sub packages_inside { @{$_[0]->{packages}} }
- sub pod_inside { @{$_[0]->{pod_headings}} }
- sub contains_pod { $#{$_[0]->{pod_headings}} }
-
- sub version {
- my $self = shift;
- my $mod = shift || $self->{module};
- my $vers;
- if ( defined( $mod ) && length( $mod ) &&
- exists( $self->{versions}{$mod} ) ) {
- return $self->{versions}{$mod};
- } else {
- return undef;
- }
- }
-
- sub pod {
- my $self = shift;
- my $sect = shift;
- if ( defined( $sect ) && length( $sect ) &&
- exists( $self->{pod}{$sect} ) ) {
- return $self->{pod}{$sect};
- } else {
- return undef;
- }
- }
-
- 1;
-
-MODULE_METADATA
-
-$fatpacked{"Parse/CPAN/Meta.pm"} = <<'PARSE_CPAN_META';
- package Parse::CPAN::Meta;
-
- use strict;
- use Carp 'croak';
-
- # UTF Support?
- sub HAVE_UTF8 () { $] >= 5.007003 }
- BEGIN {
- if ( HAVE_UTF8 ) {
- # The string eval helps hide this from Test::MinimumVersion
- eval "require utf8;";
- die "Failed to load UTF-8 support" if $@;
- }
-
- # Class structure
- require 5.004;
- require Exporter;
- $Parse::CPAN::Meta::VERSION = '1.40';
- @Parse::CPAN::Meta::ISA = qw{ Exporter };
- @Parse::CPAN::Meta::EXPORT_OK = qw{ Load LoadFile };
- }
-
- # Prototypes
- sub LoadFile ($);
- sub Load ($);
- sub _scalar ($$$);
- sub _array ($$$);
- sub _hash ($$$);
-
- # Printable characters for escapes
- my %UNESCAPES = (
- z => "\x00", a => "\x07", t => "\x09",
- n => "\x0a", v => "\x0b", f => "\x0c",
- r => "\x0d", e => "\x1b", '\\' => '\\',
- );
-
-
-
-
-
- #####################################################################
- # Implementation
-
- # Create an object from a file
- sub LoadFile ($) {
- # Check the file
- my $file = shift;
- croak('You did not specify a file name') unless $file;
- croak( "File '$file' does not exist" ) unless -e $file;
- croak( "'$file' is a directory, not a file" ) unless -f _;
- croak( "Insufficient permissions to read '$file'" ) unless -r _;
-
- # Slurp in the file
- local $/ = undef;
- local *CFG;
- unless ( open( CFG, $file ) ) {
- croak("Failed to open file '$file': $!");
- }
- my $yaml = <CFG>;
- unless ( close(CFG) ) {
- croak("Failed to close file '$file': $!");
- }
-
- # Hand off to the actual parser
- Load( $yaml );
- }
-
- # Parse a document from a string.
- # Doing checks on $_[0] prevents us having to do a string copy.
- sub Load ($) {
- my $string = $_[0];
- unless ( defined $string ) {
- croak("Did not provide a string to load");
- }
-
- # Byte order marks
- if ( $string =~ /^(?:\376\377|\377\376|\377\376\0\0|\0\0\376\377)/ ) {
- croak("Stream has a non UTF-8 Unicode Byte Order Mark");
- } else {
- # Strip UTF-8 bom if found, we'll just ignore it
- $string =~ s/^\357\273\277//;
- }
-
- # Try to decode as utf8
- utf8::decode($string) if HAVE_UTF8;
-
- # Check for some special cases
- return () unless length $string;
- unless ( $string =~ /[\012\015]+\z/ ) {
- croak("Stream does not end with newline character");
- }
-
- # Split the file into lines
- my @lines = grep { ! /^\s*(?:\#.*)?\z/ }
- split /(?:\015{1,2}\012|\015|\012)/, $string;
-
- # Strip the initial YAML header
- @lines and $lines[0] =~ /^\%YAML[: ][\d\.]+.*\z/ and shift @lines;
-
- # A nibbling parser
- my @documents = ();
- while ( @lines ) {
- # Do we have a document header?
- if ( $lines[0] =~ /^---\s*(?:(.+)\s*)?\z/ ) {
- # Handle scalar documents
- shift @lines;
- if ( defined $1 and $1 !~ /^(?:\#.+|\%YAML[: ][\d\.]+)\z/ ) {
- push @documents, _scalar( "$1", [ undef ], \@lines );
- next;
- }
- }
-
- if ( ! @lines or $lines[0] =~ /^(?:---|\.\.\.)/ ) {
- # A naked document
- push @documents, undef;
- while ( @lines and $lines[0] !~ /^---/ ) {
- shift @lines;
- }
-
- } elsif ( $lines[0] =~ /^\s*\-/ ) {
- # An array at the root
- my $document = [ ];
- push @documents, $document;
- _array( $document, [ 0 ], \@lines );
-
- } elsif ( $lines[0] =~ /^(\s*)\S/ ) {
- # A hash at the root
- my $document = { };
- push @documents, $document;
- _hash( $document, [ length($1) ], \@lines );
-
- } else {
- croak("Parse::CPAN::Meta failed to classify line '$lines[0]'");
- }
- }
-
- if ( wantarray ) {
- return @documents;
- } else {
- return $documents[-1];
- }
- }
-
- # Deparse a scalar string to the actual scalar
- sub _scalar ($$$) {
- my ($string, $indent, $lines) = @_;
-
- # Trim trailing whitespace
- $string =~ s/\s*\z//;
-
- # Explitic null/undef
- return undef if $string eq '~';
-
- # Quotes
- if ( $string =~ /^\'(.*?)\'\z/ ) {
- return '' unless defined $1;
- $string = $1;
- $string =~ s/\'\'/\'/g;
- return $string;
- }
- if ( $string =~ /^\"((?:\\.|[^\"])*)\"\z/ ) {
- # Reusing the variable is a little ugly,
- # but avoids a new variable and a string copy.
- $string = $1;
- $string =~ s/\\"/"/g;
- $string =~ s/\\([never\\fartz]|x([0-9a-fA-F]{2}))/(length($1)>1)?pack("H2",$2):$UNESCAPES{$1}/gex;
- return $string;
- }
-
- # Special cases
- if ( $string =~ /^[\'\"!&]/ ) {
- croak("Parse::CPAN::Meta does not support a feature in line '$lines->[0]'");
- }
- return {} if $string eq '{}';
- return [] if $string eq '[]';
-
- # Regular unquoted string
- return $string unless $string =~ /^[>|]/;
-
- # Error
- croak("Parse::CPAN::Meta failed to find multi-line scalar content") unless @$lines;
-
- # Check the indent depth
- $lines->[0] =~ /^(\s*)/;
- $indent->[-1] = length("$1");
- if ( defined $indent->[-2] and $indent->[-1] <= $indent->[-2] ) {
- croak("Parse::CPAN::Meta found bad indenting in line '$lines->[0]'");
- }
-
- # Pull the lines
- my @multiline = ();
- while ( @$lines ) {
- $lines->[0] =~ /^(\s*)/;
- last unless length($1) >= $indent->[-1];
- push @multiline, substr(shift(@$lines), length($1));
- }
-
- my $j = (substr($string, 0, 1) eq '>') ? ' ' : "\n";
- my $t = (substr($string, 1, 1) eq '-') ? '' : "\n";
- return join( $j, @multiline ) . $t;
- }
-
- # Parse an array
- sub _array ($$$) {
- my ($array, $indent, $lines) = @_;
-
- while ( @$lines ) {
- # Check for a new document
- if ( $lines->[0] =~ /^(?:---|\.\.\.)/ ) {
- while ( @$lines and $lines->[0] !~ /^---/ ) {
- shift @$lines;
- }
- return 1;
- }
-
- # Check the indent level
- $lines->[0] =~ /^(\s*)/;
- if ( length($1) < $indent->[-1] ) {
- return 1;
- } elsif ( length($1) > $indent->[-1] ) {
- croak("Parse::CPAN::Meta found bad indenting in line '$lines->[0]'");
- }
-
- if ( $lines->[0] =~ /^(\s*\-\s+)[^\'\"]\S*\s*:(?:\s+|$)/ ) {
- # Inline nested hash
- my $indent2 = length("$1");
- $lines->[0] =~ s/-/ /;
- push @$array, { };
- _hash( $array->[-1], [ @$indent, $indent2 ], $lines );
-
- } elsif ( $lines->[0] =~ /^\s*\-(\s*)(.+?)\s*\z/ ) {
- # Array entry with a value
- shift @$lines;
- push @$array, _scalar( "$2", [ @$indent, undef ], $lines );
-
- } elsif ( $lines->[0] =~ /^\s*\-\s*\z/ ) {
- shift @$lines;
- unless ( @$lines ) {
- push @$array, undef;
- return 1;
- }
- if ( $lines->[0] =~ /^(\s*)\-/ ) {
- my $indent2 = length("$1");
- if ( $indent->[-1] == $indent2 ) {
- # Null array entry
- push @$array, undef;
- } else {
- # Naked indenter
- push @$array, [ ];
- _array( $array->[-1], [ @$indent, $indent2 ], $lines );
- }
-
- } elsif ( $lines->[0] =~ /^(\s*)\S/ ) {
- push @$array, { };
- _hash( $array->[-1], [ @$indent, length("$1") ], $lines );
-
- } else {
- croak("Parse::CPAN::Meta failed to classify line '$lines->[0]'");
- }
-
- } elsif ( defined $indent->[-2] and $indent->[-1] == $indent->[-2] ) {
- # This is probably a structure like the following...
- # ---
- # foo:
- # - list
- # bar: value
- #
- # ... so lets return and let the hash parser handle it
- return 1;
-
- } else {
- croak("Parse::CPAN::Meta failed to classify line '$lines->[0]'");
- }
- }
-
- return 1;
- }
-
- # Parse an array
- sub _hash ($$$) {
- my ($hash, $indent, $lines) = @_;
-
- while ( @$lines ) {
- # Check for a new document
- if ( $lines->[0] =~ /^(?:---|\.\.\.)/ ) {
- while ( @$lines and $lines->[0] !~ /^---/ ) {
- shift @$lines;
- }
- return 1;
- }
-
- # Check the indent level
- $lines->[0] =~ /^(\s*)/;
- if ( length($1) < $indent->[-1] ) {
- return 1;
- } elsif ( length($1) > $indent->[-1] ) {
- croak("Parse::CPAN::Meta found bad indenting in line '$lines->[0]'");
- }
-
- # Get the key
- unless ( $lines->[0] =~ s/^\s*([^\'\" ][^\n]*?)\s*:(\s+|$)// ) {
- if ( $lines->[0] =~ /^\s*[?\'\"]/ ) {
- croak("Parse::CPAN::Meta does not support a feature in line '$lines->[0]'");
- }
- croak("Parse::CPAN::Meta failed to classify line '$lines->[0]'");
- }
- my $key = $1;
-
- # Do we have a value?
- if ( length $lines->[0] ) {
- # Yes
- $hash->{$key} = _scalar( shift(@$lines), [ @$indent, undef ], $lines );
- } else {
- # An indent
- shift @$lines;
- unless ( @$lines ) {
- $hash->{$key} = undef;
- return 1;
- }
- if ( $lines->[0] =~ /^(\s*)-/ ) {
- $hash->{$key} = [];
- _array( $hash->{$key}, [ @$indent, length($1) ], $lines );
- } elsif ( $lines->[0] =~ /^(\s*)./ ) {
- my $indent2 = length("$1");
- if ( $indent->[-1] >= $indent2 ) {
- # Null hash entry
- $hash->{$key} = undef;
- } else {
- $hash->{$key} = {};
- _hash( $hash->{$key}, [ @$indent, length($1) ], $lines );
- }
- }
- }
- }
-
- return 1;
- }
-
- 1;
-
- __END__
-
-PARSE_CPAN_META
-
-$fatpacked{"lib/core/only.pm"} = <<'LIB_CORE_ONLY';
- package lib::core::only;
-
- use strict;
- use warnings FATAL => 'all';
- use Config;
-
- sub import {
- @INC = @Config{qw(privlibexp archlibexp)};
- return
- }
-
- 1;
-LIB_CORE_ONLY
-
-$fatpacked{"local/lib.pm"} = <<'LOCAL_LIB';
- use strict;
- use warnings;
-
- package local::lib;
-
- use 5.008001; # probably works with earlier versions but I'm not supporting them
- # (patches would, of course, be welcome)
-
- use File::Spec ();
- use File::Path ();
- use Carp ();
- use Config;
-
- our $VERSION = '1.008001'; # 1.8.1
-
- our @KNOWN_FLAGS = qw(--self-contained);
-
- sub import {
- my ($class, @args) = @_;
-
- # Remember what PERL5LIB was when we started
- my $perl5lib = $ENV{PERL5LIB} || '';
-
- my %arg_store;
- for my $arg (@args) {
- # check for lethal dash first to stop processing before causing problems
- if ($arg =~ /−/) {
- die <<'DEATH';
- WHOA THERE! It looks like you've got some fancy dashes in your commandline!
- These are *not* the traditional -- dashes that software recognizes. You
- probably got these by copy-pasting from the perldoc for this module as
- rendered by a UTF8-capable formatter. This most typically happens on an OS X
- terminal, but can happen elsewhere too. Please try again after replacing the
- dashes with normal minus signs.
- DEATH
- }
- elsif(grep { $arg eq $_ } @KNOWN_FLAGS) {
- (my $flag = $arg) =~ s/--//;
- $arg_store{$flag} = 1;
- }
- elsif($arg =~ /^--/) {
- die "Unknown import argument: $arg";
- }
- else {
- # assume that what's left is a path
- $arg_store{path} = $arg;
- }
- }
-
- if($arg_store{'self-contained'}) {
- die "FATAL: The local::lib --self-contained flag has never worked reliably and the original author, Mark Stosberg, was unable or unwilling to maintain it. As such, this flag has been removed from the local::lib codebase in order to prevent misunderstandings and potentially broken builds. The local::lib authors recommend that you look at the lib::core::only module shipped with this distribution in order to create a more robust environment that is equivalent to what --self-contained provided (although quite possibly not what you originally thought it provided due to the poor quality of the documentation, for which we apologise).\n";
- }
-
- $arg_store{path} = $class->resolve_path($arg_store{path});
- $class->setup_local_lib_for($arg_store{path});
-
- for (@INC) { # Untaint @INC
- next if ref; # Skip entry if it is an ARRAY, CODE, blessed, etc.
- m/(.*)/ and $_ = $1;
- }
- }
-
- sub pipeline;
-
- sub pipeline {
- my @methods = @_;
- my $last = pop(@methods);
- if (@methods) {
- \sub {
- my ($obj, @args) = @_;
- $obj->${pipeline @methods}(
- $obj->$last(@args)
- );
- };
- } else {
- \sub {
- shift->$last(@_);
- };
- }
- }
-
- sub _uniq {
- my %seen;
- grep { ! $seen{$_}++ } @_;
- }
-
- sub resolve_path {
- my ($class, $path) = @_;
- $class->${pipeline qw(
- resolve_relative_path
- resolve_home_path
- resolve_empty_path
- )}($path);
- }
-
- sub resolve_empty_path {
- my ($class, $path) = @_;
- if (defined $path) {
- $path;
- } else {
- '~/perl5';
- }
- }
-
- sub resolve_home_path {
- my ($class, $path) = @_;
- return $path unless ($path =~ /^~/);
- my ($user) = ($path =~ /^~([^\/]+)/); # can assume ^~ so undef for 'us'
- my $tried_file_homedir;
- my $homedir = do {
- if (eval { require File::HomeDir } && $File::HomeDir::VERSION >= 0.65) {
- $tried_file_homedir = 1;
- if (defined $user) {
- File::HomeDir->users_home($user);
- } else {
- File::HomeDir->my_home;
- }
- } else {
- if (defined $user) {
- (getpwnam $user)[7];
- } else {
- if (defined $ENV{HOME}) {
- $ENV{HOME};
- } else {
- (getpwuid $<)[7];
- }
- }
- }
- };
- unless (defined $homedir) {
- Carp::croak(
- "Couldn't resolve homedir for "
- .(defined $user ? $user : 'current user')
- .($tried_file_homedir ? '' : ' - consider installing File::HomeDir')
- );
- }
- $path =~ s/^~[^\/]*/$homedir/;
- $path;
- }
-
- sub resolve_relative_path {
- my ($class, $path) = @_;
- $path = File::Spec->rel2abs($path);
- }
-
- sub setup_local_lib_for {
- my ($class, $path) = @_;
- $path = $class->ensure_dir_structure_for($path);
- if ($0 eq '-') {
- $class->print_environment_vars_for($path);
- exit 0;
- } else {
- $class->setup_env_hash_for($path);
- @INC = _uniq(split($Config{path_sep}, $ENV{PERL5LIB}), @INC);
- }
- }
-
- sub install_base_bin_path {
- my ($class, $path) = @_;
- File::Spec->catdir($path, 'bin');
- }
-
- sub install_base_perl_path {
- my ($class, $path) = @_;
- File::Spec->catdir($path, 'lib', 'perl5');
- }
-
- sub install_base_arch_path {
- my ($class, $path) = @_;
- File::Spec->catdir($class->install_base_perl_path($path), $Config{archname});
- }
-
- sub ensure_dir_structure_for {
- my ($class, $path) = @_;
- unless (-d $path) {
- warn "Attempting to create directory ${path}\n";
- }
- File::Path::mkpath($path);
- # Need to have the path exist to make a short name for it, so
- # converting to a short name here.
- $path = Win32::GetShortPathName($path) if $^O eq 'MSWin32';
-
- return $path;
- }
-
- sub INTERPOLATE_ENV () { 1 }
- sub LITERAL_ENV () { 0 }
-
- sub guess_shelltype {
- my $shellbin = 'sh';
- if(defined $ENV{'SHELL'}) {
- my @shell_bin_path_parts = File::Spec->splitpath($ENV{'SHELL'});
- $shellbin = $shell_bin_path_parts[-1];
- }
- my $shelltype = do {
- local $_ = $shellbin;
- if(/csh/) {
- 'csh'
- } else {
- 'bourne'
- }
- };
-
- # Both Win32 and Cygwin have $ENV{COMSPEC} set.
- if (defined $ENV{'COMSPEC'} && $^O ne 'cygwin') {
- my @shell_bin_path_parts = File::Spec->splitpath($ENV{'COMSPEC'});
- $shellbin = $shell_bin_path_parts[-1];
- $shelltype = do {
- local $_ = $shellbin;
- if(/command\.com/) {
- 'win32'
- } elsif(/cmd\.exe/) {
- 'win32'
- } elsif(/4nt\.exe/) {
- 'win32'
- } else {
- $shelltype
- }
- };
- }
- return $shelltype;
- }
-
- sub print_environment_vars_for {
- my ($class, $path) = @_;
- print $class->environment_vars_string_for($path);
- }
-
- sub environment_vars_string_for {
- my ($class, $path) = @_;
- my @envs = $class->build_environment_vars_for($path, LITERAL_ENV);
- my $out = '';
-
- # rather basic csh detection, goes on the assumption that something won't
- # call itself csh unless it really is. also, default to bourne in the
- # pathological situation where a user doesn't have $ENV{SHELL} defined.
- # note also that shells with funny names, like zoid, are assumed to be
- # bourne.
-
- my $shelltype = $class->guess_shelltype;
-
- while (@envs) {
- my ($name, $value) = (shift(@envs), shift(@envs));
- $value =~ s/(\\")/\\$1/g;
- $out .= $class->${\"build_${shelltype}_env_declaration"}($name, $value);
- }
- return $out;
- }
-
- # simple routines that take two arguments: an %ENV key and a value. return
- # strings that are suitable for passing directly to the relevant shell to set
- # said key to said value.
- sub build_bourne_env_declaration {
- my $class = shift;
- my($name, $value) = @_;
- return qq{export ${name}="${value}"\n};
- }
-
- sub build_csh_env_declaration {
- my $class = shift;
- my($name, $value) = @_;
- return qq{setenv ${name} "${value}"\n};
- }
-
- sub build_win32_env_declaration {
- my $class = shift;
- my($name, $value) = @_;
- return qq{set ${name}=${value}\n};
- }
-
- sub setup_env_hash_for {
- my ($class, $path) = @_;
- my %envs = $class->build_environment_vars_for($path, INTERPOLATE_ENV);
- @ENV{keys %envs} = values %envs;
- }
-
- sub build_environment_vars_for {
- my ($class, $path, $interpolate) = @_;
- return (
- PERL_LOCAL_LIB_ROOT => $path,
- PERL_MB_OPT => "--install_base ${path}",
- PERL_MM_OPT => "INSTALL_BASE=${path}",
- PERL5LIB => join($Config{path_sep},
- $class->install_base_arch_path($path),
- $class->install_base_perl_path($path),
- (($ENV{PERL5LIB}||()) ?
- ($interpolate == INTERPOLATE_ENV
- ? ($ENV{PERL5LIB})
- : (($^O ne 'MSWin32') ? '$PERL5LIB' : '%PERL5LIB%' ))
- : ())
- ),
- PATH => join($Config{path_sep},
- $class->install_base_bin_path($path),
- ($interpolate == INTERPOLATE_ENV
- ? ($ENV{PATH}||())
- : (($^O ne 'MSWin32') ? '$PATH' : '%PATH%' ))
- ),
- )
- }
-
- 1;
-LOCAL_LIB
-
-$fatpacked{"version.pm"} = <<'VERSION';
- #!perl -w
- package version;
-
- use 5.005_04;
- use strict;
-
- use vars qw(@ISA $VERSION $CLASS $STRICT $LAX *declare *qv);
-
- $VERSION = 0.88;
-
- $CLASS = 'version';
-
- #--------------------------------------------------------------------------#
- # Version regexp components
- #--------------------------------------------------------------------------#
-
- # Fraction part of a decimal version number. This is a common part of
- # both strict and lax decimal versions
-
- my $FRACTION_PART = qr/\.[0-9]+/;
-
- # First part of either decimal or dotted-decimal strict version number.
- # Unsigned integer with no leading zeroes (except for zero itself) to
- # avoid confusion with octal.
-
- my $STRICT_INTEGER_PART = qr/0|[1-9][0-9]*/;
-
- # First part of either decimal or dotted-decimal lax version number.
- # Unsigned integer, but allowing leading zeros. Always interpreted
- # as decimal. However, some forms of the resulting syntax give odd
- # results if used as ordinary Perl expressions, due to how perl treats
- # octals. E.g.
- # version->new("010" ) == 10
- # version->new( 010 ) == 8
- # version->new( 010.2) == 82 # "8" . "2"
-
- my $LAX_INTEGER_PART = qr/[0-9]+/;
-
- # Second and subsequent part of a strict dotted-decimal version number.
- # Leading zeroes are permitted, and the number is always decimal.
- # Limited to three digits to avoid overflow when converting to decimal
- # form and also avoid problematic style with excessive leading zeroes.
-
- my $STRICT_DOTTED_DECIMAL_PART = qr/\.[0-9]{1,3}/;
-
- # Second and subsequent part of a lax dotted-decimal version number.
- # Leading zeroes are permitted, and the number is always decimal. No
- # limit on the numerical value or number of digits, so there is the
- # possibility of overflow when converting to decimal form.
-
- my $LAX_DOTTED_DECIMAL_PART = qr/\.[0-9]+/;
-
- # Alpha suffix part of lax version number syntax. Acts like a
- # dotted-decimal part.
-
- my $LAX_ALPHA_PART = qr/_[0-9]+/;
-
- #--------------------------------------------------------------------------#
- # Strict version regexp definitions
- #--------------------------------------------------------------------------#
-
- # Strict decimal version number.
-
- my $STRICT_DECIMAL_VERSION =
- qr/ $STRICT_INTEGER_PART $FRACTION_PART? /x;
-
- # Strict dotted-decimal version number. Must have both leading "v" and
- # at least three parts, to avoid confusion with decimal syntax.
-
- my $STRICT_DOTTED_DECIMAL_VERSION =
- qr/ v $STRICT_INTEGER_PART $STRICT_DOTTED_DECIMAL_PART{2,} /x;
-
- # Complete strict version number syntax -- should generally be used
- # anchored: qr/ \A $STRICT \z /x
-
- $STRICT =
- qr/ $STRICT_DECIMAL_VERSION | $STRICT_DOTTED_DECIMAL_VERSION /x;
-
- #--------------------------------------------------------------------------#
- # Lax version regexp definitions
- #--------------------------------------------------------------------------#
-
- # Lax decimal version number. Just like the strict one except for
- # allowing an alpha suffix or allowing a leading or trailing
- # decimal-point
-
- my $LAX_DECIMAL_VERSION =
- qr/ $LAX_INTEGER_PART (?: \. | $FRACTION_PART $LAX_ALPHA_PART? )?
- |
- $FRACTION_PART $LAX_ALPHA_PART?
- /x;
-
- # Lax dotted-decimal version number. Distinguished by having either
- # leading "v" or at least three non-alpha parts. Alpha part is only
- # permitted if there are at least two non-alpha parts. Strangely
- # enough, without the leading "v", Perl takes .1.2 to mean v0.1.2,
- # so when there is no "v", the leading part is optional
-
- my $LAX_DOTTED_DECIMAL_VERSION =
- qr/
- v $LAX_INTEGER_PART (?: $LAX_DOTTED_DECIMAL_PART+ $LAX_ALPHA_PART? )?
- |
- $LAX_INTEGER_PART? $LAX_DOTTED_DECIMAL_PART{2,} $LAX_ALPHA_PART?
- /x;
-
- # Complete lax version number syntax -- should generally be used
- # anchored: qr/ \A $LAX \z /x
- #
- # The string 'undef' is a special case to make for easier handling
- # of return values from ExtUtils::MM->parse_version
-
- $LAX =
- qr/ undef | $LAX_DECIMAL_VERSION | $LAX_DOTTED_DECIMAL_VERSION /x;
-
- #--------------------------------------------------------------------------#
-
- eval "use version::vxs $VERSION";
- if ( $@ ) { # don't have the XS version installed
- eval "use version::vpp $VERSION"; # don't tempt fate
- die "$@" if ( $@ );
- push @ISA, "version::vpp";
- local $^W;
- *version::qv = \&version::vpp::qv;
- *version::declare = \&version::vpp::declare;
- *version::_VERSION = \&version::vpp::_VERSION;
- if ($] >= 5.009000 && $] < 5.011004) {
- no strict 'refs';
- *version::stringify = \&version::vpp::stringify;
- *{'version::(""'} = \&version::vpp::stringify;
- *version::new = \&version::vpp::new;
- *version::parse = \&version::vpp::parse;
- }
- }
- else { # use XS module
- push @ISA, "version::vxs";
- local $^W;
- *version::declare = \&version::vxs::declare;
- *version::qv = \&version::vxs::qv;
- *version::_VERSION = \&version::vxs::_VERSION;
- *version::vcmp = \&version::vxs::VCMP;
- if ($] >= 5.009000 && $] < 5.011004) {
- no strict 'refs';
- *version::stringify = \&version::vxs::stringify;
- *{'version::(""'} = \&version::vxs::stringify;
- *version::new = \&version::vxs::new;
- *version::parse = \&version::vxs::parse;
- }
-
- }
-
- # Preloaded methods go here.
- sub import {
- no strict 'refs';
- my ($class) = shift;
-
- # Set up any derived class
- unless ($class eq 'version') {
- local $^W;
- *{$class.'::declare'} = \&version::declare;
- *{$class.'::qv'} = \&version::qv;
- }
-
- my %args;
- if (@_) { # any remaining terms are arguments
- map { $args{$_} = 1 } @_
- }
- else { # no parameters at all on use line
- %args =
- (
- qv => 1,
- 'UNIVERSAL::VERSION' => 1,
- );
- }
-
- my $callpkg = caller();
-
- if (exists($args{declare})) {
- *{$callpkg.'::declare'} =
- sub {return $class->declare(shift) }
- unless defined(&{$callpkg.'::declare'});
- }
-
- if (exists($args{qv})) {
- *{$callpkg.'::qv'} =
- sub {return $class->qv(shift) }
- unless defined(&{$callpkg.'::qv'});
- }
-
- if (exists($args{'UNIVERSAL::VERSION'})) {
- local $^W;
- *UNIVERSAL::VERSION
- = \&version::_VERSION;
- }
-
- if (exists($args{'VERSION'})) {
- *{$callpkg.'::VERSION'} = \&version::_VERSION;
- }
-
- if (exists($args{'is_strict'})) {
- *{$callpkg.'::is_strict'} = \&version::is_strict
- unless defined(&{$callpkg.'::is_strict'});
- }
-
- if (exists($args{'is_lax'})) {
- *{$callpkg.'::is_lax'} = \&version::is_lax
- unless defined(&{$callpkg.'::is_lax'});
- }
- }
-
- sub is_strict { defined $_[0] && $_[0] =~ qr/ \A $STRICT \z /x }
- sub is_lax { defined $_[0] && $_[0] =~ qr/ \A $LAX \z /x }
-
- 1;
-VERSION
-
-$fatpacked{"version/vpp.pm"} = <<'VERSION_VPP';
- package charstar;
- # a little helper class to emulate C char* semantics in Perl
- # so that prescan_version can use the same code as in C
-
- use overload (
- '""' => \&thischar,
- '0+' => \&thischar,
- '++' => \&increment,
- '--' => \&decrement,
- '+' => \&plus,
- '-' => \&minus,
- '*' => \&multiply,
- 'cmp' => \&cmp,
- '<=>' => \&spaceship,
- 'bool' => \&thischar,
- '=' => \&clone,
- );
-
- sub new {
- my ($self, $string) = @_;
- my $class = ref($self) || $self;
-
- my $obj = {
- string => [split(//,$string)],
- current => 0,
- };
- return bless $obj, $class;
- }
-
- sub thischar {
- my ($self) = @_;
- my $last = $#{$self->{string}};
- my $curr = $self->{current};
- if ($curr >= 0 && $curr <= $last) {
- return $self->{string}->[$curr];
- }
- else {
- return '';
- }
- }
-
- sub increment {
- my ($self) = @_;
- $self->{current}++;
- }
-
- sub decrement {
- my ($self) = @_;
- $self->{current}--;
- }
-
- sub plus {
- my ($self, $offset) = @_;
- my $rself = $self->clone;
- $rself->{current} += $offset;
- return $rself;
- }
-
- sub minus {
- my ($self, $offset) = @_;
- my $rself = $self->clone;
- $rself->{current} -= $offset;
- return $rself;
- }
-
- sub multiply {
- my ($left, $right, $swapped) = @_;
- my $char = $left->thischar();
- return $char * $right;
- }
-
- sub spaceship {
- my ($left, $right, $swapped) = @_;
- unless (ref($right)) { # not an object already
- $right = $left->new($right);
- }
- return $left->{current} <=> $right->{current};
- }
-
- sub cmp {
- my ($left, $right, $swapped) = @_;
- unless (ref($right)) { # not an object already
- if (length($right) == 1) { # comparing single character only
- return $left->thischar cmp $right;
- }
- $right = $left->new($right);
- }
- return $left->currstr cmp $right->currstr;
- }
-
- sub bool {
- my ($self) = @_;
- my $char = $self->thischar;
- return ($char ne '');
- }
-
- sub clone {
- my ($left, $right, $swapped) = @_;
- $right = {
- string => [@{$left->{string}}],
- current => $left->{current},
- };
- return bless $right, ref($left);
- }
-
- sub currstr {
- my ($self, $s) = @_;
- my $curr = $self->{current};
- my $last = $#{$self->{string}};
- if (defined($s) && $s->{current} < $last) {
- $last = $s->{current};
- }
-
- my $string = join('', @{$self->{string}}[$curr..$last]);
- return $string;
- }
-
- package version::vpp;
- use strict;
-
- use POSIX qw/locale_h/;
- use locale;
- use vars qw ($VERSION @ISA @REGEXS);
- $VERSION = 0.88;
-
- use overload (
- '""' => \&stringify,
- '0+' => \&numify,
- 'cmp' => \&vcmp,
- '<=>' => \&vcmp,
- 'bool' => \&vbool,
- 'nomethod' => \&vnoop,
- );
-
- eval "use warnings";
- if ($@) {
- eval '
- package warnings;
- sub enabled {return $^W;}
- 1;
- ';
- }
-
- my $VERSION_MAX = 0x7FFFFFFF;
-
- # implement prescan_version as closely to the C version as possible
- use constant TRUE => 1;
- use constant FALSE => 0;
-
- sub isDIGIT {
- my ($char) = shift->thischar();
- return ($char =~ /\d/);
- }
-
- sub isALPHA {
- my ($char) = shift->thischar();
- return ($char =~ /[a-zA-Z]/);
- }
-
- sub isSPACE {
- my ($char) = shift->thischar();
- return ($char =~ /\s/);
- }
-
- sub BADVERSION {
- my ($s, $errstr, $error) = @_;
- if ($errstr) {
- $$errstr = $error;
- }
- return $s;
- }
-
- sub prescan_version {
- my ($s, $strict, $errstr, $sqv, $ssaw_decimal, $swidth, $salpha) = @_;
- my $qv = defined $sqv ? $$sqv : FALSE;
- my $saw_decimal = defined $ssaw_decimal ? $$ssaw_decimal : 0;
- my $width = defined $swidth ? $$swidth : 3;
- my $alpha = defined $salpha ? $$salpha : FALSE;
-
- my $d = $s;
-
- if ($qv && isDIGIT($d)) {
- goto dotted_decimal_version;
- }
-
- if ($d eq 'v') { # explicit v-string
- $d++;
- if (isDIGIT($d)) {
- $qv = TRUE;
- }
- else { # degenerate v-string
- # requires v1.2.3
- return BADVERSION($s,$errstr,"Invalid version format (dotted-decimal versions require at least three parts)");
- }
-
- dotted_decimal_version:
- if ($strict && $d eq '0' && isDIGIT($d+1)) {
- # no leading zeros allowed
- return BADVERSION($s,$errstr,"Invalid version format (no leading zeros)");
- }
-
- while (isDIGIT($d)) { # integer part
- $d++;
- }
-
- if ($d eq '.')
- {
- $saw_decimal++;
- $d++; # decimal point
- }
- else
- {
- if ($strict) {
- # require v1.2.3
- return BADVERSION($s,$errstr,"Invalid version format (dotted-decimal versions require at least three parts)");
- }
- else {
- goto version_prescan_finish;
- }
- }
-
- {
- my $i = 0;
- my $j = 0;
- while (isDIGIT($d)) { # just keep reading
- $i++;
- while (isDIGIT($d)) {
- $d++; $j++;
- # maximum 3 digits between decimal
- if ($strict && $j > 3) {
- return BADVERSION($s,$errstr,"Invalid version format (maximum 3 digits between decimals)");
- }
- }
- if ($d eq '_') {
- if ($strict) {
- return BADVERSION($s,$errstr,"Invalid version format (no underscores)");
- }
- if ( $alpha ) {
- return BADVERSION($s,$errstr,"Invalid version format (multiple underscores)");
- }
- $d++;
- $alpha = TRUE;
- }
- elsif ($d eq '.') {
- if ($alpha) {
- return BADVERSION($s,$errstr,"Invalid version format (underscores before decimal)");
- }
- $saw_decimal++;
- $d++;
- }
- elsif (!isDIGIT($d)) {
- last;
- }
- $j = 0;
- }
-
- if ($strict && $i < 2) {
- # requires v1.2.3
- return BADVERSION($s,$errstr,"Invalid version format (dotted-decimal versions require at least three parts)");
- }
- }
- } # end if dotted-decimal
- else
- { # decimal versions
- # special $strict case for leading '.' or '0'
- if ($strict) {
- if ($d eq '.') {
- return BADVERSION($s,$errstr,"Invalid version format (0 before decimal required)");
- }
- if ($d eq '0' && isDIGIT($d+1)) {
- return BADVERSION($s,$errstr,"Invalid version format (no leading zeros)");
- }
- }
-
- # consume all of the integer part
- while (isDIGIT($d)) {
- $d++;
- }
-
- # look for a fractional part
- if ($d eq '.') {
- # we found it, so consume it
- $saw_decimal++;
- $d++;
- }
- elsif (!$d || $d eq ';' || isSPACE($d) || $d eq '}') {
- if ( $d == $s ) {
- # found nothing
- return BADVERSION($s,$errstr,"Invalid version format (version required)");
- }
- # found just an integer
- goto version_prescan_finish;
- }
- elsif ( $d == $s ) {
- # didn't find either integer or period
- return BADVERSION($s,$errstr,"Invalid version format (non-numeric data)");
- }
- elsif ($d eq '_') {
- # underscore can't come after integer part
- if ($strict) {
- return BADVERSION($s,$errstr,"Invalid version format (no underscores)");
- }
- elsif (isDIGIT($d+1)) {
- return BADVERSION($s,$errstr,"Invalid version format (alpha without decimal)");
- }
- else {
- return BADVERSION($s,$errstr,"Invalid version format (misplaced underscore)");
- }
- }
- elsif ($d) {
- # anything else after integer part is just invalid data
- return BADVERSION($s,$errstr,"Invalid version format (non-numeric data)");
- }
-
- # scan the fractional part after the decimal point
- if ($d && !isDIGIT($d) && ($strict || ! ($d eq ';' || isSPACE($d) || $d eq '}') )) {
- # $strict or lax-but-not-the-end
- return BADVERSION($s,$errstr,"Invalid version format (fractional part required)");
- }
-
- while (isDIGIT($d)) {
- $d++;
- if ($d eq '.' && isDIGIT($d-1)) {
- if ($alpha) {
- return BADVERSION($s,$errstr,"Invalid version format (underscores before decimal)");
- }
- if ($strict) {
- return BADVERSION($s,$errstr,"Invalid version format (dotted-decimal versions must begin with 'v')");
- }
- $d = $s; # start all over again
- $qv = TRUE;
- goto dotted_decimal_version;
- }
- if ($d eq '_') {
- if ($strict) {
- return BADVERSION($s,$errstr,"Invalid version format (no underscores)");
- }
- if ( $alpha ) {
- return BADVERSION($s,$errstr,"Invalid version format (multiple underscores)");
- }
- if ( ! isDIGIT($d+1) ) {
- return BADVERSION($s,$errstr,"Invalid version format (misplaced underscore)");
- }
- $d++;
- $alpha = TRUE;
- }
- }
- }
-
- version_prescan_finish:
- while (isSPACE($d)) {
- $d++;
- }
-
- if ($d && !isDIGIT($d) && (! ($d eq ';' || $d eq '}') )) {
- # trailing non-numeric data
- return BADVERSION($s,$errstr,"Invalid version format (non-numeric data)");
- }
-
- if (defined $sqv) {
- $$sqv = $qv;
- }
- if (defined $swidth) {
- $$swidth = $width;
- }
- if (defined $ssaw_decimal) {
- $$ssaw_decimal = $saw_decimal;
- }
- if (defined $salpha) {
- $$salpha = $alpha;
- }
- return $d;
- }
-
- sub scan_version {
- my ($s, $rv, $qv) = @_;
- my $start;
- my $pos;
- my $last;
- my $errstr;
- my $saw_decimal = 0;
- my $width = 3;
- my $alpha = FALSE;
- my $vinf = FALSE;
- my @av;
-
- $s = new charstar $s;
-
- while (isSPACE($s)) { # leading whitespace is OK
- $s++;
- }
-
- $last = prescan_version($s, FALSE, \$errstr, \$qv, \$saw_decimal,
- \$width, \$alpha);
-
- if ($errstr) {
- # 'undef' is a special case and not an error
- if ( $s ne 'undef') {
- use Carp;
- Carp::croak($errstr);
- }
- }
-
- $start = $s;
- if ($s eq 'v') {
- $s++;
- }
- $pos = $s;
-
- if ( $qv ) {
- $$rv->{qv} = $qv;
- }
- if ( $alpha ) {
- $$rv->{alpha} = $alpha;
- }
- if ( !$qv && $width < 3 ) {
- $$rv->{width} = $width;
- }
-
- while (isDIGIT($pos)) {
- $pos++;
- }
- if (!isALPHA($pos)) {
- my $rev;
-
- for (;;) {
- $rev = 0;
- {
- # this is atoi() that delimits on underscores
- my $end = $pos;
- my $mult = 1;
- my $orev;
-
- # the following if() will only be true after the decimal
- # point of a version originally created with a bare
- # floating point number, i.e. not quoted in any way
- #
- if ( !$qv && $s > $start && $saw_decimal == 1 ) {
- $mult *= 100;
- while ( $s < $end ) {
- $orev = $rev;
- $rev += $s * $mult;
- $mult /= 10;
- if ( (abs($orev) > abs($rev))
- || (abs($rev) > $VERSION_MAX )) {
- warn("Integer overflow in version %d",
- $VERSION_MAX);
- $s = $end - 1;
- $rev = $VERSION_MAX;
- $vinf = 1;
- }
- $s++;
- if ( $s eq '_' ) {
- $s++;
- }
- }
- }
- else {
- while (--$end >= $s) {
- $orev = $rev;
- $rev += $end * $mult;
- $mult *= 10;
- if ( (abs($orev) > abs($rev))
- || (abs($rev) > $VERSION_MAX )) {
- warn("Integer overflow in version");
- $end = $s - 1;
- $rev = $VERSION_MAX;
- $vinf = 1;
- }
- }
- }
- }
-
- # Append revision
- push @av, $rev;
- if ( $vinf ) {
- $s = $last;
- last;
- }
- elsif ( $pos eq '.' ) {
- $s = ++$pos;
- }
- elsif ( $pos eq '_' && isDIGIT($pos+1) ) {
- $s = ++$pos;
- }
- elsif ( $pos eq ',' && isDIGIT($pos+1) ) {
- $s = ++$pos;
- }
- elsif ( isDIGIT($pos) ) {
- $s = $pos;
- }
- else {
- $s = $pos;
- last;
- }
- if ( $qv ) {
- while ( isDIGIT($pos) ) {
- $pos++;
- }
- }
- else {
- my $digits = 0;
- while ( ( isDIGIT($pos) || $pos eq '_' ) && $digits < 3 ) {
- if ( $pos ne '_' ) {
- $digits++;
- }
- $pos++;
- }
- }
- }
- }
- if ( $qv ) { # quoted versions always get at least three terms
- my $len = $#av;
- # This for loop appears to trigger a compiler bug on OS X, as it
- # loops infinitely. Yes, len is negative. No, it makes no sense.
- # Compiler in question is:
- # gcc version 3.3 20030304 (Apple Computer, Inc. build 1640)
- # for ( len = 2 - len; len > 0; len-- )
- # av_push(MUTABLE_AV(sv), newSViv(0));
- #
- $len = 2 - $len;
- while ($len-- > 0) {
- push @av, 0;
- }
- }
-
- # need to save off the current version string for later
- if ( $vinf ) {
- $$rv->{original} = "v.Inf";
- $$rv->{vinf} = 1;
- }
- elsif ( $s > $start ) {
- $$rv->{original} = $start->currstr($s);
- if ( $qv && $saw_decimal == 1 && $start ne 'v' ) {
- # need to insert a v to be consistent
- $$rv->{original} = 'v' . $$rv->{original};
- }
- }
- else {
- $$rv->{original} = '0';
- push(@av, 0);
- }
-
- # And finally, store the AV in the hash
- $$rv->{version} = \@av;
-
- # fix RT#19517 - special case 'undef' as string
- if ($s eq 'undef') {
- $s += 5;
- }
-
- return $s;
- }
-
- sub new
- {
- my ($class, $value) = @_;
- my $self = bless ({}, ref ($class) || $class);
- my $qv = FALSE;
-
- if ( ref($value) && eval('$value->isa("version")') ) {
- # Can copy the elements directly
- $self->{version} = [ @{$value->{version} } ];
- $self->{qv} = 1 if $value->{qv};
- $self->{alpha} = 1 if $value->{alpha};
- $self->{original} = ''.$value->{original};
- return $self;
- }
-
- my $currlocale = setlocale(LC_ALL);
-
- # if the current locale uses commas for decimal points, we
- # just replace commas with decimal places, rather than changing
- # locales
- if ( localeconv()->{decimal_point} eq ',' ) {
- $value =~ tr/,/./;
- }
-
- if ( not defined $value or $value =~ /^undef$/ ) {
- # RT #19517 - special case for undef comparison
- # or someone forgot to pass a value
- push @{$self->{version}}, 0;
- $self->{original} = "0";
- return ($self);
- }
-
- if ( $#_ == 2 ) { # must be CVS-style
- $value = $_[2];
- $qv = TRUE;
- }
-
- $value = _un_vstring($value);
-
- # exponential notation
- if ( $value =~ /\d+.?\d*e[-+]?\d+/ ) {
- $value = sprintf("%.9f",$value);
- $value =~ s/(0+)$//; # trim trailing zeros
- }
-
- my $s = scan_version($value, \$self, $qv);
-
- if ($s) { # must be something left over
- warn("Version string '%s' contains invalid data; "
- ."ignoring: '%s'", $value, $s);
- }
-
- return ($self);
- }
-
- *parse = \&new;
-
- sub numify
- {
- my ($self) = @_;
- unless (_verify($self)) {
- require Carp;
- Carp::croak("Invalid version object");
- }
- my $width = $self->{width} || 3;
- my $alpha = $self->{alpha} || "";
- my $len = $#{$self->{version}};
- my $digit = $self->{version}[0];
- my $string = sprintf("%d.", $digit );
-
- for ( my $i = 1 ; $i < $len ; $i++ ) {
- $digit = $self->{version}[$i];
- if ( $width < 3 ) {
- my $denom = 10**(3-$width);
- my $quot = int($digit/$denom);
- my $rem = $digit - ($quot * $denom);
- $string .= sprintf("%0".$width."d_%d", $quot, $rem);
- }
- else {
- $string .= sprintf("%03d", $digit);
- }
- }
-
- if ( $len > 0 ) {
- $digit = $self->{version}[$len];
- if ( $alpha && $width == 3 ) {
- $string .= "_";
- }
- $string .= sprintf("%0".$width."d", $digit);
- }
- else # $len = 0
- {
- $string .= sprintf("000");
- }
-
- return $string;
- }
-
- sub normal
- {
- my ($self) = @_;
- unless (_verify($self)) {
- require Carp;
- Carp::croak("Invalid version object");
- }
- my $alpha = $self->{alpha} || "";
- my $len = $#{$self->{version}};
- my $digit = $self->{version}[0];
- my $string = sprintf("v%d", $digit );
-
- for ( my $i = 1 ; $i < $len ; $i++ ) {
- $digit = $self->{version}[$i];
- $string .= sprintf(".%d", $digit);
- }
-
- if ( $len > 0 ) {
- $digit = $self->{version}[$len];
- if ( $alpha ) {
- $string .= sprintf("_%0d", $digit);
- }
- else {
- $string .= sprintf(".%0d", $digit);
- }
- }
-
- if ( $len <= 2 ) {
- for ( $len = 2 - $len; $len != 0; $len-- ) {
- $string .= sprintf(".%0d", 0);
- }
- }
-
- return $string;
- }
-
- sub stringify
- {
- my ($self) = @_;
- unless (_verify($self)) {
- require Carp;
- Carp::croak("Invalid version object");
- }
- return exists $self->{original}
- ? $self->{original}
- : exists $self->{qv}
- ? $self->normal
- : $self->numify;
- }
-
- sub vcmp
- {
- require UNIVERSAL;
- my ($left,$right,$swap) = @_;
- my $class = ref($left);
- unless ( UNIVERSAL::isa($right, $class) ) {
- $right = $class->new($right);
- }
-
- if ( $swap ) {
- ($left, $right) = ($right, $left);
- }
- unless (_verify($left)) {
- require Carp;
- Carp::croak("Invalid version object");
- }
- unless (_verify($right)) {
- require Carp;
- Carp::croak("Invalid version object");
- }
- my $l = $#{$left->{version}};
- my $r = $#{$right->{version}};
- my $m = $l < $r ? $l : $r;
- my $lalpha = $left->is_alpha;
- my $ralpha = $right->is_alpha;
- my $retval = 0;
- my $i = 0;
- while ( $i <= $m && $retval == 0 ) {
- $retval = $left->{version}[$i] <=> $right->{version}[$i];
- $i++;
- }
-
- # tiebreaker for alpha with identical terms
- if ( $retval == 0
- && $l == $r
- && $left->{version}[$m] == $right->{version}[$m]
- && ( $lalpha || $ralpha ) ) {
-
- if ( $lalpha && !$ralpha ) {
- $retval = -1;
- }
- elsif ( $ralpha && !$lalpha) {
- $retval = +1;
- }
- }
-
- # possible match except for trailing 0's
- if ( $retval == 0 && $l != $r ) {
- if ( $l < $r ) {
- while ( $i <= $r && $retval == 0 ) {
- if ( $right->{version}[$i] != 0 ) {
- $retval = -1; # not a match after all
- }
- $i++;
- }
- }
- else {
- while ( $i <= $l && $retval == 0 ) {
- if ( $left->{version}[$i] != 0 ) {
- $retval = +1; # not a match after all
- }
- $i++;
- }
- }
- }
-
- return $retval;
- }
-
- sub vbool {
- my ($self) = @_;
- return vcmp($self,$self->new("0"),1);
- }
-
- sub vnoop {
- require Carp;
- Carp::croak("operation not supported with version object");
- }
-
- sub is_alpha {
- my ($self) = @_;
- return (exists $self->{alpha});
- }
-
- sub qv {
- my $value = shift;
- my $class = 'version';
- if (@_) {
- $class = ref($value) || $value;
- $value = shift;
- }
-
- $value = _un_vstring($value);
- $value = 'v'.$value unless $value =~ /(^v|\d+\.\d+\.\d)/;
- my $version = $class->new($value);
- return $version;
- }
-
- *declare = \&qv;
-
- sub is_qv {
- my ($self) = @_;
- return (exists $self->{qv});
- }
-
-
- sub _verify {
- my ($self) = @_;
- if ( ref($self)
- && eval { exists $self->{version} }
- && ref($self->{version}) eq 'ARRAY'
- ) {
- return 1;
- }
- else {
- return 0;
- }
- }
-
- sub _is_non_alphanumeric {
- my $s = shift;
- $s = new charstar $s;
- while ($s) {
- return 0 if isSPACE($s); # early out
- return 1 unless (isALPHA($s) || isDIGIT($s) || $s =~ /[.-]/);
- $s++;
- }
- return 0;
- }
-
- sub _un_vstring {
- my $value = shift;
- # may be a v-string
- if ( length($value) >= 3 && $value !~ /[._]/
- && _is_non_alphanumeric($value)) {
- my $tvalue;
- if ( $] ge 5.008_001 ) {
- $tvalue = _find_magic_vstring($value);
- $value = $tvalue if length $tvalue;
- }
- elsif ( $] ge 5.006_000 ) {
- $tvalue = sprintf("v%vd",$value);
- if ( $tvalue =~ /^v\d+(\.\d+){2,}$/ ) {
- # must be a v-string
- $value = $tvalue;
- }
- }
- }
- return $value;
- }
-
- sub _find_magic_vstring {
- my $value = shift;
- my $tvalue = '';
- require B;
- my $sv = B::svref_2object(\$value);
- my $magic = ref($sv) eq 'B::PVMG' ? $sv->MAGIC : undef;
- while ( $magic ) {
- if ( $magic->TYPE eq 'V' ) {
- $tvalue = $magic->PTR;
- $tvalue =~ s/^v?(.+)$/v$1/;
- last;
- }
- else {
- $magic = $magic->MOREMAGIC;
- }
- }
- return $tvalue;
- }
-
- sub _VERSION {
- my ($obj, $req) = @_;
- my $class = ref($obj) || $obj;
-
- no strict 'refs';
- if ( exists $INC{"$class.pm"} and not %{"$class\::"} and $] >= 5.008) {
- # file but no package
- require Carp;
- Carp::croak( "$class defines neither package nor VERSION"
- ."--version check failed");
- }
-
- my $version = eval "\$$class\::VERSION";
- if ( defined $version ) {
- local $^W if $] <= 5.008;
- $version = version::vpp->new($version);
- }
-
- if ( defined $req ) {
- unless ( defined $version ) {
- require Carp;
- my $msg = $] < 5.006
- ? "$class version $req required--this is only version "
- : "$class does not define \$$class\::VERSION"
- ."--version check failed";
-
- if ( $ENV{VERSION_DEBUG} ) {
- Carp::confess($msg);
- }
- else {
- Carp::croak($msg);
- }
- }
-
- $req = version::vpp->new($req);
-
- if ( $req > $version ) {
- require Carp;
- if ( $req->is_qv ) {
- Carp::croak(
- sprintf ("%s version %s required--".
- "this is only version %s", $class,
- $req->normal, $version->normal)
- );
- }
- else {
- Carp::croak(
- sprintf ("%s version %s required--".
- "this is only version %s", $class,
- $req->stringify, $version->stringify)
- );
- }
- }
- }
-
- return defined $version ? $version->stringify : undef;
- }
-
- 1; #this line is important and will help the module return a true value
-VERSION_VPP
-
-s/^ //mg for values %fatpacked;
-
-unshift @INC, sub {
- if (my $fat = $fatpacked{$_[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 strict;
-use App::cpanminus::script;
-
-unless (caller) {
- my $app = App::cpanminus::script->new;
- $app->parse_options(@ARGV);
- $app->doit or exit(1);
-}
-
-__END__
-
-=head1 NAME
-
-cpanm - get, unpack build and install modules from CPAN
-
-=head1 SYNOPSIS
-
- cpanm Test::More # install Test::More
- cpanm MIYAGAWA/Plack-0.99_05.tar.gz # full distribution path
- cpanm http://example.org/LDS/CGI.pm-3.20.tar.gz # install from URL
- cpanm ~/dists/MyCompany-Enterprise-1.00.tar.gz # install from a local file
- cpanm --interactive Task::Kensho # Configure interactively
- cpanm . # install from local directory
- cpanm --installdeps . # install all the deps for the current directory
- cpanm -L extlib Plack # install Plack and all non-core deps into extlib
- cpanm --mirror http://cpan.cpantesters.org/ DBI # use the fast-syncing mirror
- cpanm --scandeps Moose # See what modules will be installed for Moose
-
-=head1 COMMANDS
-
-=over 4
-
-=item -i, --install
-
-Installs the modules. This is a default behavior and this is just a
-compatibility option to make it work like L<cpan> or L<cpanp>.
-
-=item --self-upgrade
-
-Upgrades itself. It's just an alias for:
-
- cpanm App::cpanminus
-
-=item --info
-
-Displays the distribution information in
-C<AUTHOR/Dist-Name-ver.tar.gz> format in the standard out.
-
-=item --installdeps
-
-Installs the dependencies of the target distribution but won't build
-itself. Handy if you want to try the application from a version
-controlled repository such as git.
-
- cpanm --installdeps .
-
-=item --look
-
-Download and unpack the distribution and then open the directory with
-your shell. Handy to poke around the source code or do the manual
-testing.
-
-=item -h, --help
-
-Displays the help message.
-
-=item -V, --version
-
-Displays the version number.
-
-=back
-
-=head1 OPTIONS
-
-You can specify the default options in C<PERL_CPANM_OPT> environment variable.
-
-=over 4
-
-=item -f, --force
-
-Force install modules even when testing failed.
-
-=item -n, --notest
-
-Skip the testing of modules. Use this only when you just want to save
-time for installing hundreds of distributions to the same perl and
-architecture you've already tested to make sure it builds fine.
-
-Defaults to false, and you can say C<--no-notest> to override when it
-is set in the default options in C<PERL_CPANM_OPT>.
-
-=item -S, --sudo
-
-Switch to the root user with C<sudo> when installing modules. Use this
-if you want to install modules to the system perl include path.
-
-Defaults to false, and you can say C<--no-sudo> to override when it is
-set in the default options in C<PERL_CPANM_OPT>.
-
-=item -v, --verbose
-
-Makes the output verbose. It also enables the interactive
-configuration. (See --interactive)
-
-=item -q, --quiet
-
-Makes the output even more quiet than the default. It doesn't print
-anything to the STDERR.
-
-=item -l, --local-lib
-
-Sets the L<local::lib> compatible path to install modules to. You
-don't need to set this if you already configure the shell environment
-variables using L<local::lib>, but this can be used to override that
-as well.
-
-=item -L, --local-lib-contained
-
-Same with C<--local-lib> but when examining the dependencies, it
-assumes no non-core modules are installed on the system. It's handy if
-you want to bundle application dependencies in one directory so you
-can distribute to other machines.
-
-For instance,
-
- cpanm -L extlib Plack
-
-would install Plack and all of its non-core dependencies into the
-directory C<extlib>, which can be loaded from your application with:
-
- use local::lib '/path/to/extlib';
-
-=item --mirror
-
-Specifies the base URL for the CPAN mirror to use, such as
-C<http://cpan.cpantesters.org/> (you can omit the trailing slash). You
-can specify multiple mirror URLs by repeating the command line option.
-
-Defaults to C<http://search.cpan.org/CPAN> which is a geo location
-aware redirector.
-
-=item --mirror-only
-
-Download the mirror's 02packages.details.txt.gz index file instead of
-querying the CPAN Meta DB.
-
-Select this option if you are using a local mirror of CPAN, such as
-minicpan when you're offline, or your own CPAN index (a.k.a darkpan).
-
-B<Tip:> It might be useful if you name these mirror options with your
-shell aliases, like:
-
- alias minicpanm='cpanm --mirror ~/minicpan --mirror-only'
- alias darkpan='cpanm --mirror http://mycompany.example.com/DPAN --mirror-only'
-
-=item --prompt
-
-Prompts when a test fails so that you can skip, force install, retry
-or look in the shell to see what's going wrong. It also prompts when
-one of the dependency failed if you want to proceed the installation.
-
-Defaults to false, and you can say C<--no-prompt> to override if it's
-set in the default options in C<PERL_CPANM_OPT>.
-
-=item --reinstall
-
-cpanm, when given a module name in the command line (i.e. C<cpanm
-Plack>), checks the locally installed version first and skips if it is
-already installed. This option makes it skip the check, so:
-
- cpanm --reinstall Plack
-
-would reinstall L<Plack> even if your locally installed version is
-latest, or even newer (which would happen if you install a developer
-release from version control repositories).
-
-Defaults to false.
-
-=item --interactive
-
-Makes the configuration (such as C<Makefile.PL> and C<Build.PL>)
-interactive, so you can answer questions in the distribution that
-requires custom configuration or Task:: distributions.
-
-Defaults to false, and you can say C<--no-interactive> to override
-when it's set in the default options in C<PERL_CPANM_OPT>.
-
-=item --scandeps
-
-Scans the depencencies of given modules and output the tree in a text
-format. (See C<--format> below for more options)
-
-Because this command doesn't actually install any distributions, it
-will be useful that by typing:
-
- cpanm --scandeps Catalyst::Runtime
-
-you can make sure what modules will be installed.
-
-This command takes into account which modules you already have
-installed in your system. If you want to see what modules will be
-installed against a vanilla perl installation, you might want to
-combine it with C<-L> option.
-
-=item --format
-
-Determines what format to display the scanned dependency
-tree. Available options are C<tree>, C<json>, C<yaml> and C<dists>.
-
-=over 8
-
-=item tree
-
-Displays the tree in a plain text format. This is the default value.
-
-=item json, yaml
-
-Outputs the tree in a JSON or YAML format. L<JSON> and L<YAML> modules
-need to be installed respectively. The output tree is represented as a
-recursive tuple of:
-
- [ distribution, dependencies ]
-
-and the container is an array containing the root elements. Note that
-there may be multiple root nodes, since you can give multiple modules
-to the C<--scandeps> command.
-
-=item dists
-
-C<dists> is a special output format, where it prints the distribution
-filename in the I<depth first order> after the dependency resolution,
-like:
-
- GAAS/MIME-Base64-3.13.tar.gz
- GAAS/URI-1.58.tar.gz
- PETDANCE/HTML-Tagset-3.20.tar.gz
- GAAS/HTML-Parser-3.68.tar.gz
- GAAS/libwww-perl-5.837.tar.gz
-
-which means you can install these distributions in this order without
-extra dependencies. When combined with C<-L> option, it will be useful
-to replay installations on other machines.
-
-=back
-
-=item --save-dists
-
-Specifies the optional directory path to copy downloaded tarballs in
-the CPAN mirror compatible directory structure
-i.e. I<authors/id/A/AU/AUTHORS/Foo-Bar-version.tar.gz>
-
-=item --uninst-shadows
-
-Uninstalls the shadow files of the distribution that you're
-installing. This eliminates the confusion if you're trying to install
-core (dual-life) modules from CPAN against perl 5.10 or older, or
-modules that used to be XS-based but switched to pure perl at some
-version.
-
-If you run cpanm as root and use C<INSTALL_BASE> or equivalent to
-specify custom installation path, you SHOULD disable this option so
-you won't accidentally uninstall dual-life modules from the core
-include path.
-
-Defaults to true if your perl version is smaller than 5.12, and you
-can disable that with C<--no-uninst-shadows>.
-
-B<NOTE>: Since version 1.3000 this flag is turned off by default for
-perl newer than 5.12, since with 5.12 @INC contains site_perl directory
-I<before> the perl core library path, and uninstalling shadows is not
-necessary anymore and does more harm by deleting files from the core
-library path.
-
-=item --auto-cleanup
-
-Specifies the number of days in whcih cpanm's work directories
-expire. Defaults to 7, which means old work directories will be
-cleaned up in one week.
-
-You can set the value to C<0> to make cpan never cleanup those
-directories.
-
-=item --man-pages
-
-Generates man pages for executables (man1) and libraries (man3).
-
-Defaults to false (no man pages generated) if
-C<-L|--local-lib-contained> option is supplied. Otherwise, defaults to
-true, and you can disable it with C<--no-man-pages>.
-
-=item --lwp
-
-Uses L<LWP> module to download stuff over HTTP. Defaults to true, and
-you can say C<--no-lwp> to disable using LWP, when you want to upgrade
-LWP from CPAN on some broken perl systems.
-
-=item --wget
-
-Uses GNU Wget (if available) to download stuff. Defaults to true, and
-you can say C<--no-wget> to disable using Wget (versions of Wget older
-than 1.9 don't support the C<--retry-connrefused> option used by cpanm).
-
-=item --curl
-
-Uses cURL (if available) to download stuff. Defaults to true, and
-you can say C<--no-curl> to disable using cURL.
-
-Normally with C<--lwp>, C<--wget> and C<--curl> options set to true
-(which is the default) cpanm tries L<LWP>, Wget, cURL and L<HTTP::Tiny>
-(in that order) and uses the first one available.
-
-=back
-
-=head1 SEE ALSO
-
-L<App::cpanminus>
-
-=head1 COPYRIGHT
-
-Copyright 2010 Tatsuhiko Miyagawa.
-
-=head1 AUTHOR
-
-Tatsuhiko Miyagawa
-
-=cut
diff --git a/perl-external/bin/module-manage.pl b/perl-external/bin/module-manage.pl
deleted file mode 100755
index 5e826aabf..000000000
--- a/perl-external/bin/module-manage.pl
+++ /dev/null
@@ -1,265 +0,0 @@
-#!/usr/bin/env perl
-
-use strict;
-use warnings;
-
-use IPC::Run3;
-use LWP::Simple;
-use File::Slurp;
-use Path::Class;
-use List::MoreUtils 'uniq';
-
-# TODO - 'updates' action that lists packages that could be updated
-# TODO - add smarts to strip out old packages (could switch to building using files.txt after)
-
-my $root_dir = file(__FILE__)->dir->parent->absolute->stringify;
-my $module_list = "$root_dir/modules.txt";
-my $file_list = "$root_dir/files.txt";
-my $minicpan = "$root_dir/minicpan";
-my $local_packages_file = "$minicpan/modules/02packages.details.txt";
-my $local_packages_file_gz = "$local_packages_file.gz";
-
-my %actions = (
- add => \&add,
- build_all => \&build_all,
- fetch_all => \&fetch_all,
- force_install => \&force_install,
- index_minicpan => \&index_minicpan,
- init => \&init,
- setup => \&setup,
- sort_files => \&sort_files,
- zap => \&zap,
-);
-
-# work out what to run
-my ( $action, @args ) = @ARGV;
-$actions{$action}
- ? $actions{$action}->(@args)
- : die("Usage: $0 action [...]\n actions: "
- . join( ', ', sort keys %actions )
- . "\n" );
-
-exit;
-
-############################################################################
-
-sub init {
- add('App::cpanminus');
-}
-
-sub setup {
- fetch_all();
- build('App::cpanminus');
- build_all();
-}
-
-sub add {
- my $module = shift || die "Usage: $0 add Dist::To::Add";
-
- # try to install the distribution using cpanm
- my $out = '';
- my $cmd = "cpanm --reinstall --save-dists $minicpan $module";
-
- run3( $cmd, undef, undef, undef )
- || die "Error running '$cmd'";
-
- write_file( $module_list, { append => 1 }, "$module\n" );
-
- index_minicpan();
- sort_files();
-}
-
-sub index_minicpan {
-
- # Go through all files in minicpan and add to files.txt
- my @files = sort map { s{^.*?(/authors/id/.*)$}{$1}; $_ }
- split '\s', `find $minicpan/authors -type f`;
- write_file( $file_list, map { "$_\n" } @files );
-
- # work out which ones are not currently in packages
- my @local_packages_lines = read_packages_txt_gz($local_packages_file_gz);
-
- # Are there any missing files?
- my @missing_files = ();
- MINICPAN_FILE:
- foreach my $file (@files) {
- my ($auth_and_file) = $file =~ m{/authors/id/./../(.*)$};
-
- foreach my $line (@local_packages_lines) {
- next MINICPAN_FILE if $line =~ m{$auth_and_file};
- }
-
- push @missing_files, $auth_and_file;
- }
-
- # If there are no missing files we can stop
- return unless @missing_files;
-
- # Fetch 02packages off live cpan
- my $remote_packages_url =
- 'http://cpan.perl.org/modules/02packages.details.txt.gz';
- my $remote_packages_file = "$minicpan/modules/remote_packages.txt.gz";
- print " Fetching '$remote_packages_url'...\n";
- is_error( mirror( $remote_packages_url, $remote_packages_file ) )
- && die "Could not retrieve '$remote_packages_url'";
- print " done...\n";
-
- my @remote_packages_lines = read_packages_txt_gz($remote_packages_file);
-
- # Find remaining in live file and add to local file
- my %lines_to_add = ();
- foreach my $missing (@missing_files) {
- print " Finding matches for '$missing'\n";
- my @matches = grep { m{$missing} } @remote_packages_lines;
- next unless @matches;
- $lines_to_add{$missing} = \@matches;
- }
-
- # for packages still not found parse out the contents
- foreach my $missing (@missing_files) {
- next if $lines_to_add{$missing};
-
- # do a require here so that this module does not prevent 'setup' from
- # being run - needed to install it.
- require CPAN::ParseDistribution;
-
- print " Parsing out matches for '$missing'\n";
-
- my ( $A, $B ) = $missing =~ m{^(.)(.)};
- my $dist =
- CPAN::ParseDistribution->new("$minicpan/authors/id/$A/$A$B/$missing");
-
- my $modules = $dist->modules();
- my @matches = ();
-
- foreach my $module ( sort keys %$modules ) {
- my $version = $modules->{$module} || 'undef';
-
- # Zucchini 0.000017 C/CH/CHISEL/Zucchini-0.0.17.tar.gz
- push @matches, "$module $version $A/$A$B/$missing\n";
- }
-
- $lines_to_add{$missing} = \@matches;
- }
-
- # combine and sort the lines found
- my @new_lines = sort @local_packages_lines,
- map { @$_ } values %lines_to_add;
- unlink $local_packages_file_gz;
- write_file( $local_packages_file, map { "$_\n" } packages_file_headers(),
- @new_lines );
- system "gzip -v $local_packages_file";
-}
-
-sub read_packages_txt_gz {
- my $file = shift;
-
- return unless -e $file;
-
- my @lines = split /\n/, `zcat $file`;
-
- # ditch the headers
- while ( my $line = shift @lines ) {
- last if $line =~ m{^\s*$};
- }
-
- return @lines;
-}
-
-sub packages_file_headers {
-
- # this is all fake stuff
-
- return << 'END_OF_LINES';
-Allow-Packages-Only-Once: 0
-Columns: package name, version, path
-Description: Package names for my private CPAN
-File: 02packages.details.txt
-Intended-For: My private CPAN
-Last-Updated: Wed, 04 May 2011 09:59:13 GMT
-Line-Count: 1389
-URL: http://example.com/MyCPAN/modules/02packages.details.txt
-Written-By: /home/evdb/fixmystreet/perl-external/local-lib/bin/dpan using CPAN::PackageDetails 0.25
-
-END_OF_LINES
-}
-
-sub build_all {
- my @modules = sort uniq map { s{\s+$}{}; $_; } read_file($module_list);
- build($_) for @modules;
-}
-
-sub build {
- my $module = shift #
- || die "Usage: $0 build Module::To::Build\n";
-
- print " --- checking/installing $module ---\n";
-
- my $out = '';
- my $cmd = "cpanm --mirror $minicpan --mirror-only $module";
-
- # print " running '$cmd'\n";
-
- run3( $cmd, undef, \$out, \$out )
- || die "Error running '$cmd'";
-
- my @lines =
- grep { m{\S} }
- split /\n+/, $out;
- my $last_line = $lines[-1];
-
- die "Error building '$module':\n\n$last_line\n\n$out\n\n"
- unless $last_line =~ m{Successfully installed }
- || $last_line =~ m{is up to date}
- || $last_line =~ m{\d+ distributions? installed};
-}
-
-sub fetch_all {
- my @urls = sort uniq map { s{\s+$}{}; $_; } read_file($file_list);
- fetch($_) for @urls;
-}
-
-sub fetch {
- my $filename = shift;
-
- my $destination = file("$minicpan/$filename");
- $destination->dir->mkpath;
-
- return if -e $destination;
-
- # create a list of urls to try in order
- my @urls = (
- "http://search.cpan.org/CPAN" . $filename,
- "http://backpan.perl.org" . $filename,
- );
-
- while ( scalar @urls ) {
- my $url = shift @urls;
-
- # try to fetch
- print " Fetching '$url'...\n";
- last if is_success( getstore( $url, "$destination" ) );
-
- # if more options try again
- next if scalar @urls;
-
- # could not retrieve - die
- die "ERROR - ran out of urls fetching '$filename'";
- }
-}
-
-sub zap {
-
- # delete all the bits that are generated
- my $local_lib_root = $ENV{PERL_LOCAL_LIB_ROOT} || die;
- dir($local_lib_root)->rmtree(1);
- dir($minicpan)->subdir('authors')->rmtree(1);
-}
-
-sub sort_files {
- foreach my $file ( $file_list, $module_list ) {
- my @entries = read_file($file);
- @entries = uniq sort @entries;
- write_file( $file, @entries );
- }
-}
diff --git a/perl-external/files.txt b/perl-external/files.txt
deleted file mode 100644
index 781a2564e..000000000
--- a/perl-external/files.txt
+++ /dev/null
@@ -1,261 +0,0 @@
-/authors/id/A/AB/ABRAXXA/Catalyst-View-TT-0.36.tar.gz
-/authors/id/A/AB/ABRAXXA/DBIx-Class-0.08127.tar.gz
-/authors/id/A/AB/ABW/AppConfig-1.66.tar.gz
-/authors/id/A/AB/ABW/Template-Toolkit-2.22.tar.gz
-/authors/id/A/AC/ACALPINI/Lingua-Stem-It-0.02.tar.gz
-/authors/id/A/AC/ACOBURN/Lingua-EN-Tagger-0.16.tar.gz
-/authors/id/A/AD/ADAMK/Archive-Zip-1.30.tar.gz
-/authors/id/A/AD/ADAMK/Class-Inspector-1.25.tar.gz
-/authors/id/A/AD/ADAMK/DBD-SQLite-1.31.tar.gz
-/authors/id/A/AD/ADAMK/File-Remove-1.48.tar.gz
-/authors/id/A/AD/ADAMK/File-ShareDir-1.03.tar.gz
-/authors/id/A/AD/ADAMK/Module-Install-1.00.tar.gz
-/authors/id/A/AD/ADAMK/Object-Signature-1.05.tar.gz
-/authors/id/A/AD/ADAMK/PPI-1.215.tar.gz
-/authors/id/A/AD/ADAMK/Params-Util-1.03.tar.gz
-/authors/id/A/AD/ADAMK/Task-Weaken-1.04.tar.gz
-/authors/id/A/AD/ADAMK/Test-NoWarnings-1.02.tar.gz
-/authors/id/A/AD/ADAMK/Test-Object-0.07.tar.gz
-/authors/id/A/AD/ADAMK/Test-SubCalls-1.09.tar.gz
-/authors/id/A/AD/ADAMK/YAML-Tiny-1.48.tar.gz
-/authors/id/A/AD/ADIE/Test-Exception-0.31.tar.gz
-/authors/id/A/AL/ALEXP/Net-Domain-TLD-1.68.tar.gz
-/authors/id/A/AL/ALGDR/Lingua-Stem-Ru-0.01.tar.gz
-/authors/id/A/AN/ANDK/CPAN-Checksums-2.07.tar.gz
-/authors/id/A/AN/ANDYA/CGI-Simple-1.113.tar.gz
-/authors/id/A/AN/ANDYA/Test-Harness-3.23.tar.gz
-/authors/id/A/AR/ARJAY/Compress-Bzip2-2.09.tar.gz
-/authors/id/A/AS/ASKSH/Snowball-Norwegian-1.2.tar.gz
-/authors/id/A/AS/ASKSH/Snowball-Swedish-1.2.tar.gz
-/authors/id/A/AU/AUDREYT/Test-use-ok-0.02.tar.gz
-/authors/id/B/BD/BDFOY/CPAN-PackageDetails-0.25.tar.gz
-/authors/id/B/BD/BDFOY/ConfigReader-Simple-1.28.tar.gz
-/authors/id/B/BD/BDFOY/Distribution-Guess-BuildSystem-0.12.tar.gz
-/authors/id/B/BD/BDFOY/File-Find-Closures-1.09.tar.gz
-/authors/id/B/BD/BDFOY/Module-Extract-Namespaces-0.14.tar.gz
-/authors/id/B/BD/BDFOY/Module-Extract-Use-0.17.tar.gz
-/authors/id/B/BD/BDFOY/Module-Extract-VERSION-0.13.tar.gz
-/authors/id/B/BD/BDFOY/MyCPAN-App-DPAN-1.28.tar.gz
-/authors/id/B/BD/BDFOY/MyCPAN-Indexer-1.28.tar.gz
-/authors/id/B/BD/BDFOY/Test-Output-0.16.tar.gz
-/authors/id/B/BI/BINGOS/Archive-Tar-1.76.tar.gz
-/authors/id/B/BI/BINGOS/Module-CoreList-2.45.tar.gz
-/authors/id/B/BO/BOBTFISH/Catalyst-Action-RenderView-0.16.tar.gz
-/authors/id/B/BO/BOBTFISH/Catalyst-Authentication-Store-DBIx-Class-0.1401.tar.gz
-/authors/id/B/BO/BOBTFISH/Catalyst-Devel-1.31.tar.gz
-/authors/id/B/BO/BOBTFISH/Catalyst-Model-Adaptor-0.10.tar.gz
-/authors/id/B/BO/BOBTFISH/Catalyst-Plugin-Authentication-0.10017.tar.gz
-/authors/id/B/BO/BOBTFISH/Catalyst-Plugin-Session-0.31.tar.gz
-/authors/id/B/BO/BOBTFISH/Catalyst-Plugin-Session-Store-Delegate-0.06.tar.gz
-/authors/id/B/BO/BOBTFISH/Catalyst-Plugin-Unicode-0.93.tar.gz
-/authors/id/B/BO/BOBTFISH/Catalyst-Plugin-Unicode-Encoding-1.1.tar.gz
-/authors/id/B/BO/BOBTFISH/Catalyst-Runtime-5.80032.tar.gz
-/authors/id/B/BO/BOBTFISH/CatalystX-Component-Traits-0.16.tar.gz
-/authors/id/B/BO/BOBTFISH/MooseX-Getopt-0.35.tar.gz
-/authors/id/B/BO/BOBTFISH/Test-WWW-Mechanize-Catalyst-0.53.tar.gz
-/authors/id/B/BO/BOBTFISH/namespace-autoclean-0.12.tar.gz
-/authors/id/B/BP/BPOWERS/Memoize-ExpireLRU-0.55.tar.gz
-/authors/id/B/BR/BRICAS/Catalyst-Plugin-ConfigLoader-0.30.tar.gz
-/authors/id/B/BR/BRICAS/Config-Any-0.20.tar.gz
-/authors/id/C/CH/CHOCOLATE/Scope-Guard-0.20.tar.gz
-/authors/id/C/CH/CHORNY/Hook-LexWrap-0.24.tar.gz
-/authors/id/C/CH/CHORNY/Test-Warn-0.23.tar.gz
-/authors/id/C/CH/CHORNY/Tie-IxHash-1.22.tar.gz
-/authors/id/C/CI/CINE/Lingua-Stem-Snowball-Da-1.01.tar.gz
-/authors/id/C/CK/CKRAS/DateTime-Format-HTTP-0.40.tar.gz
-/authors/id/C/CO/COGENT/Tree-DAG_Node-1.06.tar.gz
-/authors/id/C/CO/CORION/parent-0.225.tar.gz
-/authors/id/C/CR/CRENZ/Module-Find-0.10.tar.gz
-/authors/id/D/DA/DAGOLDEN/CPAN-Meta-2.110580.tar.gz
-/authors/id/D/DA/DAGOLDEN/CPAN-Meta-YAML-0.003.tar.gz
-/authors/id/D/DA/DAGOLDEN/ExtUtils-CBuilder-0.280202.tar.gz
-/authors/id/D/DA/DAGOLDEN/ExtUtils-ParseXS-2.2206.tar.gz
-/authors/id/D/DA/DAGOLDEN/Module-Build-0.3800.tar.gz
-/authors/id/D/DA/DAGOLDEN/Module-Metadata-1.000004.tar.gz
-/authors/id/D/DA/DAGOLDEN/Parse-CPAN-Meta-1.4401.tar.gz
-/authors/id/D/DA/DAGOLDEN/Perl-OSType-1.002.tar.gz
-/authors/id/D/DA/DAGOLDEN/Sub-Uplevel-0.22.tar.gz
-/authors/id/D/DC/DCANTRELL/CPAN-ParseDistribution-1.3.tar.gz
-/authors/id/D/DC/DCANTRELL/Data-Compare-1.22.tar.gz
-/authors/id/D/DC/DCONWAY/Lingua-EN-Inflect-1.893.tar.gz
-/authors/id/D/DL/DLAND/File-Path-2.08.tar.gz
-/authors/id/D/DL/DLUX/Parallel-ForkManager-0.7.9.tar.gz
-/authors/id/D/DM/DMAKI/DateTime-Format-Pg-0.16005.tar.gz
-/authors/id/D/DM/DMUEY/File-Copy-Recursive-0.38.tar.gz
-/authors/id/D/DM/DMUEY/Hash-Merge-0.12.tar.gz
-/authors/id/D/DO/DOY/Dist-CheckConflicts-0.02.tar.gz
-/authors/id/D/DO/DOY/Package-Stash-0.26.tar.gz
-/authors/id/D/DO/DOY/Package-Stash-XS-0.22.tar.gz
-/authors/id/D/DO/DOY/Try-Tiny-0.09.tar.gz
-/authors/id/D/DR/DROLSKY/Class-Factory-Util-1.7.tar.gz
-/authors/id/D/DR/DROLSKY/DateTime-0.70.tar.gz
-/authors/id/D/DR/DROLSKY/DateTime-Format-Builder-0.80.tar.gz
-/authors/id/D/DR/DROLSKY/DateTime-Format-Strptime-1.5000.tar.gz
-/authors/id/D/DR/DROLSKY/DateTime-Locale-0.45.tar.gz
-/authors/id/D/DR/DROLSKY/DateTime-TimeZone-1.34.tar.gz
-/authors/id/D/DR/DROLSKY/File-ChangeNotify-0.19.tar.gz
-/authors/id/D/DR/DROLSKY/File-Slurp-9999.13.tar.gz
-/authors/id/D/DR/DROLSKY/Moose-1.24.tar.gz
-/authors/id/D/DR/DROLSKY/MooseX-Params-Validate-0.16.tar.gz
-/authors/id/D/DR/DROLSKY/MooseX-SemiAffordanceAccessor-0.09.tar.gz
-/authors/id/D/DR/DROLSKY/MooseX-Types-0.25.tar.gz
-/authors/id/D/DR/DROLSKY/Package-DeprecationManager-0.10.tar.gz
-/authors/id/D/DR/DRTECH/Locale-Maketext-Lexicon-0.86.tar.gz
-/authors/id/F/FD/FDALY/Test-Tester-0.107.tar.gz
-/authors/id/F/FE/FERREIRA/Devel-Hide-0.0008.tar.gz
-/authors/id/F/FE/FERREIRA/Exporter-5.63.tar.gz
-/authors/id/F/FE/FERREIRA/Term-Size-Any-0.001.tar.gz
-/authors/id/F/FE/FERREIRA/Term-Size-Perl-0.029.tar.gz
-/authors/id/F/FL/FLORA/B-Hooks-EndOfScope-0.09.tar.gz
-/authors/id/F/FL/FLORA/Catalyst-Plugin-Session-Store-DBIC-0.11.tar.gz
-/authors/id/F/FL/FLORA/Class-C3-0.23.tar.gz
-/authors/id/F/FL/FLORA/Class-C3-Adopt-NEXT-0.13.tar.gz
-/authors/id/F/FL/FLORA/Class-MOP-1.12.tar.gz
-/authors/id/F/FL/FLORA/Data-Visitor-0.27.tar.gz
-/authors/id/F/FL/FLORA/Devel-GlobalDestruction-0.03.tar.gz
-/authors/id/F/FL/FLORA/HTTP-Request-AsCGI-1.2.tar.gz
-/authors/id/F/FL/FLORA/MRO-Compat-0.11.tar.gz
-/authors/id/F/FL/FLORA/MooseX-Emulate-Class-Accessor-Fast-0.00903.tar.gz
-/authors/id/F/FL/FLORA/MooseX-MethodAttributes-0.24.tar.gz
-/authors/id/F/FL/FLORA/MooseX-Role-WithOverloading-0.09.tar.gz
-/authors/id/F/FL/FLORA/Sub-Name-0.05.tar.gz
-/authors/id/F/FL/FLORA/namespace-clean-0.20.tar.gz
-/authors/id/F/FR/FREW/Data-Dumper-Concise-2.020.tar.gz
-/authors/id/F/FR/FREW/SQL-Abstract-1.72.tar.gz
-/authors/id/G/GA/GAAS/Data-Dump-1.19.tar.gz
-/authors/id/G/GA/GAAS/Digest-HMAC-1.02.tar.gz
-/authors/id/G/GA/GAAS/Encode-Locale-1.01.tar.gz
-/authors/id/G/GA/GAAS/File-Listing-6.00.tar.gz
-/authors/id/G/GA/GAAS/HTML-Form-6.00.tar.gz
-/authors/id/G/GA/GAAS/HTML-Parser-3.68.tar.gz
-/authors/id/G/GA/GAAS/HTTP-Cookies-6.00.tar.gz
-/authors/id/G/GA/GAAS/HTTP-Daemon-6.00.tar.gz
-/authors/id/G/GA/GAAS/HTTP-Date-6.00.tar.gz
-/authors/id/G/GA/GAAS/HTTP-Message-6.01.tar.gz
-/authors/id/G/GA/GAAS/HTTP-Negotiate-6.00.tar.gz
-/authors/id/G/GA/GAAS/IO-String-1.08.tar.gz
-/authors/id/G/GA/GAAS/LWP-MediaTypes-6.01.tar.gz
-/authors/id/G/GA/GAAS/Net-HTTP-6.00.tar.gz
-/authors/id/G/GA/GAAS/URI-1.58.tar.gz
-/authors/id/G/GA/GAAS/WWW-RobotRules-6.00.tar.gz
-/authors/id/G/GA/GAAS/libwww-perl-6.01.tar.gz
-/authors/id/G/GA/GAAS/libwww-perl-6.02.tar.gz
-/authors/id/G/GB/GBARR/CPAN-DistnameInfo-0.12.tar.gz
-/authors/id/G/GB/GBARR/Scalar-List-Utils-1.23.tar.gz
-/authors/id/G/GE/GETTY/HTTP-Body-1.11.tar.gz
-/authors/id/G/GR/GRODITI/MooseX-Types-Common-0.001002.tar.gz
-/authors/id/G/GR/GROMMEL/Math-Round-0.06.tar.gz
-/authors/id/G/GW/GWILLIAMS/DateTime-Format-W3CDTF-0.06.tar.gz
-/authors/id/I/IL/ILMARI/Class-Unload-0.07.tar.gz
-/authors/id/I/IN/INGY/Spiffy-0.30.tar.gz
-/authors/id/I/IN/INGY/Test-Base-0.59.tar.gz
-/authors/id/J/JE/JESSE/HTTP-Server-Simple-0.43.tar.gz
-/authors/id/J/JE/JESSE/HTTP-Server-Simple-0.44.tar.gz
-/authors/id/J/JH/JHOBLITT/DateTime-Format-ISO8601-0.07.tar.gz
-/authors/id/J/JP/JPEACOCK/version-0.88.tar.gz
-/authors/id/J/JR/JROCKWAY/Context-Preserve-0.01.tar.gz
-/authors/id/J/JR/JROCKWAY/Template-Plugin-DateTime-Format-0.02.tar.gz
-/authors/id/K/KA/KASEI/Class-Accessor-0.34.tar.gz
-/authors/id/K/KW/KWILLIAMS/Path-Class-0.23.tar.gz
-/authors/id/K/KW/KWILLIAMS/Probe-Perl-0.01.tar.gz
-/authors/id/L/LB/LBROCARD/Data-Page-2.02.tar.gz
-/authors/id/M/MA/MAKAMAKA/JSON-2.51.tar.gz
-/authors/id/M/MA/MAKAMAKA/JSON-PP-2.27105.tar.gz
-/authors/id/M/MA/MANU/Net-IP-1.25.tar.gz
-/authors/id/M/MA/MARKOV/MIME-Types-1.31.tar.gz
-/authors/id/M/MA/MAUKE/Dir-Self-0.10.tar.gz
-/authors/id/M/MH/MHX/Devel-PPPort-3.19.tar.gz
-/authors/id/M/MI/MIROD/HTML-TreeBuilder-XPath-0.12.tar.gz
-/authors/id/M/MI/MIROD/XML-XPathEngine-0.12.tar.gz
-/authors/id/M/MI/MIYAGAWA/App-cpanminus-1.4004.tar.gz
-/authors/id/M/MI/MIYAGAWA/App-cpanminus-1.4007.tar.gz
-/authors/id/M/MI/MIYAGAWA/HTML-Selector-XPath-0.07.tar.gz
-/authors/id/M/MI/MIYAGAWA/Template-Plugin-Comma-0.04.tar.gz
-/authors/id/M/MI/MIYAGAWA/Web-Scraper-0.34.tar.gz
-/authors/id/M/ML/MLEHMANN/JSON-XS-2.3.tar.gz
-/authors/id/M/ML/MLEHMANN/common-sense-3.4.tar.gz
-/authors/id/M/MR/MRAMBERG/Text-SimpleTable-2.03.tar.gz
-/authors/id/M/MS/MSCHILLI/Log-Log4perl-1.32.tar.gz
-/authors/id/M/MS/MSCHWERN/Carp-Assert-0.20.tar.gz
-/authors/id/M/MS/MSCHWERN/ExtUtils-MakeMaker-6.56.tar.gz
-/authors/id/M/MS/MSCHWERN/Test-Simple-0.98.tar.gz
-/authors/id/M/MS/MSCHWERN/UNIVERSAL-require-0.13.tar.gz
-/authors/id/M/MS/MSTROUT/Catalyst-Plugin-Session-State-Cookie-0.17.tar.gz
-/authors/id/M/MS/MSTROUT/Catalyst-Plugin-Static-Simple-0.29.tar.gz
-/authors/id/N/NU/NUFFIN/Tie-ToObject-0.03.tar.gz
-/authors/id/O/OL/OLAF/Net-DNS-0.66.tar.gz
-/authors/id/O/OV/OVID/Sub-Override-0.08.tar.gz
-/authors/id/O/OV/OVID/aliased-0.30.tar.gz
-/authors/id/P/PE/PETDANCE/Carp-Assert-More-1.12.tar.gz
-/authors/id/P/PE/PETDANCE/Template-Timer-1.00.tar.gz
-/authors/id/P/PE/PETDANCE/Test-WWW-Mechanize-1.30.tar.gz
-/authors/id/P/PE/PETDANCE/WWW-Mechanize-1.66.tar.gz
-/authors/id/P/PM/PMQS/Compress-Raw-Bzip2-2.033.tar.gz
-/authors/id/P/PM/PMQS/Compress-Raw-Zlib-2.033.tar.gz
-/authors/id/P/PM/PMQS/IO-Compress-2.033.tar.gz
-/authors/id/R/RC/RCLAMP/Class-Accessor-Chained-0.01.tar.gz
-/authors/id/R/RC/RCLAMP/Devel-Caller-2.05.tar.gz
-/authors/id/R/RC/RCLAMP/File-Find-Rule-0.32.tar.gz
-/authors/id/R/RC/RCLAMP/Number-Compare-0.01.tar.gz
-/authors/id/R/RC/RCLAMP/Text-Glob-0.09.tar.gz
-/authors/id/R/RD/RDF/Clone-0.31.tar.gz
-/authors/id/R/RG/RGARCIA/Sub-Identify-0.04.tar.gz
-/authors/id/R/RG/RGARCIA/Test-LongString-0.14.tar.gz
-/authors/id/R/RG/RGARCIA/Test-LongString-0.15.tar.gz
-/authors/id/R/RI/RIBASUSHI/Class-C3-Componentised-1.0008.tar.gz
-/authors/id/R/RJ/RJBS/Data-OptList-0.106.tar.gz
-/authors/id/R/RJ/RJBS/Email-Address-1.892.tar.gz
-/authors/id/R/RJ/RJBS/Email-Date-Format-1.002.tar.gz
-/authors/id/R/RJ/RJBS/Email-MIME-1.908.tar.gz
-/authors/id/R/RJ/RJBS/Email-MIME-ContentType-1.015.tar.gz
-/authors/id/R/RJ/RJBS/Email-MIME-Encodings-1.313.tar.gz
-/authors/id/R/RJ/RJBS/Email-MessageID-1.402.tar.gz
-/authors/id/R/RJ/RJBS/Email-Send-2.198.tar.gz
-/authors/id/R/RJ/RJBS/Email-Simple-2.100.tar.gz
-/authors/id/R/RJ/RJBS/Email-Valid-0.184.tar.gz
-/authors/id/R/RJ/RJBS/Getopt-Long-Descriptive-0.089.tar.gz
-/authors/id/R/RJ/RJBS/Return-Value-1.666001.tar.gz
-/authors/id/R/RJ/RJBS/String-RewritePrefix-0.006.tar.gz
-/authors/id/R/RJ/RJBS/Sub-Exporter-0.982.tar.gz
-/authors/id/R/RJ/RJBS/Sub-Install-0.925.tar.gz
-/authors/id/R/RJ/RJBS/Test-Deep-0.108.tar.gz
-/authors/id/R/RJ/RJBS/Test-Fatal-0.003.tar.gz
-/authors/id/R/RJ/RJBS/Version-Requirements-0.101020.tar.gz
-/authors/id/R/RK/RKITOVER/Catalyst-Model-DBIC-Schema-0.48.tar.gz
-/authors/id/R/RK/RKITOVER/Catalyst-Plugin-SmartURI-0.036.tar.gz
-/authors/id/R/RK/RKITOVER/Class-Accessor-Grouped-0.10002.tar.gz
-/authors/id/R/RK/RKITOVER/DBIx-Class-Schema-Loader-0.07010.tar.gz
-/authors/id/R/RK/RKITOVER/Lingua-EN-Inflect-Phrase-0.04.tar.gz
-/authors/id/R/RK/RKITOVER/MooseX-Traits-Pluggable-0.10.tar.gz
-/authors/id/R/RK/RKITOVER/URI-SmartURI-0.031.tar.gz
-/authors/id/R/RO/ROBIN/PadWalker-1.92.tar.gz
-/authors/id/R/RO/ROODE/Readonly-1.03.tar.gz
-/authors/id/R/RS/RSCHUPP/Module-ScanDeps-1.00.tar.gz
-/authors/id/S/SA/SALVA/Sort-Key-1.28.tar.gz
-/authors/id/S/SA/SARTAK/Class-Load-0.06.tar.gz
-/authors/id/S/SD/SDP/Lingua-Stem-Fr-0.02.tar.gz
-/authors/id/S/SI/SIMON/Lingua-EN-Inflect-Number-1.1.tar.gz
-/authors/id/S/SI/SIMONW/Module-Pluggable-3.9.tar.gz
-/authors/id/S/SM/SMUELLER/Class-XSAccessor-1.11.tar.gz
-/authors/id/S/SM/SMUELLER/PAR-Dist-0.47.tar.gz
-/authors/id/S/SM/SMUELLER/PathTools-3.33.tar.gz
-/authors/id/S/SN/SNOWHARE/Lingua-Stem-0.84.tar.gz
-/authors/id/S/ST/STBEY/Carp-Clan-6.04.tar.gz
-/authors/id/S/ST/STEVAN/Tree-Simple-1.18.tar.gz
-/authors/id/S/ST/STEVAN/Tree-Simple-VisitorFactory-0.10.tar.gz
-/authors/id/T/TI/TIMB/DBI-1.616.tar.gz
-/authors/id/T/TJ/TJENNESS/File-Temp-0.22.tar.gz
-/authors/id/T/TL/TLINDEN/Config-General-2.50.tar.gz
-/authors/id/T/TM/TMTM/Class-Data-Inheritable-0.08.tar.gz
-/authors/id/T/TO/TODDR/Locale-Maketext-1.19.tar.gz
-/authors/id/T/TO/TOKUHIROM/Test-Requires-0.06.tar.gz
-/authors/id/T/TU/TURNSTEP/DBD-Pg-2.17.2.tar.gz
-/authors/id/T/TU/TURNSTEP/DBD-Pg-2.18.1.tar.gz
-/authors/id/U/UL/ULPFR/Text-German-0.06.tar.gz
-/authors/id/V/VP/VPIT/Variable-Magic-0.46.tar.gz
-/authors/id/W/WR/WREIS/DBIx-Class-EncodedColumn-0.00011.tar.gz
-/authors/id/X/XE/XERN/Lingua-PT-Stemmer-0.01.tar.gz
-/authors/id/Y/YV/YVES/ExtUtils-Install-1.54.tar.gz
-/authors/id/Z/ZE/ZEFRAM/Class-Mix-0.004.tar.gz
-/authors/id/Z/ZE/ZEFRAM/Crypt-Eksblowfish-0.009.tar.gz
-/authors/id/Z/ZE/ZEFRAM/Params-Classify-0.013.tar.gz
diff --git a/perl-external/lib/perl5/local/lib.pm b/perl-external/lib/perl5/local/lib.pm
deleted file mode 100644
index 87d186903..000000000
--- a/perl-external/lib/perl5/local/lib.pm
+++ /dev/null
@@ -1,1030 +0,0 @@
-use strict;
-use warnings;
-
-package local::lib;
-
-use 5.008001; # probably works with earlier versions but I'm not supporting them
- # (patches would, of course, be welcome)
-
-use File::Spec ();
-use File::Path ();
-use Carp ();
-use Config;
-
-our $VERSION = '1.008004'; # 1.8.4
-
-our @KNOWN_FLAGS = qw(--self-contained --deactivate --deactivate-all);
-
-sub DEACTIVATE_ONE () { 1 }
-sub DEACTIVATE_ALL () { 2 }
-
-sub INTERPOLATE_ENV () { 1 }
-sub LITERAL_ENV () { 0 }
-
-sub import {
- my ($class, @args) = @_;
-
- # Remember what PERL5LIB was when we started
- my $perl5lib = $ENV{PERL5LIB} || '';
-
- my %arg_store;
- for my $arg (@args) {
- # check for lethal dash first to stop processing before causing problems
- if ($arg =~ /−/) {
- die <<'DEATH';
-WHOA THERE! It looks like you've got some fancy dashes in your commandline!
-These are *not* the traditional -- dashes that software recognizes. You
-probably got these by copy-pasting from the perldoc for this module as
-rendered by a UTF8-capable formatter. This most typically happens on an OS X
-terminal, but can happen elsewhere too. Please try again after replacing the
-dashes with normal minus signs.
-DEATH
- }
- elsif(grep { $arg eq $_ } @KNOWN_FLAGS) {
- (my $flag = $arg) =~ s/--//;
- $arg_store{$flag} = 1;
- }
- elsif($arg =~ /^--/) {
- die "Unknown import argument: $arg";
- }
- else {
- # assume that what's left is a path
- $arg_store{path} = $arg;
- }
- }
-
- if($arg_store{'self-contained'}) {
- die "FATAL: The local::lib --self-contained flag has never worked reliably and the original author, Mark Stosberg, was unable or unwilling to maintain it. As such, this flag has been removed from the local::lib codebase in order to prevent misunderstandings and potentially broken builds. The local::lib authors recommend that you look at the lib::core::only module shipped with this distribution in order to create a more robust environment that is equivalent to what --self-contained provided (although quite possibly not what you originally thought it provided due to the poor quality of the documentation, for which we apologise).\n";
- }
-
- my $deactivating = 0;
- if ($arg_store{deactivate}) {
- $deactivating = DEACTIVATE_ONE;
- }
- if ($arg_store{'deactivate-all'}) {
- $deactivating = DEACTIVATE_ALL;
- }
-
- $arg_store{path} = $class->resolve_path($arg_store{path});
- $class->setup_local_lib_for($arg_store{path}, $deactivating);
-
- for (@INC) { # Untaint @INC
- next if ref; # Skip entry if it is an ARRAY, CODE, blessed, etc.
- m/(.*)/ and $_ = $1;
- }
-}
-
-sub pipeline;
-
-sub pipeline {
- my @methods = @_;
- my $last = pop(@methods);
- if (@methods) {
- \sub {
- my ($obj, @args) = @_;
- $obj->${pipeline @methods}(
- $obj->$last(@args)
- );
- };
- } else {
- \sub {
- shift->$last(@_);
- };
- }
-}
-
-=begin testing
-
-#:: test pipeline
-
-package local::lib;
-
-{ package Foo; sub foo { -$_[1] } sub bar { $_[1]+2 } sub baz { $_[1]+3 } }
-my $foo = bless({}, 'Foo');
-Test::More::ok($foo->${pipeline qw(foo bar baz)}(10) == -15);
-
-=end testing
-
-=cut
-
-sub _uniq {
- my %seen;
- grep { ! $seen{$_}++ } @_;
-}
-
-sub resolve_path {
- my ($class, $path) = @_;
- $class->${pipeline qw(
- resolve_relative_path
- resolve_home_path
- resolve_empty_path
- )}($path);
-}
-
-sub resolve_empty_path {
- my ($class, $path) = @_;
- if (defined $path) {
- $path;
- } else {
- '~/perl5';
- }
-}
-
-=begin testing
-
-#:: test classmethod setup
-
-my $c = 'local::lib';
-
-=end testing
-
-=begin testing
-
-#:: test classmethod
-
-is($c->resolve_empty_path, '~/perl5');
-is($c->resolve_empty_path('foo'), 'foo');
-
-=end testing
-
-=cut
-
-sub resolve_home_path {
- my ($class, $path) = @_;
- return $path unless ($path =~ /^~/);
- my ($user) = ($path =~ /^~([^\/]+)/); # can assume ^~ so undef for 'us'
- my $tried_file_homedir;
- my $homedir = do {
- if (eval { require File::HomeDir } && $File::HomeDir::VERSION >= 0.65) {
- $tried_file_homedir = 1;
- if (defined $user) {
- File::HomeDir->users_home($user);
- } else {
- File::HomeDir->my_home;
- }
- } else {
- if (defined $user) {
- (getpwnam $user)[7];
- } else {
- if (defined $ENV{HOME}) {
- $ENV{HOME};
- } else {
- (getpwuid $<)[7];
- }
- }
- }
- };
- unless (defined $homedir) {
- Carp::croak(
- "Couldn't resolve homedir for "
- .(defined $user ? $user : 'current user')
- .($tried_file_homedir ? '' : ' - consider installing File::HomeDir')
- );
- }
- $path =~ s/^~[^\/]*/$homedir/;
- $path;
-}
-
-sub resolve_relative_path {
- my ($class, $path) = @_;
- $path = File::Spec->rel2abs($path);
-}
-
-=begin testing
-
-#:: test classmethod
-
-local *File::Spec::rel2abs = sub { shift; 'FOO'.shift; };
-is($c->resolve_relative_path('bar'),'FOObar');
-
-=end testing
-
-=cut
-
-sub setup_local_lib_for {
- my ($class, $path, $deactivating) = @_;
-
- my $interpolate = LITERAL_ENV;
- my @active_lls = $class->active_paths;
-
- $path = $class->ensure_dir_structure_for($path);
-
- if (! $deactivating) {
- if (@active_lls && $active_lls[-1] eq $path) {
- exit 0 if $0 eq '-';
- return; # Asked to add what's already at the top of the stack
- } elsif (grep { $_ eq $path} @active_lls) {
- # Asked to add a dir that's lower in the stack -- so we remove it from
- # where it is, and then add it back at the top.
- $class->setup_env_hash_for($path, DEACTIVATE_ONE);
- # Which means we can no longer output "PERL5LIB=...:$PERL5LIB" stuff
- # anymore because we're taking something *out*.
- $interpolate = INTERPOLATE_ENV;
- }
- }
-
- if ($0 eq '-') {
- $class->print_environment_vars_for($path, $deactivating, $interpolate);
- exit 0;
- } else {
- $class->setup_env_hash_for($path, $deactivating);
- @INC = _uniq(split($Config{path_sep}, $ENV{PERL5LIB}), @INC);
- }
-}
-
-sub install_base_bin_path {
- my ($class, $path) = @_;
- File::Spec->catdir($path, 'bin');
-}
-
-sub install_base_perl_path {
- my ($class, $path) = @_;
- File::Spec->catdir($path, 'lib', 'perl5');
-}
-
-sub install_base_arch_path {
- my ($class, $path) = @_;
- File::Spec->catdir($class->install_base_perl_path($path), $Config{archname});
-}
-
-sub ensure_dir_structure_for {
- my ($class, $path) = @_;
- unless (-d $path) {
- warn "Attempting to create directory ${path}\n";
- }
- File::Path::mkpath($path);
- # Need to have the path exist to make a short name for it, so
- # converting to a short name here.
- $path = Win32::GetShortPathName($path) if $^O eq 'MSWin32';
-
- return $path;
-}
-
-sub guess_shelltype {
- my $shellbin = 'sh';
- if(defined $ENV{'SHELL'}) {
- my @shell_bin_path_parts = File::Spec->splitpath($ENV{'SHELL'});
- $shellbin = $shell_bin_path_parts[-1];
- }
- my $shelltype = do {
- local $_ = $shellbin;
- if(/csh/) {
- 'csh'
- } else {
- 'bourne'
- }
- };
-
- # Both Win32 and Cygwin have $ENV{COMSPEC} set.
- if (defined $ENV{'COMSPEC'} && $^O ne 'cygwin') {
- my @shell_bin_path_parts = File::Spec->splitpath($ENV{'COMSPEC'});
- $shellbin = $shell_bin_path_parts[-1];
- $shelltype = do {
- local $_ = $shellbin;
- if(/command\.com/) {
- 'win32'
- } elsif(/cmd\.exe/) {
- 'win32'
- } elsif(/4nt\.exe/) {
- 'win32'
- } else {
- $shelltype
- }
- };
- }
- return $shelltype;
-}
-
-sub print_environment_vars_for {
- my ($class, $path, $deactivating, $interpolate) = @_;
- print $class->environment_vars_string_for($path, $deactivating, $interpolate);
-}
-
-sub environment_vars_string_for {
- my ($class, $path, $deactivating, $interpolate) = @_;
- my @envs = $class->build_environment_vars_for($path, $deactivating, $interpolate);
- my $out = '';
-
- # rather basic csh detection, goes on the assumption that something won't
- # call itself csh unless it really is. also, default to bourne in the
- # pathological situation where a user doesn't have $ENV{SHELL} defined.
- # note also that shells with funny names, like zoid, are assumed to be
- # bourne.
-
- my $shelltype = $class->guess_shelltype;
-
- while (@envs) {
- my ($name, $value) = (shift(@envs), shift(@envs));
- $value =~ s/(\\")/\\$1/g if defined $value;
- $out .= $class->${\"build_${shelltype}_env_declaration"}($name, $value);
- }
- return $out;
-}
-
-# simple routines that take two arguments: an %ENV key and a value. return
-# strings that are suitable for passing directly to the relevant shell to set
-# said key to said value.
-sub build_bourne_env_declaration {
- my $class = shift;
- my($name, $value) = @_;
- return defined($value) ? qq{export ${name}="${value}";\n} : qq{unset ${name};\n};
-}
-
-sub build_csh_env_declaration {
- my $class = shift;
- my($name, $value) = @_;
- return defined($value) ? qq{setenv ${name} "${value}"\n} : qq{unsetenv ${name}\n};
-}
-
-sub build_win32_env_declaration {
- my $class = shift;
- my($name, $value) = @_;
- return defined($value) ? qq{set ${name}=${value}\n} : qq{set ${name}=\n};
-}
-
-sub setup_env_hash_for {
- my ($class, $path, $deactivating) = @_;
- my %envs = $class->build_environment_vars_for($path, $deactivating, INTERPOLATE_ENV);
- @ENV{keys %envs} = values %envs;
-}
-
-sub build_environment_vars_for {
- my ($class, $path, $deactivating, $interpolate) = @_;
-
- if ($deactivating == DEACTIVATE_ONE) {
- return $class->build_deactivate_environment_vars_for($path, $interpolate);
- } elsif ($deactivating == DEACTIVATE_ALL) {
- return $class->build_deact_all_environment_vars_for($path, $interpolate);
- } else {
- return $class->build_activate_environment_vars_for($path, $interpolate);
- }
-}
-
-sub build_activate_environment_vars_for {
- my ($class, $path, $interpolate) = @_;
- return (
- PERL_LOCAL_LIB_ROOT => join($Config{path_sep},
- (($ENV{PERL_LOCAL_LIB_ROOT}||()) ?
- ($interpolate == INTERPOLATE_ENV
- ? ($ENV{PERL_LOCAL_LIB_ROOT}||())
- : (($^O ne 'MSWin32') ? '$PERL_LOCAL_LIB_ROOT'
- : '%PERL_LOCAL_LIB_ROOT%' ))
- : ()),
- $path
- ),
- PERL_MB_OPT => "--install_base ${path}",
- PERL_MM_OPT => "INSTALL_BASE=${path}",
- PERL5LIB => join($Config{path_sep},
- $class->install_base_arch_path($path),
- $class->install_base_perl_path($path),
- (($ENV{PERL5LIB}||()) ?
- ($interpolate == INTERPOLATE_ENV
- ? ($ENV{PERL5LIB})
- : (($^O ne 'MSWin32') ? '$PERL5LIB' : '%PERL5LIB%' ))
- : ())
- ),
- PATH => join($Config{path_sep},
- $class->install_base_bin_path($path),
- ($interpolate == INTERPOLATE_ENV
- ? ($ENV{PATH}||())
- : (($^O ne 'MSWin32') ? '$PATH' : '%PATH%' ))
- ),
- )
-}
-
-sub active_paths {
- my ($class) = @_;
-
- return () unless defined $ENV{PERL_LOCAL_LIB_ROOT};
- return split /\Q$Config{path_sep}/, $ENV{PERL_LOCAL_LIB_ROOT};
-}
-
-sub build_deactivate_environment_vars_for {
- my ($class, $path, $interpolate) = @_;
-
- my @active_lls = $class->active_paths;
-
- if (!grep { $_ eq $path } @active_lls) {
- warn "Tried to deactivate inactive local::lib '$path'\n";
- return ();
- }
-
- my @new_ll_root = grep { $_ ne $path } @active_lls;
- my @new_perl5lib = grep {
- $_ ne $class->install_base_arch_path($path) &&
- $_ ne $class->install_base_perl_path($path)
- } split /\Q$Config{path_sep}/, $ENV{PERL5LIB};
-
- my %env = (
- PERL_LOCAL_LIB_ROOT => (@new_ll_root ?
- join($Config{path_sep}, @new_ll_root) : undef
- ),
- PERL5LIB => (@new_perl5lib ?
- join($Config{path_sep}, @new_perl5lib) : undef
- ),
- PATH => join($Config{path_sep},
- grep { $_ ne $class->install_base_bin_path($path) }
- split /\Q$Config{path_sep}/, $ENV{PATH}
- ),
- );
-
- # If removing ourselves from the "top of the stack", set install paths to
- # correspond with the new top of stack.
- if ($active_lls[-1] eq $path) {
- if (@active_lls > 1) {
- my $new_top = $active_lls[-2];
- %env = (%env,
- PERL_MB_OPT => "--install_base ${new_top}",
- PERL_MM_OPT => "INSTALL_BASE=${new_top}",
- );
- } else {
- %env = (%env,
- PERL_MB_OPT => undef,
- PERL_MM_OPT => undef,
- );
- }
- }
-
- return %env;
-}
-
-sub build_deact_all_environment_vars_for {
- my ($class, $path, $interpolate) = @_;
-
- my @active_lls = $class->active_paths;
-
- my @new_perl5lib = split /\Q$Config{path_sep}/, $ENV{PERL5LIB};
- my @new_path = split /\Q$Config{path_sep}/, $ENV{PATH};
-
- for my $path (@active_lls) {
- @new_perl5lib = grep {
- $_ ne $class->install_base_arch_path($path) &&
- $_ ne $class->install_base_perl_path($path)
- } @new_perl5lib;
-
- @new_path = grep {
- $_ ne $class->install_base_bin_path($path)
- } @new_path;
- }
-
- my %env = (
- PERL_LOCAL_LIB_ROOT => undef,
- PERL_MM_OPT => undef,
- PERL_MB_OPT => undef,
- PERL5LIB => (@new_perl5lib ?
- join($Config{path_sep}, @new_perl5lib) : undef
- ),
- PATH => join($Config{path_sep}, @new_path),
- );
-
- return %env;
-}
-
-=begin testing
-
-#:: test classmethod
-
-File::Path::rmtree('t/var/splat');
-
-$c->ensure_dir_structure_for('t/var/splat');
-
-ok(-d 't/var/splat');
-
-=end testing
-
-=encoding utf8
-
-=head1 NAME
-
-local::lib - create and use a local lib/ for perl modules with PERL5LIB
-
-=head1 SYNOPSIS
-
-In code -
-
- use local::lib; # sets up a local lib at ~/perl5
-
- use local::lib '~/foo'; # same, but ~/foo
-
- # Or...
- use FindBin;
- use local::lib "$FindBin::Bin/../support"; # app-local support library
-
-From the shell -
-
- # Install LWP and its missing dependencies to the '~/perl5' directory
- perl -MCPAN -Mlocal::lib -e 'CPAN::install(LWP)'
-
- # Just print out useful shell commands
- $ perl -Mlocal::lib
- export PERL_MB_OPT='--install_base /home/username/perl5'
- export PERL_MM_OPT='INSTALL_BASE=/home/username/perl5'
- export PERL5LIB='/home/username/perl5/lib/perl5/i386-linux:/home/username/perl5/lib/perl5'
- export PATH="/home/username/perl5/bin:$PATH"
-
-=head2 The bootstrapping technique
-
-A typical way to install local::lib is using what is known as the
-"bootstrapping" technique. You would do this if your system administrator
-hasn't already installed local::lib. In this case, you'll need to install
-local::lib in your home directory.
-
-If you do have administrative privileges, you will still want to set up your
-environment variables, as discussed in step 4. Without this, you would still
-install the modules into the system CPAN installation and also your Perl scripts
-will not use the lib/ path you bootstrapped with local::lib.
-
-By default local::lib installs itself and the CPAN modules into ~/perl5.
-
-Windows users must also see L</Differences when using this module under Win32>.
-
-1. Download and unpack the local::lib tarball from CPAN (search for "Download"
-on the CPAN page about local::lib). Do this as an ordinary user, not as root
-or administrator. Unpack the file in your home directory or in any other
-convenient location.
-
-2. Run this:
-
- perl Makefile.PL --bootstrap
-
-If the system asks you whether it should automatically configure as much
-as possible, you would typically answer yes.
-
-In order to install local::lib into a directory other than the default, you need
-to specify the name of the directory when you call bootstrap, as follows:
-
- perl Makefile.PL --bootstrap=~/foo
-
-3. Run this: (local::lib assumes you have make installed on your system)
-
- make test && make install
-
-4. Now we need to setup the appropriate environment variables, so that Perl
-starts using our newly generated lib/ directory. If you are using bash or
-any other Bourne shells, you can add this to your shell startup script this
-way:
-
- echo 'eval $(perl -I$HOME/perl5/lib/perl5 -Mlocal::lib)' >>~/.bashrc
-
-If you are using C shell, you can do this as follows:
-
- /bin/csh
- echo $SHELL
- /bin/csh
- perl -I$HOME/perl5/lib/perl5 -Mlocal::lib >> ~/.cshrc
-
-If you passed to bootstrap a directory other than default, you also need to give that as
-import parameter to the call of the local::lib module like this way:
-
- echo 'eval $(perl -I$HOME/foo/lib/perl5 -Mlocal::lib=$HOME/foo)' >>~/.bashrc
-
-After writing your shell configuration file, be sure to re-read it to get the
-changed settings into your current shell's environment. Bourne shells use
-C<. ~/.bashrc> for this, whereas C shells use C<source ~/.cshrc>.
-
-If you're on a slower machine, or are operating under draconian disk space
-limitations, you can disable the automatic generation of manpages from POD when
-installing modules by using the C<--no-manpages> argument when bootstrapping:
-
- perl Makefile.PL --bootstrap --no-manpages
-
-To avoid doing several bootstrap for several Perl module environments on the
-same account, for example if you use it for several different deployed
-applications independently, you can use one bootstrapped local::lib
-installation to install modules in different directories directly this way:
-
- cd ~/mydir1
- perl -Mlocal::lib=./
- eval $(perl -Mlocal::lib=./) ### To set the environment for this shell alone
- printenv ### You will see that ~/mydir1 is in the PERL5LIB
- perl -MCPAN -e install ... ### whatever modules you want
- cd ../mydir2
- ... REPEAT ...
-
-If you are working with several C<local::lib> environments, you may want to
-remove some of them from the current environment without disturbing the others.
-You can deactivate one environment like this (using bourne sh):
-
- eval $(perl -Mlocal::lib=--deactivate,~/path)
-
-which will generate and run the commands needed to remove C<~/path> from your
-various search paths. Whichever environment was B<activated most recently> will
-remain the target for module installations. That is, if you activate
-C<~/path_A> and then you activate C<~/path_B>, new modules you install will go
-in C<~/path_B>. If you deactivate C<~/path_B> then modules will be installed
-into C<~/pathA> -- but if you deactivate C<~/path_A> then they will still be
-installed in C<~/pathB> because pathB was activated later.
-
-You can also ask C<local::lib> to clean itself completely out of the current
-shell's environment with the C<--deactivate-all> option.
-For multiple environments for multiple apps you may need to include a modified
-version of the C<< use FindBin >> instructions in the "In code" sample above.
-If you did something like the above, you have a set of Perl modules at C<<
-~/mydir1/lib >>. If you have a script at C<< ~/mydir1/scripts/myscript.pl >>,
-you need to tell it where to find the modules you installed for it at C<<
-~/mydir1/lib >>.
-
-In C<< ~/mydir1/scripts/myscript.pl >>:
-
- use strict;
- use warnings;
- use local::lib "$FindBin::Bin/.."; ### points to ~/mydir1 and local::lib finds lib
- use lib "$FindBin::Bin/../lib"; ### points to ~/mydir1/lib
-
-Put this before any BEGIN { ... } blocks that require the modules you installed.
-
-=head2 Differences when using this module under Win32
-
-To set up the proper environment variables for your current session of
-C<CMD.exe>, you can use this:
-
- C:\>perl -Mlocal::lib
- set PERL_MB_OPT=--install_base C:\DOCUME~1\ADMINI~1\perl5
- set PERL_MM_OPT=INSTALL_BASE=C:\DOCUME~1\ADMINI~1\perl5
- set PERL5LIB=C:\DOCUME~1\ADMINI~1\perl5\lib\perl5;C:\DOCUME~1\ADMINI~1\perl5\lib\perl5\MSWin32-x86-multi-thread
- set PATH=C:\DOCUME~1\ADMINI~1\perl5\bin;%PATH%
-
- ### To set the environment for this shell alone
- C:\>perl -Mlocal::lib > %TEMP%\tmp.bat && %TEMP%\tmp.bat && del %TEMP%\temp.bat
- ### instead of $(perl -Mlocal::lib=./)
-
-If you want the environment entries to persist, you'll need to add then to the
-Control Panel's System applet yourself or use L<App::local::lib::Win32Helper>.
-
-The "~" is translated to the user's profile directory (the directory named for
-the user under "Documents and Settings" (Windows XP or earlier) or "Users"
-(Windows Vista or later)) unless $ENV{HOME} exists. After that, the home
-directory is translated to a short name (which means the directory must exist)
-and the subdirectories are created.
-
-=head1 RATIONALE
-
-The version of a Perl package on your machine is not always the version you
-need. Obviously, the best thing to do would be to update to the version you
-need. However, you might be in a situation where you're prevented from doing
-this. Perhaps you don't have system administrator privileges; or perhaps you
-are using a package management system such as Debian, and nobody has yet gotten
-around to packaging up the version you need.
-
-local::lib solves this problem by allowing you to create your own directory of
-Perl packages downloaded from CPAN (in a multi-user system, this would typically
-be within your own home directory). The existing system Perl installation is
-not affected; you simply invoke Perl with special options so that Perl uses the
-packages in your own local package directory rather than the system packages.
-local::lib arranges things so that your locally installed version of the Perl
-packages takes precedence over the system installation.
-
-If you are using a package management system (such as Debian), you don't need to
-worry about Debian and CPAN stepping on each other's toes. Your local version
-of the packages will be written to an entirely separate directory from those
-installed by Debian.
-
-=head1 DESCRIPTION
-
-This module provides a quick, convenient way of bootstrapping a user-local Perl
-module library located within the user's home directory. It also constructs and
-prints out for the user the list of environment variables using the syntax
-appropriate for the user's current shell (as specified by the C<SHELL>
-environment variable), suitable for directly adding to one's shell
-configuration file.
-
-More generally, local::lib allows for the bootstrapping and usage of a
-directory containing Perl modules outside of Perl's C<@INC>. This makes it
-easier to ship an application with an app-specific copy of a Perl module, or
-collection of modules. Useful in cases like when an upstream maintainer hasn't
-applied a patch to a module of theirs that you need for your application.
-
-On import, local::lib sets the following environment variables to appropriate
-values:
-
-=over 4
-
-=item PERL_MB_OPT
-
-=item PERL_MM_OPT
-
-=item PERL5LIB
-
-=item PATH
-
-PATH is appended to, rather than clobbered.
-
-=back
-
-These values are then available for reference by any code after import.
-
-=head1 CREATING A SELF-CONTAINED SET OF MODULES
-
-See L<lib::core::only> for one way to do this - but note that
-there are a number of caveats, and the best approach is always to perform a
-build against a clean perl (i.e. site and vendor as close to empty as possible).
-
-=head1 OPTIONS
-
-Options are values that can be passed to the C<local::lib> import besides the
-directory to use. They are specified as C<use local::lib '--option'[, path];>
-or C<perl -Mlocal::lib=--option[,path]>.
-
-=head2 --deactivate
-
-Remove the chosen path (or the default path) from the module search paths if it
-was added by C<local::lib>, instead of adding it.
-
-=head2 --deactivate-all
-
-Remove all directories that were added to search paths by C<local::lib> from the
-search paths.
-
-=head1 METHODS
-
-=head2 ensure_dir_structure_for
-
-=over 4
-
-=item Arguments: $path
-
-=item Return value: None
-
-=back
-
-Attempts to create the given path, and all required parent directories. Throws
-an exception on failure.
-
-=head2 print_environment_vars_for
-
-=over 4
-
-=item Arguments: $path
-
-=item Return value: None
-
-=back
-
-Prints to standard output the variables listed above, properly set to use the
-given path as the base directory.
-
-=head2 build_environment_vars_for
-
-=over 4
-
-=item Arguments: $path, $interpolate
-
-=item Return value: \%environment_vars
-
-=back
-
-Returns a hash with the variables listed above, properly set to use the
-given path as the base directory.
-
-=head2 setup_env_hash_for
-
-=over 4
-
-=item Arguments: $path
-
-=item Return value: None
-
-=back
-
-Constructs the C<%ENV> keys for the given path, by calling
-L</build_environment_vars_for>.
-
-=head2 active_paths
-
-=over 4
-
-=item Arguments: None
-
-=item Return value: @paths
-
-=back
-
-Returns a list of active C<local::lib> paths, according to the
-C<PERL_LOCAL_LIB_ROOT> environment variable.
-
-=head2 install_base_perl_path
-
-=over 4
-
-=item Arguments: $path
-
-=item Return value: $install_base_perl_path
-
-=back
-
-Returns a path describing where to install the Perl modules for this local
-library installation. Appends the directories C<lib> and C<perl5> to the given
-path.
-
-=head2 install_base_arch_path
-
-=over 4
-
-=item Arguments: $path
-
-=item Return value: $install_base_arch_path
-
-=back
-
-Returns a path describing where to install the architecture-specific Perl
-modules for this local library installation. Based on the
-L</install_base_perl_path> method's return value, and appends the value of
-C<$Config{archname}>.
-
-=head2 install_base_bin_path
-
-=over 4
-
-=item Arguments: $path
-
-=item Return value: $install_base_bin_path
-
-=back
-
-Returns a path describing where to install the executable programs for this
-local library installation. Based on the L</install_base_perl_path> method's
-return value, and appends the directory C<bin>.
-
-=head2 resolve_empty_path
-
-=over 4
-
-=item Arguments: $path
-
-=item Return value: $base_path
-
-=back
-
-Builds and returns the base path into which to set up the local module
-installation. Defaults to C<~/perl5>.
-
-=head2 resolve_home_path
-
-=over 4
-
-=item Arguments: $path
-
-=item Return value: $home_path
-
-=back
-
-Attempts to find the user's home directory. If installed, uses C<File::HomeDir>
-for this purpose. If no definite answer is available, throws an exception.
-
-=head2 resolve_relative_path
-
-=over 4
-
-=item Arguments: $path
-
-=item Return value: $absolute_path
-
-=back
-
-Translates the given path into an absolute path.
-
-=head2 resolve_path
-
-=over 4
-
-=item Arguments: $path
-
-=item Return value: $absolute_path
-
-=back
-
-Calls the following in a pipeline, passing the result from the previous to the
-next, in an attempt to find where to configure the environment for a local
-library installation: L</resolve_empty_path>, L</resolve_home_path>,
-L</resolve_relative_path>. Passes the given path argument to
-L</resolve_empty_path> which then returns a result that is passed to
-L</resolve_home_path>, which then has its result passed to
-L</resolve_relative_path>. The result of this final call is returned from
-L</resolve_path>.
-
-=head1 A WARNING ABOUT UNINST=1
-
-Be careful about using local::lib in combination with "make install UNINST=1".
-The idea of this feature is that will uninstall an old version of a module
-before installing a new one. However it lacks a safety check that the old
-version and the new version will go in the same directory. Used in combination
-with local::lib, you can potentially delete a globally accessible version of a
-module while installing the new version in a local place. Only combine "make
-install UNINST=1" and local::lib if you understand these possible consequences.
-
-=head1 LIMITATIONS
-
-The perl toolchain is unable to handle directory names with spaces in it,
-so you cant put your local::lib bootstrap into a directory with spaces. What
-you can do is moving your local::lib to a directory with spaces B<after> you
-installed all modules inside your local::lib bootstrap. But be aware that you
-cant update or install CPAN modules after the move.
-
-Rather basic shell detection. Right now anything with csh in its name is
-assumed to be a C shell or something compatible, and everything else is assumed
-to be Bourne, except on Win32 systems. If the C<SHELL> environment variable is
-not set, a Bourne-compatible shell is assumed.
-
-Bootstrap is a hack and will use CPAN.pm for ExtUtils::MakeMaker even if you
-have CPANPLUS installed.
-
-Kills any existing PERL5LIB, PERL_MM_OPT or PERL_MB_OPT.
-
-Should probably auto-fixup CPAN config if not already done.
-
-Patches very much welcome for any of the above.
-
-On Win32 systems, does not have a way to write the created environment variables
-to the registry, so that they can persist through a reboot.
-
-=head1 TROUBLESHOOTING
-
-If you've configured local::lib to install CPAN modules somewhere in to your
-home directory, and at some point later you try to install a module with C<cpan
--i Foo::Bar>, but it fails with an error like: C<Warning: You do not have
-permissions to install into /usr/lib64/perl5/site_perl/5.8.8/x86_64-linux at
-/usr/lib64/perl5/5.8.8/Foo/Bar.pm> and buried within the install log is an
-error saying C<'INSTALL_BASE' is not a known MakeMaker parameter name>, then
-you've somehow lost your updated ExtUtils::MakeMaker module.
-
-To remedy this situation, rerun the bootstrapping procedure documented above.
-
-Then, run C<rm -r ~/.cpan/build/Foo-Bar*>
-
-Finally, re-run C<cpan -i Foo::Bar> and it should install without problems.
-
-=head1 ENVIRONMENT
-
-=over 4
-
-=item SHELL
-
-=item COMSPEC
-
-local::lib looks at the user's C<SHELL> environment variable when printing out
-commands to add to the shell configuration file.
-
-On Win32 systems, C<COMSPEC> is also examined.
-
-=back
-
-=head1 SUPPORT
-
-IRC:
-
- Join #local-lib on irc.perl.org.
-
-=head1 AUTHOR
-
-Matt S Trout <mst@shadowcat.co.uk> http://www.shadowcat.co.uk/
-
-auto_install fixes kindly sponsored by http://www.takkle.com/
-
-=head1 CONTRIBUTORS
-
-Patches to correctly output commands for csh style shells, as well as some
-documentation additions, contributed by Christopher Nehren <apeiron@cpan.org>.
-
-Doc patches for a custom local::lib directory, more cleanups in the english
-documentation and a L<german documentation|POD2::DE::local::lib> contributed by Torsten Raudssus
-<torsten@raudssus.de>.
-
-Hans Dieter Pearcey <hdp@cpan.org> sent in some additional tests for ensuring
-things will install properly, submitted a fix for the bug causing problems with
-writing Makefiles during bootstrapping, contributed an example program, and
-submitted yet another fix to ensure that local::lib can install and bootstrap
-properly. Many, many thanks!
-
-pattern of Freenode IRC contributed the beginnings of the Troubleshooting
-section. Many thanks!
-
-Patch to add Win32 support contributed by Curtis Jewell <csjewell@cpan.org>.
-
-Warnings for missing PATH/PERL5LIB (as when not running interactively) silenced
-by a patch from Marco Emilio Poleggi.
-
-Mark Stosberg <mark@summersault.com> provided the code for the now deleted
-'--self-contained' option.
-
-Documentation patches to make win32 usage clearer by
-David Mertens <dcmertens.perl@gmail.com> (run4flat).
-
-Brazilian L<portuguese translation|POD2::PT_BR::local::lib> and minor doc patches contributed by Breno
-G. de Oliveira <garu@cpan.org>.
-
-Improvements to stacking multiple local::lib dirs and removing them from the
-environment later on contributed by Andrew Rodland <arodland@cpan.org>.
-
-=head1 COPYRIGHT
-
-Copyright (c) 2007 - 2010 the local::lib L</AUTHOR> and L</CONTRIBUTORS> as
-listed above.
-
-=head1 LICENSE
-
-This library is free software and may be distributed under the same terms
-as perl itself.
-
-=cut
-
-1;
diff --git a/perl-external/minicpan/.gitignore b/perl-external/minicpan/.gitignore
deleted file mode 100644
index 40c08735d..000000000
--- a/perl-external/minicpan/.gitignore
+++ /dev/null
@@ -1,3 +0,0 @@
-authors
-modules/remote_packages.txt.gz
-indexer_reports
diff --git a/perl-external/minicpan/modules/02packages.details.txt.gz b/perl-external/minicpan/modules/02packages.details.txt.gz
deleted file mode 100644
index dda827b07..000000000
--- a/perl-external/minicpan/modules/02packages.details.txt.gz
+++ /dev/null
Binary files differ
diff --git a/perl-external/minicpan/modules/03modlist.data.gz b/perl-external/minicpan/modules/03modlist.data.gz
deleted file mode 100644
index 9c8cc712e..000000000
--- a/perl-external/minicpan/modules/03modlist.data.gz
+++ /dev/null
Binary files differ
diff --git a/perl-external/modules.txt b/perl-external/modules.txt
deleted file mode 100644
index 5ad9b477c..000000000
--- a/perl-external/modules.txt
+++ /dev/null
@@ -1,62 +0,0 @@
-App::cpanminus
-Bundle::DBD::Pg
-CPAN::ParseDistribution
-Catalyst
-Catalyst::Action::RenderView
-Catalyst::Authentication::Store::DBIx::Class
-Catalyst::Devel
-Catalyst::Model::Adaptor
-Catalyst::Plugin::Authentication
-Catalyst::Plugin::ConfigLoader
-Catalyst::Plugin::Session::Store::DBIC
-Catalyst::Plugin::SmartURI
-Catalyst::Plugin::Static::Simple
-Catalyst::Plugin::Unicode
-Catalyst::Plugin::Unicode::Encoding
-Catalyst::Runtime
-Catalyst::View::TT
-Class::Accessor
-Class::Unload
-Config::General
-Crypt::Eksblowfish::Bcrypt
-DBIx::Class
-DBIx::Class::EncodedColumn
-DBIx::Class::EncodedColumn::Crypt::Eksblowfish::Bcrypt
-DBIx::Class::FilterColumn
-DBIx::Class::Schema::Loader
-DBIx::Class::Storage::DBI
-DateTime::Format::HTTP
-DateTime::Format::ISO8601
-DateTime::Format::Pg
-DateTime::Format::W3CDTF
-Email::Address
-Email::MIME
-Email::Send
-Email::Simple
-Email::Valid
-File::Path
-HTML::Entities
-HTML::Form
-HTTP::Server::Simple
-HTTP::Server::Simple::CGI
-IO::String
-JSON
-LWP::UserAgent
-Locale::Maketext::Lexicon
-Moose
-Net::Domain::TLD
-Path::Class
-Readonly
-Return::Value
-Sort::Key
-Spiffy
-Sub::Override
-Template::Plugin::Comma
-Template::Plugin::DateTime::Format
-Term::Size::Any
-Test::More
-Test::WWW::Mechanize
-Test::WWW::Mechanize::Catalyst
-URI
-Web::Scraper
-namespace::autoclean