# -*- Mode: cperl; coding: utf-8; cperl-indent-level: 4 -*-
use strict;
package CPAN;
-$CPAN::VERSION = '1.88_53';
+$CPAN::VERSION = '1.88_54';
$CPAN::VERSION = eval $CPAN::VERSION;
use CPAN::HandleConfig;
}
}
+# CPAN::_yaml_loadfile
+sub _yaml_loadfile {
+ my($self,$local_file) = @_;
+ my $yaml_module = $CPAN::Config->{yaml_module} || "YAML";
+ if ($CPAN::META->has_inst($yaml_module)) {
+ my $code = UNIVERSAL::can($yaml_module, "LoadFile");
+ my $yaml;
+ eval { $yaml = $code->($local_file); };
+ if ($@) {
+ $CPAN::Frontend->mydie("Alert: While trying to parse YAML file\n".
+ " $local_file\n".
+ "with $yaml_module the following error was encountered:\n".
+ " $@\n"
+ );
+ }
+ return $yaml;
+ } else {
+ $CPAN::Frontend->mywarn("'$yaml_module' not installed, cannot parse '$local_file'\n");
+ }
+ return +{};
+}
+
package CPAN::CacheMgr;
use strict;
@CPAN::CacheMgr::ISA = qw(CPAN::InfoObj CPAN);
}
for my $obj (@qcopy) {
$obj->color_cmd_tmps(0,0);
- delete $obj->{incommandcolor};
}
}
local($_);
push @lines, split /\012/ while <FH>;
my $i = 0;
- my $modulus = int(@lines/75) || 1;
+ my $modulus = int($#lines/75) || 1;
+ CPAN->debug(sprintf "modulus[%d]lines[%s]", $modulus, scalar @lines) if $CPAN::DEBUG;
foreach (@lines) {
my($userid,$fullname,$email) =
m/alias\s+(\S+)\s+\"([^\"\<]+)\s+\<([^\>]+)\>\"/;
CPAN->debug("secondtime[$secondtime]") if $CPAN::DEBUG;
my(%exists);
my $i = 0;
- my $modulus = int(@lines/75) || 1;
+ my $modulus = int($#lines/75) || 1;
foreach (@lines) {
# before 1.56 we split into 3 and discarded the rest. From
# 1.57 we assign remaining text to $comment thus allowing to
Carp::confess($@) if $@;
return if $CPAN::Signal;
my $i = 0;
- my $until = keys %$ret;
+ my $until = keys(%$ret) - 1;
my $modulus = int($until/75) || 1;
CPAN->debug(sprintf "until[%d]", $until) if $CPAN::DEBUG;
for (keys %$ret) {
$local_wanted)) {
$CPAN::Frontend->mydie("Giving up on downloading yaml file '$local_wanted'\n");
}
- if ($CPAN::META->has_inst("YAML")) {
- my $yaml = YAML::LoadFile($local_file);
- return $yaml;
- } else {
- $CPAN::Frontend->mydie("Yaml not installed, cannot parse '$local_file'\n");
- }
+ my $yaml = CPAN->_yaml_loadfile($local_file);
}
#-> sub CPAN::Distribution::pretty_id
# $switch = "-MExtUtils::MakeMaker ".
# "-Mops=:default,:filesys_read,:filesys_open,require,chdir"
# if $] > 5.00310;
+ my $makepl_arg = $self->make_x_arg("pl");
$system = sprintf("%s%s Makefile.PL%s",
$perl,
$switch ? " $switch" : "",
- $CPAN::Config->{makepl_arg} ? " $CPAN::Config->{makepl_arg}" : "",
+ $makepl_arg ? " $makepl_arg" : "",
);
}
- unless (exists $self->{writemakefile}) {
+ local %ENV = %ENV;
+ if (my $env = $self->prefs->{pl}{env}) {
+ for my $e (keys %$env) {
+ $ENV{$e} = $env->{$e};
+ }
+ }
+ if (exists $self->{writemakefile}) {
+ } else {
local($SIG{ALRM}) = sub { die "inactivity_timeout reached\n" };
my($ret,$pid);
$@ = "";
return;
}
} else {
- $ret = system($system);
- if ($ret != 0) {
- $self->{writemakefile} = CPAN::Distrostatus
- ->new("NO '$system' returned status $ret");
- $CPAN::Frontend->mywarn("Warning: No success on command[$system]\n");
- return;
- }
+ if (my $expect = $self->prefs->{pl}{expect}) {
+ $ret = $self->run_via_expect($system,$expect);
+ } else {
+ $ret = system($system);
+ }
+ if ($ret != 0) {
+ $self->{writemakefile} = CPAN::Distrostatus
+ ->new("NO '$system' returned status $ret");
+ $CPAN::Frontend->mywarn("Warning: No success on command[$system]\n");
+ return;
+ }
}
if (-f "Makefile" || -f "Build") {
$self->{writemakefile} = CPAN::Distrostatus->new("YES");
return 1 if $self->follow_prereqs(@prereq); # signal success to the queuerunner
}
}
+ if ($CPAN::Signal){
+ delete $self->{force_update};
+ return;
+ }
if ($self->{modulebuild}) {
unless (-f "Build") {
my $cwd = Cwd::cwd;
} else {
$system = join " ", $self->_make_command(), $CPAN::Config->{make_arg};
}
+ my $make_arg = $self->make_x_arg("make");
+ $system = sprintf("%s%s",
+ $system,
+ $make_arg ? " $make_arg" : "",
+ );
+ if (my $env = $self->prefs->{make}{env}) { # overriding the local
+ # ENV of PL, not the
+ # outer ENV, but
+ # unlikely to be a risk
+ for my $e (keys %$env) {
+ $ENV{$e} = $env->{$e};
+ }
+ }
if (system($system) == 0) {
$CPAN::Frontend->myprint(" $system -- OK\n");
$self->{make} = CPAN::Distrostatus->new("YES");
}
}
+# CPAN::Distribution::run_via_expect
+sub run_via_expect {
+ my($self,$system,$expect) = @_;
+ CPAN->debug("system[$system]expect[$expect]") if $CPAN::DEBUG;
+ if ($CPAN::META->has_inst("Expect")) {
+ my $expo = Expect->new;
+ $expo->spawn($system);
+ EXPECT: for (my $i = 0; $i < $#$expect; $i+=2) {
+ my $regex = eval "qr{$expect->[$i]}";
+ my $send = $expect->[$i+1];
+ $expo->expect(10,
+ [ eof => sub {
+ my $but = $expo->clear_accum;
+ $CPAN::Frontend->mywarn("EOF (maybe harmless) system[$system]
+expected[$regex]\nbut[$but]\n\n");
+ last EXPECT;
+ } ],
+ [ timeout => sub {
+ my $but = $expo->clear_accum;
+ $CPAN::Frontend->mydie("TIMEOUT system[$system]
+expected[$regex]\nbut[$but]\n\n");
+ } ],
+ -re => $regex);
+ $expo->send($send);
+ }
+ $expo->soft_close;
+ return $expo->exitstatus();
+ } else {
+ $CPAN::Frontend->mywarn("Expect not installed, falling back to system()\n");
+ return system($system);
+ }
+}
+
+# CPAN::Distribution::_find_prefs
+sub _find_prefs {
+ my($self,$distro) = @_;
+ my $distroid = $distro->pretty_id;
+ CPAN->debug("distroid[$distroid]") if $CPAN::DEBUG;
+ my $prefs_dir = $CPAN::Config->{prefs_dir};
+ eval { File::Path::mkpath($prefs_dir); };
+ if ($@) {
+ $CPAN::Frontend->mydie("Cannot create directory $prefs_dir");
+ }
+ my $yaml_module = $CPAN::Config->{yaml_module} || "YAML";
+ if ($CPAN::META->has_inst($yaml_module)) {
+ my $dh = DirHandle->new($prefs_dir)
+ or die Carp::croak("Couldn't open '$prefs_dir': $!");
+ DIRENT: for (sort $dh->read) {
+ next if $_ eq "." || $_ eq "..";
+ next unless /\.yml$/;
+ my $abs = File::Spec->catfile($prefs_dir, $_);
+ CPAN->debug("abs[$abs]") if $CPAN::DEBUG;
+ if (-f $abs) {
+ my $yaml = CPAN->_yaml_loadfile($abs);
+ my $ok = 1;
+ my $match = $yaml->{match} or
+ $CPAN::Frontend->mydie("Nonconforming YAML file '$abs': ".
+ "missing attribut 'match'. Please ".
+ "remove, cannot continue.");
+ for my $sub_attribute (keys %$match) {
+ my $qr = eval "qr{$yaml->{match}{$sub_attribute}}";
+ if ($sub_attribute eq "module") {
+ my $okm = 0;
+ my @modules = $distro->containsmods;
+ for my $module (@modules) {
+ $okm ||= $module =~ /$qr/;
+ last if $okm;
+ }
+ $ok &&= $okm;
+ } elsif ($sub_attribute eq "distribution") {
+ my $okd = $distroid =~ /$qr/;
+ $ok &&= $okd;
+ } else {
+ $CPAN::Frontend->mydie("Nonconforming YAML file '$abs': ".
+ "unknown sub_attribut '$sub_attribute'. ".
+ "Please ".
+ "remove, cannot continue.");
+ }
+ }
+ if ($ok) {
+ return {
+ prefs => $yaml,
+ prefs_file => $abs,
+ };
+ }
+ }
+ }
+ } else {
+ $CPAN::Frontend->mywarn("'$yaml_module' not installed, cannot read prefs '$prefs_dir'\n");
+ }
+ return;
+}
+
+# CPAN::Distribution::prefs
+sub prefs {
+ my($self) = @_;
+ if (exists $self->{prefs}) {
+ return $self->{prefs}; # XXX comment out during debugging
+ }
+ if ($CPAN::Config->{prefs_dir}) {
+ CPAN->debug("prefs_dir[$CPAN::Config->{prefs_dir}]") if $CPAN::DEBUG;
+ my $prefs = $self->_find_prefs($self);
+ if ($prefs) {
+ for my $x (qw(prefs prefs_file)) {
+ $self->{$x} = $prefs->{$x};
+ }
+ my $basename = File::Basename::basename($self->{prefs_file});
+ my $filler1 = "_" x 22;
+ my $filler2 = int(66 - length($basename))/2;
+ $filler2 = 0 if $filler2 < 0;
+ $filler2 = " " x $filler2;
+ $CPAN::Frontend->myprint("
+$filler1 D i s t r o P r e f s $filler1
+$filler2 $basename $filler2
+");
+ $CPAN::Frontend->mysleep(1);
+ return $self->{prefs};
+ }
+ }
+ return +{};
+}
+
+# CPAN::Distribution::make_x_arg
+sub make_x_arg {
+ my($self, $whixh) = @_;
+ my $make_x_arg;
+ my $prefs = $self->prefs;
+ if (
+ $prefs
+ && exists $prefs->{$whixh}
+ && exists $prefs->{$whixh}{args}
+ && $prefs->{$whixh}{args}
+ ) {
+ $make_x_arg = join(" ",
+ map {CPAN::HandleConfig
+ ->safe_quote($_)} @{$prefs->{$whixh}{args}},
+ );
+ }
+ my $what = sprintf "make%s_arg", $whixh eq "make" ? "" : $whixh;
+ $make_x_arg ||= $CPAN::Config->{$what};
+ return $make_x_arg;
+}
+
+# CPAN::Distribution::_make_command
sub _make_command {
my ($self) = @_;
if ($self) {
return
- CPAN::HandleConfig
+ CPAN::HandleConfig
->safe_quote(
- $CPAN::Config->{make} || $Config::Config{make} || 'make'
+ $self->prefs->{cpanconfig}{make}
+ || $CPAN::Config->{make}
+ || $Config::Config{make}
+ || 'make'
);
} else {
# Old style call, without object. Deprecated
Carp::confess("CPAN::_make_command() used as function. Don't Do That.");
return
- safe_quote(undef, $CPAN::Config->{make} || $Config::Config{make} || 'make');
+ safe_quote(undef,
+ $self->prefs->{cpanconfig}{make}
+ || $CPAN::Config->{make}
+ || $Config::Config{make}
+ || 'make');
}
}
my $yaml = File::Spec->catfile($build_dir,"META.yml");
$self->debug("yaml[$yaml]") if $CPAN::DEBUG;
return unless -f $yaml;
- if ($CPAN::META->has_inst("YAML")) {
- eval { $self->{yaml_content} = YAML::LoadFile($yaml); };
- if ($@) {
- $CPAN::Frontend->mywarn("Error while parsing META.yml: $@");
- return;
- }
- if (not exists $self->{yaml_content}{dynamic_config}
- or $self->{yaml_content}{dynamic_config}
- ) {
- $self->{yaml_content} = undef;
- }
+ eval { $self->{yaml_content} = CPAN->_yaml_loadfile($yaml); };
+ if ($@) {
+ return; # if we die, then we cannot read our own META.yml
+ }
+ if (not exists $self->{yaml_content}{dynamic_config}
+ or $self->{yaml_content}{dynamic_config}
+ ) {
+ $self->{yaml_content} = undef;
}
$self->debug(sprintf "yaml_content[%s]", $self->{yaml_content} || "UNDEF")
if $CPAN::DEBUG;
} else {
$system = join " ", $self->_make_command(), "test";
}
- my $tests_ok;
- if ( $CPAN::Config->{test_report} &&
- $CPAN::META->has_inst("CPAN::Reporter") ) {
+ my($tests_ok);
+ local %ENV = %ENV;
+ if (my $env = $self->prefs->{test}{env}) {
+ for my $e (keys %$env) {
+ $ENV{$e} = $env->{$e};
+ }
+ }
+ my $expect = $self->prefs->{test}{expect};
+ if ($expect && @$expect) {
+ $tests_ok = $self->run_via_expect($system,$expect) == 0;
+ } elsif ( $CPAN::Config->{test_report} &&
+ $CPAN::META->has_inst("CPAN::Reporter") ) {
$tests_ok = CPAN::Reporter::test($self, $system);
} else {
$tests_ok = system($system) == 0;
my @prereq;
for my $m (keys %{$self->{sponsored_mods}}) {
my $m_obj = CPAN::Shell->expand("Module",$m);
- if (!$m_obj->distribution->{make_test}
- ||
- $m_obj->distribution->{make_test}->failed){
- #$m_obj->dump;
- push @prereq, $m;
+ my $d_obj = $m_obj->distribution;
+ if ($d_obj) {
+ if (!$d_obj->{make_test}
+ ||
+ $d_obj->{make_test}->failed){
+ #$m_obj->dump;
+ push @prereq, $m;
+ }
}
}
if (@prereq){
$CPAN::Config->{mbuild_install_arg},
);
} else {
- my($make_install_make_command) = $CPAN::Config->{make_install_make_command} ||
- $self->_make_command();
+ my($make_install_make_command) =
+ $self->prefs->{cpanconfig}{make_install_make_command}
+ || $CPAN::Config->{make_install_make_command}
+ || $self->_make_command();
$system = sprintf("%s install %s",
$make_install_make_command,
$CPAN::Config->{make_install_arg},
}
my($stderr) = $^O eq "MSWin32" ? "" : " 2>&1 ";
- $CPAN::Config->{build_requires_install_policy}||="ask/yes";
+ my $brip = $self->prefs->{cpanconfig}{build_requires_install_policy};
+ $brip ||= $CPAN::Config->{build_requires_install_policy};
+ $brip ||="ask/yes";
my $id = $self->id;
my $reqtype = $self->{reqtype} ||= "c"; # in doubt it was a command
my $want_install = "yes";
if ($reqtype eq "b") {
- if ($CPAN::Config->{build_requires_install_policy} eq "no") {
+ if ($brip eq "no") {
$want_install = "no";
- } elsif ($CPAN::Config->{build_requires_install_policy} =~ m|^ask/(.+)|) {
+ } elsif ($brip =~ m|^ask/(.+)|) {
my $default = $1;
$default = "yes" unless $default =~ /^(y|n)/i;
$want_install =
} else {
$self->{install} = CPAN::Distrostatus->new("NO");
$CPAN::Frontend->mywarn(" $system -- NOT OK\n");
+ my $mimc =
+ $self->prefs->{cpanconfig}{make_install_make_command} ||
+ $CPAN::Config->{make_install_make_command};
if (
$makeout =~ /permission/s
&& $> > 0
&& (
- ! $CPAN::Config->{make_install_make_command}
- || $CPAN::Config->{make_install_make_command} eq $CPAN::Config->{make}
+ ! $mimc
+ || $mimc eq ($self->prefs->{cpanconfig}{make}
+ || $CPAN::Config->{make})
)
) {
$CPAN::Frontend->myprint(
use CPAN;
- # modules:
+ # Modules:
+
+ cpan> install Acme::Meta # in the shell
+
+ CPAN::Shell->install("Acme::Meta"); # in perl
+
+ # Distributions:
+
+ cpan> install NWCLARK/Acme-Meta-0.02.tar.gz # in the shell
+
+ CPAN::Shell->
+ install("NWCLARK/Acme-Meta-0.02.tar.gz"); # in perl
+
+ # module objects:
- $mod = "Acme::Meta";
- install $mod;
- CPAN::Shell->install($mod); # same thing
- CPAN::Shell->expandany($mod)->install; # same thing
- CPAN::Shell->expand("Module",$mod)->install; # same thing
- CPAN::Shell->expand("Module",$mod)
- ->distribution->install; # same thing
+ $mo = CPAN::Shell->expandany($mod);
+ $mo = CPAN::Shell->expand("Module",$mod); # same thing
- # distributions:
+ # distribution objects:
- $distro = "NWCLARK/Acme-Meta-0.01.tar.gz";
- install $distro; # same thing
- CPAN::Shell->install($distro); # same thing
- CPAN::Shell->expandany($distro)->install; # same thing
- CPAN::Shell->expand("Distribution",$distro)->install; # same thing
+ $do = CPAN::Shell->expand("Module",$mod)->distribution;
+ $do = CPAN::Shell->expandany($distro); # same thing
+ $do = CPAN::Shell->expand("Distribution",
+ $distro); # same thing
=head1 STATUS
# install my favorite programs if necessary:
for $mod (qw(Net::FTP Digest::SHA Data::Dumper)){
- my $obj = CPAN::Shell->expand('Module',$mod);
- $obj->install;
+ CPAN::Shell->install($mod);
}
# list all modules on my disk that have no VERSION number
cancellation can be avoided by letting C<force> run the C<install> for
you.
+This install method has only the power to install the distribution if
+there are no dependencies in the way. To install an object and all of
+its dependencies, use CPAN::Shell->install.
+
Note that install() gives no meaningful return value. See uptodate().
=item CPAN::Distribution::isa_perl()
command html2text and runs it through the pager specified
in C<$CPAN::Config->{pager}>
+=item CPAN::Distribution::prefs()
+
+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.
+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
+agains the regular expressions in the $root->{match}{module} attribute
+value. The two match values are ANDed together. Each of the two
+attributes are optional.
+
=item CPAN::Distribution::prereq_pm()
Returns the hash reference that has been announced by a distribution
prerequisites_policy
what to do if you are missing module prerequisites
('follow' automatically, 'ask' me, or 'ignore')
+ prefs_dir local directory to store per-distro build options
proxy_user username for accessing an authenticating proxy
proxy_pass password for accessing an authenticating proxy
scan_cache controls scanning of cache ('atstart' or 'never')
username your username if you CPAN server wants one
wait_list arrayref to a wait server to try (See CPAN::WAIT)
wget path to external prg
+ yaml_module which module to use to read/write YAML files
You can set and query each of these options interactively in the cpan
shell with the command set defined within the C<o conf> command:
a site for the next transfer, it must be explicitly removed from
urllist.
+=head2 prefs_dir for avoiding interactive questions (ALPHA)
+
+(B<Note:> This feature has been introduced in CPAN.pm 1.8854 and is
+still considered experimental and may still be changed)
+
+The files in the directory specified in C<prefs_dir> are YAML files
+that specify how CPAN.pm shall treat distributions that deviate from
+the normal non-interactive model of building and installing CPAN
+modules.
+
+Some modules try to get some data from the user interactively thus
+disturbing the installation of large bundles like Phalanx100 or
+modules like Plagger.
+
+CPAN.pm can use YAML files to either pass additional arguments to one
+of the four commands, set environment variables or instantiate an
+Expect object that reads from the console, waits for some regular
+expression and enters some answer. Needless to say that for the latter
+option Expect.pm needs to be installed.
+
+CPAN.pm comes with a couple of such YAML files. The structure is
+currently not documented. Please see the distroprefs directory of the
+CPAN distribution for examples and follow the README in there.
+
+Please note that setting the environment variable PERL_MM_USE_DEFAULT
+to a true value can also get you a long way if you want to always pick
+the default answers. But this only works if the author of apackage
+used the prompt function provided by ExtUtils::MakeMaker and if the
+defaults are OK for you.
+
=head1 SECURITY
There's no strong security layer in CPAN.pm. CPAN.pm helps you to
use File::Path ();
use File::Spec;
use vars qw($VERSION $urllist);
-$VERSION = sprintf "%.6f", substr(q$Rev: 924 $,4)/1000000 + 5.4;
+$VERSION = sprintf "%.6f", substr(q$Rev: 1012 $,4)/1000000 + 5.4;
=head1 NAME
}
}
- if (!$matcher or 'cpan_home keep_source_where build_dir' =~ /$matcher/){
+ if (!$matcher or 'cpan_home keep_source_where build_dir prefs_dir' =~ /$matcher/){
$CPAN::Frontend->myprint($prompts{config_intro});
if (!$matcher or 'cpan_home' =~ /$matcher/) {
}
$default = $cpan_home;
+ my $loop = 0;
while ($ans = prompt("CPAN build and cache directory?",$default)) {
unless (File::Spec->file_name_is_absolute($ans)) {
require Cwd;
} else {
$CPAN::Frontend->mywarn("Couldn't find directory $ans\n".
"or directory is not writable. Please retry.\n");
+ if (++$loop > 5) {
+ $CPAN::Frontend->mydie("Giving up");
+ }
}
}
$CPAN::Config->{cpan_home} = $ans;
$matcher
);
}
+
+ if (!$matcher or 'prefs_dir' =~ /$matcher/) {
+ my_dflt_prompt("prefs_dir",
+ File::Spec->catdir($CPAN::Config->{cpan_home},"prefs"),
+ $matcher
+ );
+ }
}
#
#
if (!$matcher or 'build_cache' =~ /$matcher/){
- $CPAN::Frontend->myprint($prompts{build_cache_intro});
-
# large enough to build large dists like Tk
my_dflt_prompt(build_cache => 100, $matcher);
}
if (!$matcher or 'index_expire' =~ /$matcher/) {
- $CPAN::Frontend->myprint($prompts{index_expire_intro});
-
my_dflt_prompt(index_expire => 1, $matcher);
}
if (!$matcher or 'scan_cache' =~ /$matcher/){
$CPAN::Frontend->myprint($prompts{scan_cache_intro});
-
my_prompt_loop(scan_cache => 'atstart', $matcher, 'atstart|never');
}
}
#
+ #= YAML vs. YAML::Syck
+ #
+ if (!$matcher or "yaml_module" =~ /$matcher/) {
+ my_dflt_prompt(yaml_module => "YAML", $matcher);
+ }
+
+ #
#= External programs
#
}
if (!$matcher or 'makepl_arg make_arg' =~ /$matcher/){
- $CPAN::Frontend->myprint($prompts{makepl_arg_intro});
-
my_dflt_prompt(makepl_arg => "", $matcher);
my_dflt_prompt(make_arg => "", $matcher);
}
$matcher);
if (!$matcher or 'mbuildpl_arg mbuild_arg' =~ /$matcher/){
- $CPAN::Frontend->myprint($prompts{mbuildpl_arg_intro});
-
my_dflt_prompt(mbuildpl_arg => "", $matcher);
-
my_dflt_prompt(mbuild_arg => "", $matcher);
}
$DB::single = 1;
if (!$m || $item =~ /$m/) {
+ if (my $intro = $prompts{$item . "_intro"}) {
+ $CPAN::Frontend->myprint($intro);
+ }
$CPAN::Config->{$item} = prompt($prompts{$item}, $default);
} else {
$CPAN::Config->{$item} = $default;
sub bring_your_own {
my %seen = map (($_ => 1), @$urllist);
my($ans,@urls);
+ my $eacnt = 0; # empty answers
do {
my $prompt = "Enter another URL or RETURN to quit:";
unless (%seen) {
|| "configuration file",
));
}
+ } else {
+ if (++$eacnt >= 5) {
+ $CPAN::Frontend->
+ mywarn("Giving up.\n");
+ $CPAN::Frontend->mysleep(5);
+ return;
+ }
}
} while $ans || !%seen;
The following questions are intended to help you with the
configuration. The CPAN module needs a directory of its own to cache
important index files and maybe keep a temporary mirror of CPAN files.
-This may be a site-wide directory or a personal directory.
+This may be a site-wide or a personal directory.
},
"Directory where the build process takes place?",
+prefs_dir_intro => qq{
+
+CPAN.pm can store customized build environments based on regular
+expressions for distribution names. These are YAML files where the
+default options for CPAN.pm and the environment can be overridden and
+dialog sequences can be stored that can later be executed by an
+Expect.pm object. The CPAN.pm distribution comes with some prefab YAML
+files that cover sample distributions that can be used as blueprints
+to store one own prefs. Please check out the distroprefs/ directory of
+the CPAN.pm distribution to get a quick start into the prefs system.
+
+},
+
+prefs_dir =>
+
+"Directory where to store default options/environment/dialogs for
+building modules that need some customization?",
+
scan_cache_intro => qq{
By default, each time the CPAN module is started, cache scanning is
qq{Policy on installing 'build_requires' modules (yes, no, ask/yes,
ask/no)?},
+yaml_module_intro => qq{
+
+At the time of this writing there are two competing YAML modules,
+YAML.pm and YAML::Syck. The latter is faster but needs a C compiler
+installed on your system. There may be more alternative YAML
+conforming modules but at the time of writing a potential third
+player, YAML::Tiny, is not yet sufficiently similar to the other two.
+
+},
+
+yaml_module => qq{Which YAML implementation would you prefer?},
+
);
die "Coding error in \@prompts declaration. Odd number of elements, above"