Initial Commit
This commit is contained in:
292
database/perl/vendor/lib/App/cpanminus.pm
vendored
Normal file
292
database/perl/vendor/lib/App/cpanminus.pm
vendored
Normal file
@@ -0,0 +1,292 @@
|
||||
package App::cpanminus;
|
||||
our $VERSION = "1.7044";
|
||||
|
||||
=encoding utf8
|
||||
|
||||
=head1 NAME
|
||||
|
||||
App::cpanminus - get, unpack, build and install modules from CPAN
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
cpanm Module
|
||||
|
||||
Run C<cpanm -h> or C<perldoc cpanm> 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 https://cpanmin.us | perl - --sudo App::cpanminus
|
||||
|
||||
This will install C<cpanm> to your bin directory like
|
||||
C</usr/local/bin> and you'll need the C<--sudo> option to write to
|
||||
the directory, unless you configured C<INSTALL_BASE> with L<local::lib>.
|
||||
|
||||
=head2 Installing to local perl (perlbrew, plenv etc.)
|
||||
|
||||
If you have perl in your home directory, which is the case if you use
|
||||
tools like L<perlbrew> or plenv, 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 https://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 -L https://cpanmin.us/ -o cpanm
|
||||
chmod +x cpanm
|
||||
|
||||
This just works, but be sure to grab the new version manually when you
|
||||
upgrade because C<--self-upgrade> might not work with this installation setup.
|
||||
|
||||
=head2 Troubleshoot: HTTPS warnings
|
||||
|
||||
When you run C<curl> commands above, you may encounter SSL handshake
|
||||
errors or certification warnings. This is due to your HTTP client
|
||||
(curl) being old, or SSL certificates installed on your system needs
|
||||
to be updated.
|
||||
|
||||
You're recommended to update the software or system if you can. If
|
||||
that is impossible or difficult, use the C<-k> option with curl or an
|
||||
alternative URL, C<https://git.io/cpanm>
|
||||
|
||||
=head1 DEPENDENCIES
|
||||
|
||||
perl 5.8.1 or later.
|
||||
|
||||
=over 4
|
||||
|
||||
=item *
|
||||
|
||||
'tar' executable (bsdtar or GNU tar version 1.22 are recommended) 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 How does cpanm get/parse/update the CPAN index?
|
||||
|
||||
It queries the CPAN Meta DB site at L<http://cpanmetadb.plackperl.org/>.
|
||||
The site is updated at least every hour to reflect the latest changes
|
||||
from fast syncing mirrors. The script then also falls back to query the
|
||||
module at L<http://metacpan.org/> using its search API.
|
||||
|
||||
Upon calling these API hosts, cpanm (1.6004 or later) will send the
|
||||
local perl versions to the server in User-Agent string by default. You
|
||||
can turn it off with C<--no-report-perl-version> option. Read more
|
||||
about the option with L<cpanm>, and read more about the privacy policy
|
||||
about this data collection at L<http://cpanmetadb.plackperl.org/#privacy>
|
||||
|
||||
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>).
|
||||
|
||||
By default, it installs to the site_perl directory that belongs to
|
||||
your perl. You can see the locations for that by running C<perl -V>
|
||||
and it will be likely something under C</opt/local/perl/...> if you're
|
||||
using system perl, or under your home directory if you have built perl
|
||||
yourself using perlbrew or plenv.
|
||||
|
||||
If you've already configured local::lib on your shell, cpanm respects
|
||||
that settings and modules will be installed to your local perl5
|
||||
directory.
|
||||
|
||||
At a boot time, cpanminus checks whether you have already configured
|
||||
local::lib, or have a permission to install modules to the site_perl
|
||||
directory. If neither, i.e. you're using system perl and do not run
|
||||
cpanm as a root, it automatically sets up local::lib compatible
|
||||
installation path in a C<perl5> directory under your home
|
||||
directory.
|
||||
|
||||
To avoid this, run C<cpanm> either as a 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 may have issues with distributions such as follows:
|
||||
|
||||
=over 4
|
||||
|
||||
=item *
|
||||
|
||||
Tests that require input from STDIN.
|
||||
|
||||
=item *
|
||||
|
||||
Build.PL or Makefile.PL that prompts for input even when
|
||||
C<PERL_MM_USE_DEFAULT> 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 to cpanminus.
|
||||
|
||||
=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.
|
||||
|
||||
If you need these features, use L<CPAN>, L<CPANPLUS> or the standalone
|
||||
tools that are mentioned.
|
||||
|
||||
=over 4
|
||||
|
||||
=item *
|
||||
|
||||
CPAN testers reporting. See L<App::cpanminus::reporter>
|
||||
|
||||
=item *
|
||||
|
||||
Building RPM packages from CPAN modules
|
||||
|
||||
=item *
|
||||
|
||||
Listing the outdated modules that needs upgrading. See L<App::cpanoutdated>
|
||||
|
||||
=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<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
|
||||
|
||||
=item L<JSON::PP> Copyright 2007-2011 by Makamaka Hannyaharamitu
|
||||
|
||||
=item L<CPAN::Meta>, L<CPAN::Meta::Requirements> Copyright (c) 2010 by David Golden and Ricardo Signes
|
||||
|
||||
=item L<CPAN::Meta::YAML> Copyright 2010 Adam Kennedy
|
||||
|
||||
=item L<CPAN::Meta::Check> Copyright (c) 2012 by Leon Timmermans
|
||||
|
||||
=item L<File::pushd> Copyright 2012 David Golden
|
||||
|
||||
=item L<parent> Copyright (c) 2007-10 Max Maischein
|
||||
|
||||
=item L<Parse::PMFile> Copyright 1995 - 2013 by Andreas Koenig, Copyright 2013 by Kenichi Ishigaki
|
||||
|
||||
=item L<String::ShellQuote> by Roderick Schertler
|
||||
|
||||
|
||||
=back
|
||||
|
||||
=head1 LICENSE
|
||||
|
||||
This software is licensed under the same terms 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 (mst), 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/#cpanm> - discussions about cpanm and its related tools
|
||||
|
||||
=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;
|
||||
25245
database/perl/vendor/lib/App/cpanminus/fatscript.pm
vendored
Normal file
25245
database/perl/vendor/lib/App/cpanminus/fatscript.pm
vendored
Normal file
File diff suppressed because it is too large
Load Diff
34
database/perl/vendor/lib/App/cpanoutdated.pm
vendored
Normal file
34
database/perl/vendor/lib/App/cpanoutdated.pm
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
package App::cpanoutdated;
|
||||
use strict;
|
||||
use warnings;
|
||||
our $VERSION = "0.32";
|
||||
1;
|
||||
__END__
|
||||
|
||||
=head1 NAME
|
||||
|
||||
App::cpanoutdated - detect outdated CPAN modules in your environment.
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
see L<cpan-outdated>.
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Tokuhiro Matsuno
|
||||
|
||||
=head1 LICENSE
|
||||
|
||||
Copyright (C) 2009 Tokuhiro Matsuno.
|
||||
|
||||
This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
L<CPAN>
|
||||
|
||||
L<App::cpanminus>
|
||||
|
||||
L<App::DualLivedList>
|
||||
|
||||
=cut
|
||||
102
database/perl/vendor/lib/App/local/lib/Win32Helper.pm
vendored
Normal file
102
database/perl/vendor/lib/App/local/lib/Win32Helper.pm
vendored
Normal file
@@ -0,0 +1,102 @@
|
||||
package App::local::lib::Win32Helper; ## no critic(Capitalization)
|
||||
|
||||
=head1 NAME
|
||||
|
||||
App::local::lib::Win32Helper - Helper for Win32 users of local::lib.
|
||||
|
||||
=head1 VERSION
|
||||
|
||||
Version 0.992
|
||||
|
||||
=cut
|
||||
|
||||
use 5.008001;
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
our $VERSION = '0.992';
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
This module is a placeholder for the llwin32helper script, which saves the
|
||||
environment variables that local::lib requires for its use to the Windows
|
||||
registry.
|
||||
|
||||
To run it, just type
|
||||
|
||||
llw32helper
|
||||
|
||||
at the command prompt.
|
||||
|
||||
There are no command line parameters.
|
||||
|
||||
=head1 CONFIGURATION AND ENVIRONMENT
|
||||
|
||||
The default directory to create a L<local::lib|local::lib> library in is
|
||||
determined by $ENV{HOME} if that is given, or the user's default directory
|
||||
if that is not defined.
|
||||
|
||||
The script saves and retrieves information using the Windows registry.
|
||||
|
||||
=head1 DEPENDENCIES
|
||||
|
||||
This script depends on Perl 5.8.1 (because L<local::lib|local::lib> depends
|
||||
on it) and also depends on C<local::lib> version 1.004007,
|
||||
L<IO::Interactive|IO::Interactive> 0.0.5, L<File::HomeDir|File::HomeDir>
|
||||
0.81, L<Win32::TieRegistry|Win32::TieRegistry> 0.26, and
|
||||
L<File::Spec|File::Spec> 3.2701.
|
||||
|
||||
=head1 BUGS AND LIMITATIONS
|
||||
|
||||
Please report any bugs or feature requests to
|
||||
C<< <bug-App-local-lib-Win32Helper at rt.cpan.org> >>, or through the web
|
||||
interface at L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=local-lib-Win32>.
|
||||
I will be notified, and then you'll automatically be notified of progress on
|
||||
your bug as I make changes.
|
||||
|
||||
=head1 SUPPORT
|
||||
|
||||
You can find documentation for this module with the perldoc command.
|
||||
|
||||
perldoc App::local::lib::Win32Helper
|
||||
|
||||
You can also look for information at:
|
||||
|
||||
=over 4
|
||||
|
||||
=item * RT: CPAN's request tracker
|
||||
|
||||
L<http://rt.cpan.org/NoAuth/Bugs.html?Dist=App-local-lib-Win32Helper>
|
||||
|
||||
=item * AnnoCPAN: Annotated CPAN documentation
|
||||
|
||||
L<http://annocpan.org/dist/App-local-lib-Win32Helper>
|
||||
|
||||
=item * CPAN Ratings
|
||||
|
||||
L<http://cpanratings.perl.org/d/App-local-lib-Win32Helper>
|
||||
|
||||
=item * Search CPAN
|
||||
|
||||
L<http://search.cpan.org/dist/App-local-lib-Win32Helper/>
|
||||
|
||||
=back
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Curtis Jewell, C<< <csjewell at cpan.org> >>
|
||||
|
||||
=head1 LICENSE AND COPYRIGHT
|
||||
|
||||
Copyright 2010 Curtis Jewell.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of either: the GNU General Public License as published
|
||||
by the Free Software Foundation; or the Artistic License.
|
||||
|
||||
See http://dev.perl.org/licenses/ for more information.
|
||||
|
||||
|
||||
=cut
|
||||
|
||||
1; # End of App::local::lib::Win32Helper
|
||||
194
database/perl/vendor/lib/App/module/version.pm
vendored
Normal file
194
database/perl/vendor/lib/App/module/version.pm
vendored
Normal file
@@ -0,0 +1,194 @@
|
||||
package App::module::version;
|
||||
|
||||
use 5.008009;
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use Getopt::Long 2.13 qw(GetOptionsFromArray);
|
||||
use Pod::Usage qw(pod2usage);
|
||||
use English qw( -no_match_vars );
|
||||
use Config;
|
||||
use File::Spec::Functions qw(splitpath catfile);
|
||||
use Carp qw(carp);
|
||||
|
||||
# following recommendation from http://www.dagolden.com/index.php/369/version-numbers-should-be-boring/
|
||||
our $VERSION = "1.004";
|
||||
$VERSION = eval $VERSION;
|
||||
|
||||
sub new {
|
||||
my $class = shift;
|
||||
return bless {
|
||||
prompt => 0,
|
||||
prompted => [],
|
||||
list => [],
|
||||
}, $class;
|
||||
}
|
||||
|
||||
sub parse_options {
|
||||
my $self = shift;
|
||||
my @a = @_;
|
||||
|
||||
GetOptionsFromArray(\@a,
|
||||
'help|?' => sub { pod2usage(-exitstatus => 0, -verbose => 0); },
|
||||
'man' => sub { pod2usage(-exitstatus => 0, -verbose => 2); },
|
||||
'usage' => sub { _usage(); },
|
||||
'version' => sub { _version(); exit(1); },
|
||||
'prompt' => \$self->{prompt},
|
||||
) or pod2usage(-verbose => 2);
|
||||
|
||||
if (0 == scalar @a) {
|
||||
$self->{prompt} = 1;
|
||||
}
|
||||
else {
|
||||
@{$self->{list}} = @a;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
sub do_job {
|
||||
my $self = shift;
|
||||
|
||||
if ($self->{prompt}) {
|
||||
_version();
|
||||
print "\nPlease type in a space-separated list of modules you want to find\nthe installed versions for below.\n> ";
|
||||
my $cmd = <STDIN>;
|
||||
@{$self->{prompted}} = split m{\s+}, $cmd;
|
||||
}
|
||||
|
||||
print "\n";
|
||||
my $version_info;
|
||||
MODULE:
|
||||
for my $module (@{$self->{list}}, @{$self->{prompted}}) {
|
||||
if ('perl' eq lc($module)) {
|
||||
print "The version of perl is $PERL_VERSION on $OSNAME ($Config{archname})\n";
|
||||
next MODULE;
|
||||
}
|
||||
|
||||
if ($module =~ m/\Astrawberry (?:perl)?\z/imsx) {
|
||||
if (('MSWin32' ne $OSNAME) or ($Config{libperl} !~ m{\.a\z}msx)) {
|
||||
print "This is not Strawberry Perl.\n";
|
||||
}
|
||||
|
||||
if (($Config{libperl} =~ m{\.a\z}msx) and ($Config{myuname} !~ m/\AWin32 [ ] strawberryperl/msx )) {
|
||||
print "This is not a new enough version of Strawberry Perl to easily tell what version it is.\n";
|
||||
next MODULE;
|
||||
}
|
||||
|
||||
my ($strawberryversion, $bits) = (q{}, q{});
|
||||
if ($Config{myuname} =~
|
||||
m{\AWin32 [ ] strawberryperl [ ] # Starting code.
|
||||
(\S+) # Version
|
||||
.* [ ] # The date Strawberry Perl was built.
|
||||
(\S+)\z # The version
|
||||
}msx) {
|
||||
($strawberryversion, $bits) = ($1, $2);
|
||||
$bits = ('i386' eq $bits) ? 32 : 64;
|
||||
}
|
||||
print "The version of Strawberry Perl is $strawberryversion ($bits-bit), using gcc $Config{gccversion}\n";
|
||||
next MODULE;
|
||||
}
|
||||
|
||||
if ('activeperl' eq lc($module)) {
|
||||
my $buildnumber = eval { return Win32::BuildNumber() };
|
||||
if ($EVAL_ERROR) {
|
||||
print "This is not ActivePerl (at least, not on Windows.)\n";
|
||||
next MODULE;
|
||||
}
|
||||
print "The version of ActivePerl is $PERL_VERSION build number $buildnumber\n";
|
||||
next MODULE;
|
||||
}
|
||||
|
||||
my $version_info = {};
|
||||
my $module_file = catfile(split(/::/, $module));
|
||||
|
||||
DIRECTORY: foreach my $dir (@INC) {
|
||||
my $filename = catfile($dir, "$module_file.pm");
|
||||
if (-e $filename ) {
|
||||
$version_info->{dir} = $dir;
|
||||
if (open IN, "$filename") {
|
||||
while (<IN>) {
|
||||
# the following regexp comes from the Extutils::MakeMaker
|
||||
# documentation.
|
||||
if (/([\$*])(([\w\:\']*)\bVERSION)\b.*\=/) {
|
||||
local $VERSION;
|
||||
my $res = eval $_;
|
||||
$version_info->{version} = $VERSION || $res;
|
||||
last DIRECTORY;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
carp "Can't open $filename: $!";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (exists $version_info->{dir}) {
|
||||
if (exists $version_info->{version}) {
|
||||
print "The version of $module in " . $version_info->{dir} . ' is ' . $version_info->{version} . "\n";
|
||||
} else {
|
||||
print "$module is installed in " . $version_info->{dir} . ", but does not have a detectable version.\n";
|
||||
}
|
||||
} else {
|
||||
print "$module could not be found.\n";
|
||||
}
|
||||
}
|
||||
|
||||
print "\n";
|
||||
|
||||
if ($self->{prompt}) {
|
||||
require Term::ReadKey;
|
||||
my $char = undef;
|
||||
print "Press any key to exit.\n";
|
||||
$char = Term::ReadKey::ReadKey(-1) until $char;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
sub _version {
|
||||
|
||||
my (undef, undef, $script) = splitpath( $PROGRAM_NAME );
|
||||
|
||||
print <<"EOF";
|
||||
This is $script, version $VERSION, which checks the
|
||||
installed version of the modules named on the command line.
|
||||
|
||||
Copyright 2010 Curtis Jewell.
|
||||
|
||||
This script may be copied only under the terms of either the Artistic License
|
||||
or the GNU General Public License, which may be found in the Perl 5
|
||||
distribution or the distribution containing this script.
|
||||
EOF
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
sub _usage {
|
||||
my $error = shift;
|
||||
|
||||
print "Error: $error\n\n" if (defined $error);
|
||||
my (undef, undef, $script) = splitpath( $PROGRAM_NAME );
|
||||
|
||||
print <<"EOF";
|
||||
This is $script, version $VERSION, which checks the
|
||||
installed version of the modules named on the command line.
|
||||
|
||||
Usage: $script [ --help ] [ --usage ] [ --man ] [ --version ] [ -? ]
|
||||
[--prompt] Module::To::Check ...
|
||||
|
||||
For more assistance, run $script --help.
|
||||
EOF
|
||||
|
||||
exit(1);
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=head1 NAME
|
||||
|
||||
App::module::version - Gets the version info about a module
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This is just a helper module for the main script L<module-version|module-version>.
|
||||
527
database/perl/vendor/lib/App/pmuninstall.pm
vendored
Normal file
527
database/perl/vendor/lib/App/pmuninstall.pm
vendored
Normal file
@@ -0,0 +1,527 @@
|
||||
package App::pmuninstall;
|
||||
use strict;
|
||||
use warnings;
|
||||
use File::Spec;
|
||||
use File::Basename qw(dirname);
|
||||
use Getopt::Long qw(GetOptions :config bundling);
|
||||
use Config;
|
||||
use YAML ();
|
||||
use CPAN::DistnameInfo;
|
||||
use version;
|
||||
use HTTP::Tiny;
|
||||
use Term::ANSIColor qw(colored);
|
||||
use Cwd ();
|
||||
use JSON::PP qw(decode_json);
|
||||
|
||||
our $VERSION = "0.30";
|
||||
|
||||
my $perl_version = version->new($])->numify;
|
||||
my $depended_on_by = 'http://deps.cpantesters.org/depended-on-by.pl?dist=';
|
||||
my $cpanmetadb = 'http://cpanmetadb.plackperl.org/v1.0/package';
|
||||
my @core_modules_dir = do { my %h; grep !$h{$_}++, @Config{qw/archlib archlibexp privlib privlibexp/} };
|
||||
|
||||
$ENV{ANSI_COLORS_DISABLED} = 1 if $^O eq 'MSWin32';
|
||||
|
||||
our $OUTPUT_INDENT_LEVEL = 0;
|
||||
|
||||
sub new {
|
||||
my ($class, $inc) = @_;
|
||||
$inc = [@INC] unless ref $inc eq 'ARRAY';
|
||||
bless {
|
||||
check_deps => 1,
|
||||
verbose => 0,
|
||||
inc => $class->prepare_include_paths($inc),
|
||||
}, $class;
|
||||
}
|
||||
|
||||
sub run {
|
||||
my ($self, @args) = @_;
|
||||
local @ARGV = @args;
|
||||
GetOptions(
|
||||
'f|force' => \$self->{force},
|
||||
'v|verbose!' => sub { ++$self->{verbose} },
|
||||
'c|checkdeps!' => \$self->{check_deps},
|
||||
'n|no-checkdeps!' => sub { $self->{check_deps} = 0 },
|
||||
'q|quiet!' => \$self->{quiet},
|
||||
'h|help!' => sub { $self->usage },
|
||||
'V|version!' => \$self->{version},
|
||||
'l|local-lib=s' => \$self->{local_lib},
|
||||
'L|local-lib-contained=s' => sub {
|
||||
$self->{local_lib} = $_[1];
|
||||
$self->{self_contained} = 1;
|
||||
},
|
||||
) or $self->usage;
|
||||
|
||||
if ($self->{version}) {
|
||||
$self->puts("pm-uninstall (App::pmuninstall) version $App::pmuninstall::VERSION");
|
||||
exit;
|
||||
}
|
||||
|
||||
$self->short_usage unless @ARGV;
|
||||
|
||||
$self->uninstall(@ARGV);
|
||||
}
|
||||
|
||||
sub uninstall {
|
||||
my ($self, @modules) = @_;
|
||||
|
||||
$self->setup_local_lib;
|
||||
|
||||
my $uninstalled = 0;
|
||||
for my $module (@modules) {
|
||||
$self->puts("--> Working on $module") unless $self->{quiet};
|
||||
my ($packlist, $dist, $vname) = $self->find_packlist($module);
|
||||
|
||||
$packlist = File::Spec->catfile($packlist);
|
||||
if ($self->is_core_module($module, $packlist)) {
|
||||
$self->puts(colored ['red'], "! $module is a core module!! Can't be uninstalled.");
|
||||
$self->puts unless $self->{quiet};
|
||||
next;
|
||||
}
|
||||
|
||||
unless ($dist) {
|
||||
$self->puts(colored ['red'], "! $module not found.");
|
||||
$self->puts unless $self->{quiet};
|
||||
next;
|
||||
}
|
||||
|
||||
unless ($packlist) {
|
||||
$self->puts(colored ['red'], "! $module is not installed.");
|
||||
$self->puts unless $self->{quiet};
|
||||
next;
|
||||
}
|
||||
|
||||
if ($self->ask_permission($module, $dist, $vname, $packlist)) {
|
||||
if ($self->uninstall_from_packlist($packlist)) {
|
||||
$self->puts(colored ['green'], "Successfully uninstalled $module");
|
||||
++$uninstalled;
|
||||
}
|
||||
else {
|
||||
$self->puts(colored ['red'], "! Failed to uninstall $module");
|
||||
}
|
||||
$self->puts unless $self->{quiet};
|
||||
}
|
||||
}
|
||||
|
||||
if ($uninstalled) {
|
||||
$self->puts if $self->{quiet};
|
||||
$self->puts("You may want to rebuild man(1) entries. Try `mandb -c` if needed");
|
||||
}
|
||||
|
||||
return $uninstalled;
|
||||
}
|
||||
|
||||
sub uninstall_from_packlist {
|
||||
my ($self, $packlist) = @_;
|
||||
|
||||
my $inc = {
|
||||
map { File::Spec->catfile($_) => 1 } @{$self->{inc}}
|
||||
};
|
||||
|
||||
my $failed;
|
||||
for my $file ($self->fixup_packlist($packlist)) {
|
||||
chomp $file;
|
||||
$self->puts(-f $file ? 'unlink ' : 'not found', " : $file") if $self->{verbose};
|
||||
unlink $file or $self->puts("$file: $!") and $failed++;
|
||||
$self->rm_empty_dir_from_file($file, $inc);
|
||||
}
|
||||
$self->puts("unlink : $packlist") if $self->{verbose};
|
||||
unlink $packlist or $self->puts("$packlist: $!") and $failed++;
|
||||
$self->rm_empty_dir_from_file($packlist, $inc);
|
||||
|
||||
if (my $install_json = $self->{install_json}) {
|
||||
$self->puts("unlink : $install_json") if $self->{verbose};
|
||||
unlink $install_json or $self->puts("$install_json: $!") and $failed++;
|
||||
$self->rm_empty_dir_from_file($install_json);
|
||||
}
|
||||
|
||||
$self->puts unless $self->{quiet} || $self->{force};
|
||||
return !$failed;
|
||||
}
|
||||
|
||||
sub rm_empty_dir_from_file {
|
||||
my ($self, $file, $inc) = @_;
|
||||
my $dir = dirname $file;
|
||||
return unless -d $dir;
|
||||
return if $inc->{+File::Spec->catfile($dir)};
|
||||
|
||||
my $failed;
|
||||
if ($self->is_empty_dir($dir)) {
|
||||
$self->puts("rmdir : $dir") if $self->{verbose};
|
||||
rmdir $dir or $self->puts("$dir: $!") and $failed++;
|
||||
$self->rm_empty_dir_from_file($dir, $inc);
|
||||
}
|
||||
|
||||
return !$failed;
|
||||
}
|
||||
|
||||
sub is_empty_dir {
|
||||
my ($self, $dir) = @_;
|
||||
opendir my $dh, $dir or die "$dir: $!";
|
||||
my @dir = grep !/^\.{1,2}$/, readdir $dh;
|
||||
closedir $dh;
|
||||
return @dir ? 0 : 1;
|
||||
}
|
||||
|
||||
sub find_packlist {
|
||||
my ($self, $module) = @_;
|
||||
$self->puts("Finding $module in your \@INC") if $self->{verbose};
|
||||
|
||||
# find with the given name first
|
||||
(my $try_dist = $module) =~ s!::!-!g;
|
||||
if (my $pl = $self->locate_pack($try_dist)) {
|
||||
$self->puts("-> Found $pl") if $self->{verbose};
|
||||
return ($pl, $try_dist);
|
||||
}
|
||||
|
||||
$self->puts("Looking up $module on cpanmetadb") if $self->{verbose};
|
||||
|
||||
# map module -> dist and retry
|
||||
my $yaml = $self->fetch("$cpanmetadb/$module") or return;
|
||||
my $meta = YAML::Load($yaml);
|
||||
my $info = CPAN::DistnameInfo->new($meta->{distfile});
|
||||
|
||||
my $name = $self->find_meta($info->distvname) || $info->dist;
|
||||
if (my $pl = $self->locate_pack($name)) {
|
||||
$self->puts("-> Found $pl") if $self->{verbose};
|
||||
return ($pl, $info->dist, $info->distvname);
|
||||
}
|
||||
}
|
||||
|
||||
sub find_meta {
|
||||
my ($self, $distvname) = @_;
|
||||
|
||||
my $name;
|
||||
for my $lib (@{$self->{inc}}) {
|
||||
next unless $lib =~ /$Config{archname}/;
|
||||
my $install_json = "$lib/.meta/$distvname/install.json";
|
||||
next unless -f $install_json && -r _;
|
||||
my $data = decode_json +$self->slurp($install_json);
|
||||
$name = $data->{name} || next;
|
||||
$self->puts("-> Found $install_json") if $self->{verbose};
|
||||
$self->{meta} = $install_json;
|
||||
last;
|
||||
}
|
||||
return $name;
|
||||
}
|
||||
|
||||
sub locate_pack {
|
||||
my ($self, $dist) = @_;
|
||||
$dist =~ s!-!/!g;
|
||||
for my $lib (@{$self->{inc}}) {
|
||||
my $packlist = "$lib/auto/$dist/.packlist";
|
||||
$self->puts("-> Finding .packlist $packlist") if $self->{verbose} > 1;
|
||||
return $packlist if -f $packlist && -r _;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
sub is_core_module {
|
||||
my ($self, $dist, $packlist) = @_;
|
||||
require Module::CoreList;
|
||||
return unless exists $Module::CoreList::version{$perl_version}{$dist};
|
||||
return 1 unless $packlist;
|
||||
|
||||
my $is_core = 0;
|
||||
for my $dir (@core_modules_dir) {
|
||||
my $safe_dir = quotemeta $dir; # workaround for MSWin32
|
||||
if ($packlist =~ /^$safe_dir/) {
|
||||
$is_core = 1;
|
||||
last;
|
||||
}
|
||||
}
|
||||
return $is_core;
|
||||
}
|
||||
|
||||
sub ask_permission {
|
||||
my($self, $module, $dist, $vname, $packlist) = @_;
|
||||
|
||||
my @deps = $self->find_deps($vname, $module);
|
||||
|
||||
$self->puts if $self->{verbose};
|
||||
$self->puts("$module is included in the distribution $dist and contains:\n")
|
||||
unless $self->{quiet};
|
||||
for my $file ($self->fixup_packlist($packlist)) {
|
||||
chomp $file;
|
||||
$self->puts(" $file") unless $self->{quiet};
|
||||
}
|
||||
$self->puts unless $self->{quiet};
|
||||
|
||||
return 'force uninstall' if $self->{force};
|
||||
|
||||
my $default = 'y';
|
||||
if (@deps) {
|
||||
$self->puts("Also, they're depended on by the following installed dists:\n");
|
||||
for my $dep (@deps) {
|
||||
$self->puts(" $dep");
|
||||
}
|
||||
$self->puts;
|
||||
$default = 'n';
|
||||
}
|
||||
|
||||
return lc($self->prompt("Are you sure you want to uninstall $dist?", $default)) eq 'y';
|
||||
}
|
||||
|
||||
sub find_deps {
|
||||
my ($self, $vname, $module) = @_;
|
||||
|
||||
return unless $self->{check_deps} && !$self->{force};
|
||||
$vname ||= $self->vname_for($module) or return;
|
||||
|
||||
$self->puts("Checking modules depending on $vname") if $self->{verbose};
|
||||
my $content = $self->fetch("$depended_on_by$vname") or return;
|
||||
|
||||
my (@deps, %seen);
|
||||
for my $dep ($content =~ m|<li><a href=[^>]+>([a-zA-Z0-9_:-]+)|smg) {
|
||||
$dep =~ s/^\s+|\s+$//smg; # trim
|
||||
next if $seen{$dep}++;
|
||||
local $OUTPUT_INDENT_LEVEL = $OUTPUT_INDENT_LEVEL + 1;
|
||||
$self->puts("Finding $dep in your \@INC (dependencies)") if $self->{verbose};
|
||||
push @deps, $dep if $self->locate_pack($dep);
|
||||
}
|
||||
|
||||
return @deps;
|
||||
}
|
||||
|
||||
sub prompt {
|
||||
my ($self, $msg, $default) = @_;
|
||||
require ExtUtils::MakeMaker;
|
||||
ExtUtils::MakeMaker::prompt($msg, $default);
|
||||
}
|
||||
|
||||
sub fixup_packlist {
|
||||
my ($self, $packlist) = @_;
|
||||
my @target_list;
|
||||
my $is_local_lib = $self->is_local_lib($packlist);
|
||||
open my $in, "<", $packlist or die "$packlist: $!";
|
||||
while (defined (my $file = <$in>)) {
|
||||
if ($is_local_lib) {
|
||||
next unless $self->is_local_lib($file);
|
||||
}
|
||||
push @target_list, $file;
|
||||
}
|
||||
return @target_list;
|
||||
}
|
||||
|
||||
sub is_local_lib {
|
||||
my ($self, $file) = @_;
|
||||
return unless $self->{local_lib};
|
||||
|
||||
my $local_lib_base = quotemeta File::Spec->catfile(Cwd::realpath($self->{local_lib}));
|
||||
$file = File::Spec->catfile($file);
|
||||
|
||||
return $file =~ /^$local_lib_base/ ? 1 : 0;
|
||||
}
|
||||
|
||||
sub vname_for {
|
||||
my ($self, $module) = @_;
|
||||
|
||||
$self->puts("Fetching $module vname on cpanmetadb") if $self->{verbose};
|
||||
my $yaml = $self->fetch("$cpanmetadb/$module") or return;
|
||||
my $meta = YAML::Load($yaml);
|
||||
my $info = CPAN::DistnameInfo->new($meta->{distfile}) or return;
|
||||
|
||||
return $info->distvname;
|
||||
}
|
||||
|
||||
# taken from cpan-outdated
|
||||
sub setup_local_lib {
|
||||
my $self = shift;
|
||||
return unless $self->{local_lib};
|
||||
|
||||
unless (-d $self->{local_lib}) {
|
||||
$self->puts(colored ['red'], "! $self->{local_lib} : no such directory");
|
||||
exit 1;
|
||||
}
|
||||
|
||||
local $SIG{__WARN__} = sub { }; # catch 'Attempting to write ...'
|
||||
$self->{inc} = [
|
||||
map { Cwd::realpath($_) }
|
||||
@{$self->build_active_perl5lib($self->{local_lib}, $self->{self_contained})}
|
||||
];
|
||||
push @{$self->{inc}}, @INC unless $self->{self_contained};
|
||||
}
|
||||
|
||||
sub build_active_perl5lib {
|
||||
my ($self, $path, $interpolate) = @_;
|
||||
my $perl5libs = [
|
||||
$self->install_base_arch_path($path),
|
||||
$self->install_base_perl_path($path),
|
||||
$interpolate && $ENV{PERL5LIB} ? $ENV{PERL5LIB} : (),
|
||||
];
|
||||
return $perl5libs;
|
||||
}
|
||||
|
||||
sub install_base_perl_path {
|
||||
my ($self, $path) = @_;
|
||||
File::Spec->catdir($path, 'lib', 'perl5');
|
||||
}
|
||||
|
||||
sub install_base_arch_path {
|
||||
my ($self, $path) = @_;
|
||||
File::Spec->catdir($self->install_base_perl_path($path), $Config{archname});
|
||||
}
|
||||
|
||||
sub fetch {
|
||||
my ($self, $url) = @_;
|
||||
$self->puts("-> Fetching from $url") if $self->{verbose};
|
||||
my $res = HTTP::Tiny->new->get($url);
|
||||
return if $res->{status} == 404;
|
||||
die "[$res->{status}] fetch $url failed!!\n" if !$res->{success};
|
||||
return $res->{content};
|
||||
}
|
||||
|
||||
sub slurp {
|
||||
my ($self, $file) = @_;
|
||||
open my $fh, '<', $file or die "$file $!";
|
||||
do { local $/; <$fh> };
|
||||
}
|
||||
|
||||
sub puts {
|
||||
my ($self, @msg) = @_;
|
||||
push @msg, '' unless @msg;
|
||||
print ' ' x $OUTPUT_INDENT_LEVEL if $OUTPUT_INDENT_LEVEL;
|
||||
print @msg, "\n";
|
||||
}
|
||||
|
||||
sub usage {
|
||||
my $self = shift;
|
||||
$self->puts(<< 'USAGE');
|
||||
Usage:
|
||||
pm-uninstall [options] Module [...]
|
||||
|
||||
options:
|
||||
-v,--verbose Turns on chatty output
|
||||
-f,--force Uninstalls without prompts
|
||||
-c,--checkdeps Check dependencies (defaults to on)
|
||||
-n,--no-checkdeps Don't check dependencies
|
||||
-q,--quiet Suppress some messages
|
||||
-h,--help This help message
|
||||
-V,--version Show version
|
||||
-l,--local-lib Additional module path
|
||||
-L,--local-lib-contained Additional module path (don't include non-core modules)
|
||||
USAGE
|
||||
|
||||
exit 1;
|
||||
}
|
||||
|
||||
sub short_usage {
|
||||
my $self = shift;
|
||||
$self->puts(<< 'USAGE');
|
||||
Usage: pm-uninstall [options] Module [...]
|
||||
|
||||
Try `pm-uninstall --help` or `man pm-uninstall` for more options.
|
||||
USAGE
|
||||
|
||||
exit 1;
|
||||
}
|
||||
|
||||
sub prepare_include_paths {
|
||||
my ($class, $inc) = @_;
|
||||
my $new_inc = [];
|
||||
my $archname = quotemeta $Config{archname};
|
||||
for my $path (@$inc) {
|
||||
push @$new_inc, $path;
|
||||
next if $path eq '.' or $path =~ /$archname/;
|
||||
push @$new_inc, File::Spec->catdir($path, $Config{archname});
|
||||
}
|
||||
return [do { my %h; grep !$h{$_}++, @$new_inc }];
|
||||
}
|
||||
|
||||
1;
|
||||
__END__
|
||||
|
||||
=head1 NAME
|
||||
|
||||
App::pmuninstall - Uninstall modules
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
App::pmuninstall is a fast module uninstaller.
|
||||
delete files from B<.packlist>.
|
||||
|
||||
L<App::cpanminus> and, L<App::cpanoutdated> with a high affinity.
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
uninstall MODULE
|
||||
|
||||
$ pm-uninstall App::pmuninstall
|
||||
|
||||
=head1 OPTIONS
|
||||
|
||||
=over
|
||||
|
||||
=item -f, --force
|
||||
|
||||
Uninstalls without prompts
|
||||
|
||||
$ pm-uninstall -f App::pmuninstall
|
||||
|
||||
=item -v, --verbose
|
||||
|
||||
Turns on chatty output
|
||||
|
||||
$ pm-uninstall -v App::cpnaminus
|
||||
|
||||
=item -c, --checkdeps
|
||||
|
||||
Check dependencies ( default on )
|
||||
|
||||
$ pm-uninstall -c Plack
|
||||
|
||||
=item -n, --no-checkdeps
|
||||
|
||||
Don't check dependencies
|
||||
|
||||
$ pm-uninstall -n LWP
|
||||
|
||||
=item -q, --quiet
|
||||
|
||||
Suppress some messages
|
||||
|
||||
$ pm-uninstall -q Furl
|
||||
|
||||
=item -h, --help
|
||||
|
||||
Show help message
|
||||
|
||||
$ pm-uninstall -h
|
||||
|
||||
=item -V, --version
|
||||
|
||||
Show version
|
||||
|
||||
$ pm-uninstall -V
|
||||
|
||||
=item -l, --local-lib
|
||||
|
||||
Additional module path
|
||||
|
||||
$ pm-uninstall -l extlib App::pmuninstall
|
||||
|
||||
=item -L, --local-lib-contained
|
||||
|
||||
Additional module path (don't include non-core modules)
|
||||
|
||||
$ pm-uninstall -L extlib App::pmuninstall
|
||||
|
||||
=back
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Yuji Shimada
|
||||
|
||||
Tatsuhiko Miyagawa
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
L<pm-uninstall>
|
||||
|
||||
=head1 LICENSE
|
||||
|
||||
This library is free software; you can redistribute it and/or modify
|
||||
it under the same terms as Perl itself.
|
||||
|
||||
=cut
|
||||
|
||||
Reference in New Issue
Block a user