# vim: ts=4 sts=4 sw=4:
use strict;
package CPAN;
-$CPAN::VERSION = '1.94_64';
+$CPAN::VERSION = '2.09';
$CPAN::VERSION =~ s/_//;
# we need to run chdir all over and we would get at wrong libraries
use CPAN::LWP::UserAgent;
use CPAN::Exception::RecursiveDependency;
use CPAN::Exception::yaml_not_installed;
+use CPAN::Exception::yaml_process_error;
use Carp ();
use Config ();
return +[] unless -s $local_file;
my $yaml_module = _yaml_module;
if ($CPAN::META->has_inst($yaml_module)) {
- # temporarly enable yaml code deserialisation
+ # temporarily enable yaml code deserialisation
no strict 'refs';
# 5.6.2 could not do the local() with the reference
# so we do it manually instead
# be politely squashed. Any bug that causes every eval {} to have to be
# modified should be not so politely squashed.
#
-# Those are my current opinions. It is also my optinion that polite
+# Those are my current opinions. It is also my opinion that polite
# arguments degenerate to personal arguments far too frequently, and that
# when they do, it's because both people wanted it to, or at least didn't
# sufficiently want it not to.
#-> sub CPAN::fastcwd ;
sub fastcwd {Cwd::fastcwd();}
+#-> sub CPAN::getdcwd ;
+sub getdcwd {Cwd::getdcwd();}
+
#-> sub CPAN::backtickcwd ;
sub backtickcwd {my $cwd = `cwd`; chomp $cwd; $cwd}
#
# these subroutines die if they believe the installed version is unusable;
#
+ 'CPAN::Meta' => [
+ sub {
+ require CPAN::Meta;
+ unless (CPAN::Version->vge(CPAN::Meta->VERSION, 2.110350)) {
+ for ("Will not use CPAN::Meta, need version 2.110350\n") {
+ $CPAN::Frontend->mywarn($_);
+ die $_;
+ }
+ }
+ },
+ ],
+
+ 'CPAN::Meta::Requirements' => [
+ sub {
+ require CPAN::Meta::Requirements;
+ unless (CPAN::Version->vge(CPAN::Meta::Requirements->VERSION, 2.120920)) {
+ for ("Will not use CPAN::Meta::Requirements, need version 2.120920\n") {
+ $CPAN::Frontend->mywarn($_);
+ die $_;
+ }
+ }
+ },
+ ],
LWP => [ # we frequently had "Can't locate object
# method "new" via package "LWP::UserAgent" at
# don't die, because we may need
# Archive::Tar to upgrade
}
-
+
}
},
],
return $HAS_USABLE->{$mod} = 1;
}
+sub frontend {
+ shift;
+ $CPAN::Frontend = shift if @_;
+ $CPAN::Frontend;
+}
+
+sub use_inst {
+ my ($self, $module) = @_;
+
+ unless ($self->has_inst($module)) {
+ $self->frontend->mydie("$module not installed, cannot continue");
+ }
+}
+
#-> sub CPAN::has_inst
sub has_inst {
my($self,$mod,$message) = @_;
my %dont = map { $_ => 1 } keys %{$CPAN::META->{dontload_hash}||{}},
keys %{$CPAN::Config->{dontload_hash}||{}},
@{$CPAN::Config->{dontload_list}||[]};
- if (defined $message && $message eq "no" # afair only used by Nox
+ if (defined $message && $message eq "no" # as far as I remember only used by Nox
||
$dont{$mod}
) {
if ($INC{$file}) {
# checking %INC is wrong, because $INC{LWP} may be true
# although $INC{"URI/URL.pm"} may have failed. But as
- # I really want to say "bla loaded OK", I have to somehow
+ # I really want to say "blah loaded OK", I have to somehow
# cache results.
### warn "$file in %INC"; #debug
return 1;
CPAN: Module::Signature security checks disabled because Module::Signature
not installed. Please consider installing the Module::Signature module.
You may also need to be able to connect over the Internet to the public
- keyservers like pool.sks-keyservers.net or pgp.mit.edu.
+ key servers like pool.sks-keyservers.net or pgp.mit.edu.
});
$CPAN::Frontend->mysleep(2);
sub _list_sorted_descending_is_tested {
my($self) = @_;
- sort
+ my $foul = 0;
+ my @sorted = sort
{ ($self->{is_tested}{$b}||0) <=> ($self->{is_tested}{$a}||0) }
- keys %{$self->{is_tested}}
+ grep
+ { if ($foul){ 0 } elsif (-e) { 1 } else { $foul = $_; 0 } }
+ keys %{$self->{is_tested}};
+ if ($foul) {
+ $CPAN::Frontend->mywarn("Lost build_dir detected ($foul), giving up all cached test results of currently running session.\n");
+ for my $dbd (keys %{$self->{is_tested}}) { # distro-build-dir
+ SEARCH: for my $d ($CPAN::META->all_objects("CPAN::Distribution")) {
+ if ($d->{build_dir} && $d->{build_dir} eq $dbd) {
+ $CPAN::Frontend->mywarn(sprintf "Flushing cache for %s\n", $d->pretty_id);
+ $d->fforce("");
+ last SEARCH;
+ }
+ }
+ delete $self->{is_tested}{$dbd};
+ }
+ return ();
+ } else {
+ return @sorted;
+ }
}
#-> sub CPAN::set_perl5lib
with slightly differing methods for displaying an object.
Arguments to these commands are either strings exactly matching
-the identification string of an object, or regular expressions
+the identification string of an object, or regular expressions
matched case-insensitively against various attributes of the
objects. The parser only recognizes a regular expression when you
enclose it with slashes.
The principle is that the number of objects found influences how an
item is displayed. If the search finds one item, the result is
-displayed with the rather verbose method C<as_string>, but if
+displayed with the rather verbose method C<as_string>, but if
more than one is found, each object is displayed with the terse method
C<as_glimpse>.
C<readme> displays the README file of the associated distribution.
C<Look> gets and untars (if not yet done) the distribution file,
changes to the appropriate directory and opens a subshell process in
-that directory. C<perldoc> displays the module's pod documentation
+that directory. C<perldoc> displays the module's pod documentation
in html or plain text format.
=item C<ls> author
=item C<ls> globbing_expression
The first form lists all distribution files in and below an author's
-CPAN directory as stored in the CHECKUMS files distributed on
+CPAN directory as stored in the CHECKSUMS files distributed on
CPAN. The listing recurses into subdirectories.
The second form limits or expands the output with shell
C<autobundle> writes a bundle file into the
C<$CPAN::Config-E<gt>{cpan_home}/Bundle> directory. The file contains
a list of all modules that are both available from CPAN and currently
-installed within @INC. The name of the bundle file is based on the
-current date and a counter.
+installed within @INC. Duplicates of each distribution are suppressed.
+The name of the bundle file is based on the current date and a
+counter, e.g. F<Bundle/Snapshot_2012_05_21_00.pm>. This is installed
+again by running C<cpan Bundle::Snapshot_2012_05_21_00>, or installing
+C<Bundle::Snapshot_2012_05_21_00> from the CPAN shell.
+
+Return value: path to the written file.
=head2 hosts
C<FTPstats.yml> in your C<cpan_home> directory. If no YAML module is
configured or YAML not installed, no stats are provided.
+=over
+
+=item install_tested
+
+Install all distributions that have been tested successfully but have
+not yet been installed. See also C<is_tested>.
+
+=item is_tested
+
+List all build directories of distributions that have been tested
+successfully but have not yet been installed. See also
+C<install_tested>.
+
+=back
+
=head2 mkmyconfig
mkmyconfig() writes your own CPAN::MyConfig file into your C<~/.cpan/>
directory so that you can save your own preferences instead of the
system-wide ones.
+=head2 r [Module|/Regexp/]...
+
+scans current perl installation for modules that have a newer version
+available on CPAN and provides a list of them. If called without
+argument, all potential upgrades are listed; if called with arguments
+the list is filtered to the modules and regexps given as arguments.
+
+The listing looks something like this:
+
+ Package namespace installed latest in CPAN file
+ CPAN 1.94_64 1.9600 ANDK/CPAN-1.9600.tar.gz
+ CPAN::Reporter 1.1801 1.1902 DAGOLDEN/CPAN-Reporter-1.1902.tar.gz
+ YAML 0.70 0.73 INGY/YAML-0.73.tar.gz
+ YAML::Syck 1.14 1.17 AVAR/YAML-Syck-1.17.tar.gz
+ YAML::Tiny 1.44 1.50 ADAMK/YAML-Tiny-1.50.tar.gz
+ CGI 3.43 3.55 MARKSTOS/CGI.pm-3.55.tar.gz
+ Module::Build::YAML 1.40 1.41 DAGOLDEN/Module-Build-0.3800.tar.gz
+ TAP::Parser::Result::YAML 3.22 3.23 ANDYA/Test-Harness-3.23.tar.gz
+ YAML::XS 0.34 0.35 INGY/YAML-LibYAML-0.35.tar.gz
+
+It suppresses duplicates in the column C<in CPAN file> such that
+distributions with many upgradeable modules are listed only once.
+
+Note that the list is not sorted.
+
=head2 recent ***EXPERIMENTAL COMMAND***
The C<recent> command downloads a list of recent uploads to CPAN and
-displays them I<slowly>. While the command is running, a $SIG{INT}
+displays them I<slowly>. While the command is running, a $SIG{INT}
exits the loop after displaying the current item.
B<Note>: This command requires XML::LibXML installed.
recompile() is a special command that takes no argument and
runs the make/test/install cycle with brute force over all installed
-dynamically loadable extensions (aka XS modules) with 'force' in
+dynamically loadable extensions (a.k.a. XS modules) with 'force' in
effect. The primary purpose of this command is to finish a network
installation. Imagine you have a common source tree for two different
architectures. You decide to do a completely independent fresh
B<Note>: See also L<recent>
-=head2 upgrade [Module|/Regex/]...
+=head2 upgrade [Module|/Regexp/]...
The C<upgrade> command first runs an C<r> command with the given
arguments and then installs the newest versions of all modules that
Modules know their associated Distribution objects. They always refer
to the most recent official release. Developers may mark their releases
-as unstable development versions (by inserting an underbar into the
+as unstable development versions (by inserting an underscore into the
module version number which will also be reflected in the distribution
name when you run 'make dist'), so the really hottest and newest
distribution is not always the default. If a module Foo circulates
pager or redirecting output into a file works somewhat as in a normal
shell, with the stipulation that you must type extra spaces.
+=head2 Plugin support ***EXPERIMENTAL***
+
+Plugins are objects that implement any of currently eight methods:
+
+ pre_get
+ post_get
+ pre_make
+ post_make
+ pre_test
+ post_test
+ pre_install
+ post_install
+
+The C<plugin_list> configuration parameter holds a list of strings of
+the form
+
+ Modulename=arg0,arg1,arg2,arg3,...
+
+At run time, each listed plugin is instantiated as a singleton object
+by running the equivalent of this pseudo code:
+
+ my $plugin = <string representation from config>;
+ <generate Modulename and arguments from $plugin>;
+ my $p = $instance{$plugin} ||= Modulename->new($arg0,$arg1,...);
+
+The generated singletons are kept around from instantiation until the
+end of the shell session. <plugin_list> can be reconfigured at any
+time at run time. While the cpan shell is running, it checks all
+activated plugins at each of the 8 reference points listed above and
+runs the respective method if it is implemented for that object. The
+method is called with the active CPAN::Distribution object passed in
+as an argument.
+
=head1 CONFIGURATION
When the CPAN module is used for the first time, a configuration
o conf shell
If KEY starts and ends with a slash, the string in between is
-treated as a regular expression and only keys matching this regex
+treated as a regular expression and only keys matching this regexp
are displayed
Example:
dontload_list arrayref: modules in the list will not be
loaded by the CPAN::has_inst() routine
ftp path to external prg
- ftp_passive if set, the envariable FTP_PASSIVE is set for downloads
+ ftp_passive if set, the environment variable FTP_PASSIVE is set
+ for downloads
ftp_proxy proxy host for ftp requests
ftpstats_period max number of days to keep download statistics
ftpstats_size max number of items to keep in the download statistics
inactivity_timeout breaks interactive Makefile.PLs or Build.PLs
after this many seconds inactivity. Set to 0 to
disable timeouts.
- index_expire refetch index files after this many days
+ index_expire refetch index files after this many days
inhibit_startup_message
if true, suppress the startup message
keep_source_where directory in which to keep the source (if we do)
patch path to external prg
patches_dir local directory containing patch files
perl5lib_verbosity verbosity level for PERL5LIB additions
+ plugin_list list of active hooks (see Plugin support above
+ and the CPAN::Plugin module)
prefer_external_tar
per default all untar operations are done with
Archive::Tar; by setting this variable to true
proxy_user username for accessing an authenticating proxy
proxy_pass password for accessing an authenticating proxy
randomize_urllist add some randomness to the sequence of the urllist
+ recommends_policy whether recommended prerequisites should be included
scan_cache controls scanning of cache ('atstart', 'atexit' or 'never')
shell your favorite shell
show_unparsable_versions
boolean if r command tells which modules are versionless
show_upload_date boolean if commands should try to determine upload date
show_zero_versions boolean if r command tells for which modules $version==0
+ suggests_policy whether suggested prerequisites should be included
tar location of external program tar
tar_verbosity verbosity level for the tar command
term_is_latin deprecated: if true Unicode is translated to ISO-8859-1
CPAN::Reporter history)
unzip location of external program unzip
urllist arrayref to nearby CPAN sites (or equivalent locations)
+ use_prompt_default set PERL_MM_USE_DEFAULT for configure/make/test/install
use_sqlite use CPAN::SQLite for metadata storage (fast and lean)
username your username if you CPAN server wants one
version_timeout stops version parsing after this many seconds.
Calls Cwd::fastcwd
+=item getdcwd
+
+Calls Cwd::getdcwd
+
=item backtickcwd
Calls the external command cwd.
Since CPAN.pm version 1.88_51 modules declared as C<build_requires> by
a distribution are treated differently depending on the config
variable C<build_requires_install_policy>. By setting
-C<build_requires_install_policy> to C<no>, such a module is not
+C<build_requires_install_policy> to C<no>, such a module is not
installed. It is only built and tested, and then kept in the list of
tested but uninstalled modules. As such, it is available during the
build of the dependent module by integrating the path to the
=head2 Configuration for individual distributions (I<Distroprefs>)
-(B<Note:> This feature has been introduced in CPAN.pm 1.8854 and is
-still considered beta quality)
+(B<Note:> This feature has been introduced in CPAN.pm 1.8854)
Distributions on CPAN usually behave according to what we call the
CPAN mantra. Or since the advent of Module::Build we should talk about
=item
-specify dependencies the original maintainer forgot
+specify dependencies the original maintainer forgot
=item
=item match [hash]
-A hashref with one or more of the keys C<distribution>, C<modules>,
+A hashref with one or more of the keys C<distribution>, C<module>,
C<perl>, C<perlconfig>, and C<env> that specify whether a document is
targeted at a specific CPAN distribution or installation.
Keys prefixed with C<not_> negates the corresponding match.
beforehand. The path to each patch is either an absolute path on the
local filesystem or relative to a patch directory specified in the
C<patches_dir> configuration variable or in the format of a canonical
-distroname. For examples please consult the distroprefs/ directory in
+distro name. For examples please consult the distroprefs/ directory in
the CPAN.pm distribution (these examples are not installed by
default).
=head1 PROGRAMMER'S INTERFACE
-If you do not enter the shell, shell commands are
+If you do not enter the shell, shell commands are
available both as methods (C<CPAN::Shell-E<gt>install(...)>) and as
functions in the calling package (C<install(...)>). Before calling low-level
commands, it makes sense to initialize components of CPAN you need, e.g.:
There's currently only one class that has a stable interface -
CPAN::Shell. All commands that are available in the CPAN shell are
-methods of the class CPAN::Shell. Each of the commands that produce
-listings of modules (C<r>, C<autobundle>, C<u>) also return a list of
-the IDs of all modules within the list.
+methods of the class CPAN::Shell. The arguments on the commandline are
+passed as arguments to the method.
+
+So if you take for example the shell command
+
+ notest install A B C
+
+the actually executed command is
+
+ CPAN::Shell->notest("install","A","B","C");
+
+Each of the commands that produce listings of modules (C<r>,
+C<autobundle>, C<u>) also return a list of the IDs of all modules
+within the list.
=over 2
If you don't want any output should all modules be
up to date, parse the output of above command for the regular
expression C</modules are up to date/> and decide to mail the output
-only if it doesn't match.
+only if it doesn't match.
If you prefer to do it more in a programmerish style in one single
process, something like this may better suit you:
=item CPAN::Bundle::uptodate()
-Returns 1 if the bundle itself and all its members are uptodate.
+Returns 1 if the bundle itself and all its members are up-to-date.
=item CPAN::Bundle::install()
you.
This install method only has the power to install the distribution if
-there are no dependencies in the way. To install an object along with all
+there are no dependencies in the way. To install an object along with all
its dependencies, use CPAN::Shell->install.
Note that install() gives no meaningful return value. See uptodate().
-=item CPAN::Distribution::install_tested()
-
-Install all distributions that have tested sucessfully but
-not yet installed. See also C<is_tested>.
-
=item CPAN::Distribution::isa_perl()
Returns 1 if this distribution file seems to be a perl distribution.
Returns the hash reference from the first matching YAML file that the
user has deposited in the C<prefs_dir/> directory. The first
succeeding match wins. The files in the C<prefs_dir/> are processed
-alphabetically, and the canonical distroname (e.g.
+alphabetically, and the canonical distro name (e.g.
AUTHOR/Foo-Bar-3.14.tar.gz) is matched against the regular expressions
stored in the $root->{match}{distribution} attribute value.
Additionally all module names contained in a distribution are matched
=item CPAN::Distribution::uptodate()
Returns 1 if all the modules contained in the distribution are
-uptodate. Relies on containsmods.
+up-to-date. Relies on containsmods.
=item CPAN::Index::force_reload()
Returns a one-line description of the module in four columns: The
first column contains the word C<Module>, the second column consists
of one character: an equals sign if this module is already installed
-and uptodate, a less-than sign if this module is installed but can be
+and up-to-date, a less-than sign if this module is installed but can be
upgraded, and a space if the module is not installed. The third column
is the name of the module and the fourth column gives maintainer or
distribution information.
d - Developer
u - Usenet newsgroup comp.lang.perl.modules
n - None known, try comp.lang.perl.modules
- a - abandoned; volunteers welcome to take over maintainance
+ a - abandoned; volunteers welcome to take over maintenance
L - Language Used:
p - Perl-only, no compiler needed, should be platform independent
b - BSD: The BSD License
a - Artistic license alone
2 - Artistic license 2.0 or later
- o - open source: appoved by www.opensource.org
+ o - open source: approved by www.opensource.org
d - allows distribution without restrictions
- r - restricted distribtion
+ r - restricted distribution
n - no license at all
=item CPAN::Module::force($method,@args)
Module_Name [Version_String] [- optional text]
The only required part is the first field, the name of a module
-(e.g. Foo::Bar, ie. I<not> the name of the distribution file). The rest
+(e.g. Foo::Bar, i.e. I<not> the name of the distribution file). The rest
of the line is optional. The comment part is delimited by a dash just
as in the man page header.
=head1 PREREQUISITES
The CPAN program is trying to depend on as little as possible so the
-user can use it in hostile enviroment. It works better the more goodies
+user can use it in hostile environment. It works better the more goodies
the environment provides. For example if you try in the CPAN shell
install Bundle::CPAN
packaging, configuration, synchronicity, and even (gasp!) due to bugs
within the CPAN.pm module itself.
-For debugging the code of CPAN.pm itself in interactive mode, some
+For debugging the code of CPAN.pm itself in interactive mode, some
debugging aid can be turned on for most packages within
CPAN.pm with one of
See the source for details.
+=item use_inst($module)
+
+Similary to L<has_inst()> tries to load optional library but also dies if
+library is not available
+
=item has_usable($module)
Returns true if the module is installed and in a usable state. Only
distributions, authors, and bundles. If the object already exists, this
method returns the object; otherwise, it calls the constructor.
+=item frontend()
+
+=item frontend($new_frontend)
+
+Getter/setter for frontend object. Method just allows to subclass CPAN.pm.
+
=back
=head1 SECURITY
command-line F<gpg> tool installed.
You will also need to be able to connect over the Internet to the public
-keyservers, like pgp.mit.edu, and their port 11731 (the HKP protocol).
+key servers, like pgp.mit.edu, and their port 11731 (the HKP protocol).
The configuration parameter check_sigs is there to turn signature
checking on or off.
things: dependencies and interactivity. CPAN.pm sometimes fails on
calculating dependencies because not all modules define all MakeMaker
attributes correctly, so a bundle definition file should specify
-prerequisites as early as possible. On the other hand, it's
+prerequisites as early as possible. On the other hand, it's
annoying that so many distributions need some interactive configuring. So
what you can try to accomplish in your private bundle file is to have the
packages that need to be configured early in the file and the gentle
-ones later, so you can go out for cofeee after a few minutes and leave CPAN.pm
-to churn away untended.
+ones later, so you can go out for coffee after a few minutes and leave CPAN.pm
+to churn away unattended.
=head1 WORKING WITH CPAN.pm BEHIND FIREWALLS
=item One-way visibility
-One-way visibility means these firewalls try to make themselves
+One-way visibility means these firewalls try to make themselves
invisible to users inside the firewall. An FTP data connection is
normally created by sending your IP address to the remote server and then
listening for the return connection. But the remote server will not be able to
cpan> o conf term_is_latin 1
-If other charset support is needed, please file a bugreport against
+If other charset support is needed, please file a bug report against
CPAN.pm at rt.cpan.org and describe your needs. Maybe we can extend
the support or maybe UTF-8 terminals become widely available.
urllist' and allow CPAN to automatically select mirrors for you.
Beyond that help, the urllist config parameter is yours. You can add and remove
-sites at will. You should find out which sites have the best uptodateness,
+sites at will. You should find out which sites have the best up-to-dateness,
bandwidth, reliability, etc. and are topologically close to you. Some people
-prefer fast downloads, others uptodateness, others reliability. You decide
+prefer fast downloads, others up-to-dateness, others reliability. You decide
which to try in which order.
Henk P. Penning maintains a site that collects data about CPAN sites:
- http://www.cs.uu.nl/people/henkp/mirmon/cpan.html
+ http://mirrors.cpan.org/
Also, feel free to play with experimental features. Run
You have the choice to set the config variable C<scan_cache> to
C<never>. Then you must clean it up yourself. The other possible
values, C<atstart> and C<atexit> clean up the build directory when you
-start or exit the CPAN shell, respectively. If you never start up the
-CPAN shell, you probably also have to clean up the build directory
+start (or more precisely, after the first extraction into the build
+directory) or exit the CPAN shell, respectively. If you never start up
+the CPAN shell, you probably also have to clean up the build directory
yourself.
=back
=head2 OLD PERL VERSIONS
-CPAN.pm is regularly tested to run under 5.004, 5.005, and assorted
+CPAN.pm is regularly tested to run under 5.005 and assorted
newer versions. It is getting more and more difficult to get the
minimal prerequisites working on older perls. It is close to
impossible to get the whole Bundle::CPAN working there. If you're in
work for you as well. Above that the utility provides several
commandline shortcuts.
+melezhik (Alexey) sent me a link where he published a chef recipe to
+work with CPAN.pm: http://community.opscode.com/cookbooks/cpan.
+
+
=cut