├── .gitignore ├── t └── 00_compile.t ├── Changes ├── .shipit ├── xt └── pod.t ├── MANIFEST.SKIP ├── lib └── CPAN │ ├── Any │ ├── cpanminus.pm │ ├── Base.pm │ ├── CPANPLUS.pm │ └── CPAN.pm │ └── Any.pm ├── MANIFEST ├── Makefile.PL └── README /.gitignore: -------------------------------------------------------------------------------- 1 | META.yml 2 | Makefile 3 | inc/ 4 | pm_to_blib 5 | *~ 6 | lib/CPAN/Any/Config.pm 7 | -------------------------------------------------------------------------------- /t/00_compile.t: -------------------------------------------------------------------------------- 1 | use strict; 2 | use Test::More tests => 1; 3 | 4 | BEGIN { use_ok 'CPAN::Any' } 5 | -------------------------------------------------------------------------------- /Changes: -------------------------------------------------------------------------------- 1 | Revision history for Perl extension CPAN::Any 2 | 3 | 0.01 Wed Dec 15 15:20:59 2010 4 | - original version 5 | -------------------------------------------------------------------------------- /.shipit: -------------------------------------------------------------------------------- 1 | steps = FindVersion, ChangeVersion, CheckChangeLog, DistTest, Commit, Tag, MakeDist, UploadCPAN 2 | git.push_to = origin 3 | -------------------------------------------------------------------------------- /xt/pod.t: -------------------------------------------------------------------------------- 1 | use Test::More; 2 | eval "use Test::Pod 1.00"; 3 | plan skip_all => "Test::Pod 1.00 required for testing POD" if $@; 4 | all_pod_files_ok(); 5 | -------------------------------------------------------------------------------- /MANIFEST.SKIP: -------------------------------------------------------------------------------- 1 | \bRCS\b 2 | \bCVS\b 3 | \.svn/ 4 | \.git/ 5 | ^MANIFEST\. 6 | ^Makefile$ 7 | ~$ 8 | \.old$ 9 | ^blib/ 10 | ^pm_to_blib 11 | ^MakeMaker-\d 12 | \.gz$ 13 | \.cvsignore 14 | \.shipit 15 | lib/CPAN/Any/Config.pm 16 | -------------------------------------------------------------------------------- /lib/CPAN/Any/cpanminus.pm: -------------------------------------------------------------------------------- 1 | package CPAN::Any::cpanminus; 2 | use strict; 3 | use parent qw(CPAN::Any::Base); 4 | 5 | sub install_module { 6 | my($self, @modules) = @_; 7 | !system("cpanm", @modules); 8 | } 9 | 10 | 1; 11 | -------------------------------------------------------------------------------- /lib/CPAN/Any/Base.pm: -------------------------------------------------------------------------------- 1 | package CPAN::Any::Base; 2 | use strict; 3 | 4 | sub new { 5 | my $class = shift; 6 | bless {}, $class; 7 | } 8 | 9 | sub name { 10 | my $self = shift; 11 | my $name = ref $self; 12 | $name =~ s/.*:://; 13 | $name; 14 | } 15 | 16 | 1; 17 | 18 | -------------------------------------------------------------------------------- /lib/CPAN/Any/CPANPLUS.pm: -------------------------------------------------------------------------------- 1 | package CPAN::Any::CPANPLUS; 2 | use strict; 3 | use parent qw(CPAN::Any::Base); 4 | 5 | use CPANPLUS (); 6 | 7 | my $backend; 8 | 9 | sub install_module { 10 | my($self, @modules) = @_; 11 | 12 | $backend ||= CPANPLUS::Backend->new; 13 | $backend->install(modules => \@modules); 14 | } 15 | 16 | 1; 17 | -------------------------------------------------------------------------------- /lib/CPAN/Any/CPAN.pm: -------------------------------------------------------------------------------- 1 | package CPAN::Any::CPAN; 2 | use strict; 3 | use parent qw(CPAN::Any::Base); 4 | 5 | use CPAN (); 6 | 7 | sub install_module { 8 | my($self, @modules) = @_; 9 | 10 | my @r; 11 | for my $module (@modules) { 12 | my $mod = CPAN::Shell->expand("Module", $module); 13 | push @r, CPAN::Shell->install($mod); # Seems CPAN.pm passes 1 even if it fails 14 | } 15 | 16 | return @r == @modules; 17 | } 18 | 19 | 1; 20 | -------------------------------------------------------------------------------- /MANIFEST: -------------------------------------------------------------------------------- 1 | .gitignore 2 | Changes 3 | inc/Module/Install.pm 4 | inc/Module/Install/Base.pm 5 | inc/Module/Install/Can.pm 6 | inc/Module/Install/Fetch.pm 7 | inc/Module/Install/Makefile.pm 8 | inc/Module/Install/Metadata.pm 9 | inc/Module/Install/ReadmeFromPod.pm 10 | inc/Module/Install/Repository.pm 11 | inc/Module/Install/Win32.pm 12 | inc/Module/Install/WriteAll.pm 13 | lib/CPAN/Any.pm 14 | lib/CPAN/Any/Base.pm 15 | lib/CPAN/Any/CPAN.pm 16 | lib/CPAN/Any/cpanminus.pm 17 | lib/CPAN/Any/CPANPLUS.pm 18 | Makefile.PL 19 | MANIFEST This list of files 20 | META.yml 21 | README 22 | t/00_compile.t 23 | xt/pod.t 24 | -------------------------------------------------------------------------------- /Makefile.PL: -------------------------------------------------------------------------------- 1 | use inc::Module::Install; 2 | all_from 'lib/CPAN/Any.pm'; 3 | readme_from('lib/CPAN/Any.pm'); 4 | requires 'UNIVERSAL::require'; 5 | requires 'parent'; 6 | build_requires 'Test::More', 0.88; 7 | test_requires 'Test::Requires'; 8 | auto_set_repository(); 9 | write_config_pm(); 10 | WriteAll; 11 | 12 | sub write_config_pm { 13 | my $client = get_client_type(); 14 | 15 | $client = $client ? qq('$client') : "undef"; 16 | 17 | open my $out, ">", "lib/CPAN/Any/Config.pm" or die $!; 18 | print $out <. 31 | 32 | =head1 SEE ALSO 33 | 34 | L 35 | 36 | =cut 37 | EOF 38 | } 39 | 40 | sub get_client_type { 41 | # NOTE: Both cpanm and CPANPLUS try to cheat Module::Install 42 | # etc. that they're CPAN.pm, so we should go with the reverse 43 | # order. 44 | 45 | if ($ENV{PERL5_CPANM_IS_RUNNING}) { 46 | return 'cpanminus'; 47 | } 48 | 49 | # CPAN.pm sets CPANPLUS_IS_RUNNING too :( 50 | # https://rt.cpan.org/Ticket/Display.html?id=2373 51 | if ($ENV{PERL5_CPANPLUS_IS_EXECUTING}) { 52 | return 'CPANPLUS'; 53 | } 54 | 55 | if ($ENV{PERL5_CPAN_IS_RUNNING}) { 56 | return 'CPAN'; 57 | } 58 | 59 | return; 60 | } 61 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | NAME 2 | CPAN::Any - Install Perl modules using any of CPAN clients 3 | 4 | SYNOPSIS 5 | use CPAN::Any; 6 | 7 | # install modules using the user's favorite installer 8 | CPAN::Any->install_module("Plack"); 9 | 10 | # explicitly specify which client to use 11 | my $cpan = CPAN::Any->new("cpanm"); 12 | $cpan->install_module("Catalyst"); 13 | 14 | DESCRIPTION 15 | CPAN::Any is an interface to install Perl modules using any CPAN client. 16 | 17 | WHY 18 | There are many tools and modules that use (one of) CPAN clients to 19 | install modules, and most of them hardcode the author's favorite CPAN 20 | clients, either CPAN, CPANPLUS or cpanm. Examples are Dist::Zilla, 21 | App::CPAN::Fresh, Acme::Everything, Module::AutoINC and CPAN::AutoINC, 22 | but could be more. 23 | 24 | CPAN::Any provides one unified interface to install modules, and which 25 | client to use is now up to user's own configuration. 26 | 27 | METHODS 28 | install_module 29 | CPAN::Any->install_module($package [, ... ]); 30 | 31 | Install the module using its package name. Calling this method as a 32 | class method is equivalent to: 33 | 34 | my $client = CPAN::Any->auto; 35 | $client->install_module($package); 36 | 37 | PREFERENCE 38 | "CPAN::Any->install_module($module)" and friends will automatically 39 | detect which client to use, based on the following order. 40 | 41 | PERL_PREFER_CPAN_CLIENT 42 | Users can set the environment variable "PERL_PREFER_CPAN_CLIENT" to 43 | the acceptable client name. Acceptable values are "CPAN", "CPANP", 44 | "CPANPLUS", "cpanm" and "cpanminus". The values are case insensitive 45 | for convenience. 46 | 47 | CPAN::Any::Config 48 | When this module (CPAN::Any) is installed from CPAN, CPANPLUS or 49 | cpanm it automatically sets up the current installer you use as the 50 | preferred installer type in CPAN::Any::Config module and installs it 51 | in your site include path. 52 | 53 | You can reinstall modules using one of those installers to change 54 | the default preference. 55 | 56 | fallback to CPAN 57 | If none of the above is set, the default installer is CPAN. 58 | 59 | AUTHOR 60 | Tatsuhiko Miyagawa 61 | 62 | COPYRIGHT 63 | Copyright 2010- Tatsuhiko Miyagawa 64 | 65 | LICENSE 66 | This library is free software; you can redistribute it and/or modify it 67 | under the same terms as Perl itself. 68 | 69 | SEE ALSO 70 | CPAN, CPANPLUS, App::cpanminus 71 | 72 | -------------------------------------------------------------------------------- /lib/CPAN/Any.pm: -------------------------------------------------------------------------------- 1 | package CPAN::Any; 2 | 3 | use strict; 4 | use 5.008_001; 5 | our $VERSION = '0.01'; 6 | 7 | use Carp (); 8 | use UNIVERSAL::require; 9 | 10 | our $ClientNames = { 11 | cpan => 'CPAN::Any::CPAN', 12 | cpanp => 'CPAN::Any::CPANPLUS', 13 | cpanplus => 'CPAN::Any::CPANPLUS', 14 | cpanm => 'CPAN::Any::cpanminus', 15 | cpanminus => 'CPAN::Any::cpanminus', 16 | }; 17 | 18 | sub _preference { 19 | my $class = shift; 20 | 21 | if ($ENV{PERL_PREFER_CPAN_CLIENT}) { 22 | return $ENV{PERL_PREFER_CPAN_CLIENT}; 23 | } 24 | 25 | if (eval { require CPAN::Any::Config; 1 }) { 26 | return $CPAN::Any::Config::PreferredClient; 27 | } 28 | 29 | return; 30 | } 31 | 32 | sub auto { 33 | my $class = shift; 34 | 35 | my $type = $class->_preference || 'cpan'; 36 | $class->new($type); 37 | } 38 | 39 | sub new { 40 | my($class, $type) = @_; 41 | 42 | my $backend = $ClientNames->{lc($type)} 43 | or Carp::croak("Couldn't find the installer type '$type'"); 44 | 45 | $backend->require or Carp::croak("$backend: $@"); 46 | $backend->new; 47 | } 48 | 49 | sub install_module { shift->auto->install_module(@_) } 50 | 51 | 1; 52 | __END__ 53 | 54 | =encoding utf-8 55 | 56 | =for stopwords 57 | 58 | =head1 NAME 59 | 60 | CPAN::Any - Install Perl modules using any of CPAN clients 61 | 62 | =head1 SYNOPSIS 63 | 64 | use CPAN::Any; 65 | 66 | # install modules using the user's favorite installer 67 | CPAN::Any->install_module("Plack"); 68 | 69 | # explicitly specify which client to use 70 | my $cpan = CPAN::Any->new("cpanm"); 71 | $cpan->install_module("Catalyst"); 72 | 73 | =head1 DESCRIPTION 74 | 75 | CPAN::Any is an interface to install Perl modules using any CPAN client. 76 | 77 | =head1 WHY 78 | 79 | There are many tools and modules that use (one of) CPAN clients to 80 | install modules, and most of them hardcode the author's favorite CPAN 81 | clients, either L, L or L. Examples are 82 | L, L, L, 83 | L and L, but could be more. 84 | 85 | L provides one unified interface to install modules, and 86 | which client to use is now up to user's own configuration. 87 | 88 | =head1 METHODS 89 | 90 | =over 4 91 | 92 | =item install_module 93 | 94 | CPAN::Any->install_module($package [, ... ]); 95 | 96 | Install the module using its package name. Calling this method as a 97 | class method is equivalent to: 98 | 99 | my $client = CPAN::Any->auto; 100 | $client->install_module($package); 101 | 102 | =back 103 | 104 | =head1 PREFERENCE 105 | 106 | C<< CPAN::Any->install_module($module) >> and friends will 107 | automatically detect which client to use, based on the following order. 108 | 109 | =over 4 110 | 111 | =item PERL_PREFER_CPAN_CLIENT 112 | 113 | Users can set the environment variable C to 114 | the acceptable client name. Acceptable values are C, C, 115 | C, C and C. The values are case 116 | insensitive for convenience. 117 | 118 | =item CPAN::Any::Config 119 | 120 | When this module (L) is installed from L, L 121 | or L it automatically sets up the current installer you use as 122 | the preferred installer type in L module and 123 | installs it in your site include path. 124 | 125 | You can reinstall modules using one of those installers to change the 126 | default preference. 127 | 128 | =item fallback to CPAN 129 | 130 | If none of the above is set, the default installer is L. 131 | 132 | =back 133 | 134 | =head1 AUTHOR 135 | 136 | Tatsuhiko Miyagawa Emiyagawa@bulknews.netE 137 | 138 | =head1 COPYRIGHT 139 | 140 | Copyright 2010- Tatsuhiko Miyagawa 141 | 142 | =head1 LICENSE 143 | 144 | This library is free software; you can redistribute it and/or modify 145 | it under the same terms as Perl itself. 146 | 147 | =head1 SEE ALSO 148 | 149 | L, L, L 150 | 151 | =cut 152 | --------------------------------------------------------------------------------