Subject: | CPAN should warn if CPAN::Config contains problematic entries |
I have my make utility installed in a path with whitespace in it
(actually, Microsoft chose so and I stayed with the default).
CPAN/FirstTime.pm adds $CPAN::Config->{make} as
'make' => q[C:\Programme\Microsoft Visual C++ Toolkit 2003\bin\nmake.EXE],
which later on causes problems with the shell interpolation. Of course,
the Grand Big Scheme will be to exorcise all shell interpolation
and system(STRING) calls, but the easy fix was to add appropriate quotes
to my CPAN/Config.pm like this:
'make' => q["C:\Programme\Microsoft Visual C++ Toolkit
2003\bin\nmake.EXE"],
I've patched CPAN::HandleConfig to add a C<sanity_check> method which
currently checks just that the C<make> entry is sane (that is, exists,
and if it contains whitespace, that it also has quotes at the start and
end). See the attached diff against 1.87, and the attached test file to
test it.
Thanks for maintaining CPAN!
-max
Subject: | sanity_check.t |
#!/usr/bin/perl -w
use strict;
use Test::More tests => 5;
use Data::Dumper;
use_ok "CPAN::HandleConfig";
{
local $CPAN::Config = {};
is_deeply( { CPAN::HandleConfig->sanity_check() }, {}, "Sanity check for undefined 'make' entry works" )
or diag Dumper { CPAN::HandleConfig->sanity_check() };
};
{
local $CPAN::Config = {
make => '/some/path with whitespace/in it/where the file doesnt/exist',
};
is_deeply( { CPAN::HandleConfig->sanity_check() }->{make},
[
'A path seems to be given in >/some/path with whitespace/in it/where the file doesnt/exist< but the file was not found.',
'>/some/path with whitespace/in it/where the file doesnt/exist<
seems to contain whitespace but is not quoted.
This might be OK if there are additional commands you
want to pass to your make utility. If you want to use
"/some/path with whitespace/in it/where the file doesnt/exist"
as your make program, please add appropriate quotes
to the line in Config.pm.
',
], "Sanity check for unquoted 'make' entry works" )
or diag Dumper { CPAN::HandleConfig->sanity_check() };
};
{
local $CPAN::Config = {
make => 'make',
};
is_deeply( { CPAN::HandleConfig->sanity_check() }, {}, "Sanity check for bare 'make' is silent" )
or diag Dumper { CPAN::HandleConfig->sanity_check() };
};
{
local $CPAN::Config = {
make => 'nmake.exe',
};
is_deeply( { CPAN::HandleConfig->sanity_check() }, {}, "Sanity check for bare 'make' is silent (Win32 variant)" );
};
Subject: | HandleConfig.diff |
--- HandleConfig.pm Wed Feb 22 23:02:27 2006
+++ HandleConfig.pm-Corion Mon Feb 27 16:54:40 2006
@@ -287,7 +287,7 @@
# maintainability. RMB
#
sub _configpmtest {
- my($configpmdir, $configpmtest) = @_;
+ my($configpmdir, $configpmtest) = @_;
if (-w $configpmtest) {
return $configpmtest;
} elsif (-w $configpmdir) {
@@ -341,6 +341,18 @@
my(@miss);
use Carp;
require_myconfig_or_config;
+ my %warnings = $self->sanity_check();
+ if (! $args{be_silent} && keys %warnings) {
+ $CPAN::Frontend->myprint( "*** The following values are possibly problematic:\n" );
+ for my $val (keys %warnings) {
+ for my $w (@{$warnings{$val}}) {
+ $w =~ s!^!\t\t!mg;
+ my $text = $val . substr( $w, 1 );
+ $CPAN::Frontend->myprint("$text\n");
+ };
+ };
+ };
+
return unless @miss = $self->missing_config_data;
require CPAN::FirstTime;
@@ -473,6 +485,60 @@
return grep /^\Q$word\E/, @o_conf;
}
+=head2 C<< $self->sanity_check >>
+
+Returns a list of suspicious/potentially problematic
+values and the corresponding warning messages.
+
+Currently, the only check made is for:
+
+=head3 C<< make >>
+
+If the (path to the) file contains whitespace
+and is not quoted, a warning is emitted, as
+CPAN.pm and other tools will likely have problems
+with that.
+
+=cut
+
+sub sanity_check {
+ my ($self) = @_;
+ my %res;
+ if (defined (my $make = $CPAN::Config->{make})) {
+ my $quotes = $^O eq 'MSWin32'
+ ? '"'
+ : qq<"'>;
+
+ my ($real_make,$is_quoted);
+ if ($make =~ /^([$quotes])(.*)\1$/) {
+ ($is_quoted,$real_make) = ($2,$1);
+ } else {
+ $real_make = $make;
+ };
+
+ # This will maybe create bogus warnings on VMSish systems?
+ # Maybe this should use a real shell parser or something
+ # to determine which "word" is the (path to) the make program
+ if (! -f $real_make && $real_make =~ m![\\/:]!) {
+ $res{ make } ||= [];
+ push @{$res{make}}, "A path seems to be given in >$make< but the file was not found.";
+ };
+ if ($make =~ /\s/ and not $is_quoted) {
+ $res{ make } ||= [];
+ push @{$res{make}}, <<MAKE_HAS_WHITESPACE;
+>$make<
+seems to contain whitespace but is not quoted.
+This might be OK if there are additional commands you
+want to pass to your make utility. If you want to use
+"$make"
+as your make program, please add appropriate quotes
+to the line in Config.pm.
+MAKE_HAS_WHITESPACE
+ };
+ };
+
+ %res;
+};
package
CPAN::Config; ####::###### #hide from indexer