From: Steve Peters Date: Thu, 6 Jul 2006 15:38:51 +0000 (+0000) Subject: Upgrade to Module-Build-0.2801. X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=f943a5bf3fa0f85f262e926ddedb02aad0fc623c;p=p5sagit%2Fp5-mst-13.2.git Upgrade to Module-Build-0.2801. p4raw-id: //depot/perl@28495 --- diff --git a/lib/Module/Build.pm b/lib/Module/Build.pm index 1688060..396add3 100644 --- a/lib/Module/Build.pm +++ b/lib/Module/Build.pm @@ -15,7 +15,7 @@ use Module::Build::Base; use vars qw($VERSION @ISA); @ISA = qw(Module::Build::Base); -$VERSION = '0.28'; +$VERSION = '0.2801'; $VERSION = eval $VERSION; # Okay, this is the brute-force method of finding out what kind of @@ -867,113 +867,29 @@ This will effectively install to "/tmp/foo/$sitelib", C to make the pathnames work correctly on whatever platform you're installing on. -=back - - -=head2 About PREFIX Support - -[version 0.28] - -First, it is necessary to understand the original idea behind -C. If, for example, the default installation locations for -your machine are F for modules, -F for executables, F and -F for manual pages, etc., then they all share the -same "prefix" F. MakeMaker's C mechanism was -intended as a way to change an existing prefix that happened to occur -in all those paths - essentially a C<< s{/usr/local}{/foo/bar} >> for -each path. - -However, the real world is more complicated than that. The C -idea is fundamentally broken when your machine doesn't jibe with -C's worldview. - - -=over 4 - -=item Why PREFIX is not recommended - -=over 4 - -=item * - -Many systems have Perl configs that make little sense with PREFIX. -For example, OS X, where core modules go in -F, user-installed modules go in -F, and man pages go in F. The -PREFIX is thus set to F. Install L on OS X with -C and you get things like -F and -F. Not too pretty. - -The problem is not limited to Unix-like platforms, either - on Windows -builds (e.g. ActiveState perl 5.8.0), we have user-installed modules -going in F, user-installed executables going in -F, and PREFIX=F. The prefix just doesn't -apply neatly to the executables. - -=item * - -The PREFIX logic is too complicated and hard to predict for the user. -It's hard to document what exactly is going to happen. You can't give -a user simple instructions like "run perl Makefile.PL PREFIX=~ and -then set PERL5LIB=~/lib/perl5". - -=item * - -The results from PREFIX will change if your configuration of Perl -changes (for example, if you upgrade Perl). This means your modules -will end up in different places. - -=item * - -The results from PREFIX can change with different releases of -MakeMaker. The logic of PREFIX is subtle and it has been altered in -the past (mostly to limit damage in the many "edge cases" when its -behavior was undesirable). - -=item * - -PREFIX imposes decisions made by the person who configured Perl onto -the person installing a module. The person who configured Perl could -have been you or it could have been some guy at Redhat. - -=back - - -=item Alternatives to PREFIX - -Module::Build offers L as a simple, predictable, and -user-configurable alternative to ExtUtils::MakeMaker's C. -What's more, MakeMaker will soon accept C -- we strongly -urge you to make the switch. - -Here's a quick comparison of the two when installing modules to your -home directory on a unix box: - -MakeMaker [*]: - - % perl Makefile.PL PREFIX=/home/spurkis - PERL5LIB=/home/spurkis/lib/perl5/5.8.5:/home/spurkis/lib/perl5/site_perl/5.8.5 - PATH=/home/spurkis/bin - MANPATH=/home/spurkis/man +=item prefix -Module::Build: +Provided for compatibility with ExtUtils::MakeMaker's PREFIX argument. +C should be used when you wish Module::Build to install your +modules, documentation and scripts in the same place +ExtUtils::MakeMaker does. - % perl Build.PL install_base=/home/spurkis - PERL5LIB=/home/spurkis/lib/perl5 - PATH=/home/spurkis/bin - MANPATH=/home/spurkis/man +The following are equivalent. -[*] Note that MakeMaker's behaviour cannot be guaranteed in even this -common scenario, and differs among different versions of MakeMaker. + perl Build.PL --prefix /tmp/foo + perl Makefile.PL PREFIX=/tmp/foo -In short, using C is similar to the following MakeMaker usage: +Because of the very complex nature of the prefixification logic, the +behavior of PREFIX in MakeMaker has changed subtly over time. +Module::Build's --prefix logic is equivalent to the PREFIX logic found +in ExtUtils::MakeMaker 6.30. - perl Makefile.PL PREFIX=/home/spurkis LIB=/home/spurkis/lib/perl5 +If you do not need to retain compatibility with ExtUtils::MakeMaker or +are starting a fresh Perl installation we recommand you use +C instead (and C in ExtUtils::MakeMaker). +See L for further information. -See L for details on other -installation options available and how to configure them. =back diff --git a/lib/Module/Build/Base.pm b/lib/Module/Build/Base.pm index c8d6275..bb17f66 100644 --- a/lib/Module/Build/Base.pm +++ b/lib/Module/Build/Base.pm @@ -1272,6 +1272,13 @@ sub make_executable { } } +sub is_executable { + # We assume this does the right thing on generic platforms, though + # we do some other more specific stuff on Unixish platforms. + my ($self, $file) = @_; + return -x $file; +} + sub _startperl { shift()->config('startperl') } # Return any directories in @INC which are not in the default @INC for @@ -2496,7 +2503,7 @@ sub htmlify_pods { my $pods = $self->_find_pods( $self->{properties}{"${type}doc_dirs"}, exclude => [ qr/\.(?:bat|com|html)$/ ] ); - next unless %$pods; # nothing to do + return unless %$pods; # nothing to do unless ( -d $htmldir ) { File::Path::mkpath($htmldir, 0, 0755) @@ -3955,7 +3962,7 @@ sub copy_if_modified { $self->log_info("$file -> $to_path\n") if $args{verbose}; File::Copy::copy($file, $to_path) or die "Can't copy('$file', '$to_path'): $!"; # mode is read-only + (executable if source is executable) - my $mode = 0444 | ( -x $file ? 0111 : 0 ); + my $mode = 0444 | ( $self->is_executable($file) ? 0111 : 0 ); chmod( $mode, $to_path ); return $to_path; diff --git a/lib/Module/Build/Changes b/lib/Module/Build/Changes index bab7592..1928c70 100644 --- a/lib/Module/Build/Changes +++ b/lib/Module/Build/Changes @@ -1,5 +1,39 @@ Revision history for Perl extension Module::Build. +0.2801 Sun May 21 00:07:40 CDT 2006 + + - Module::Build::Compat's emulation of INC is incorrectly prepending + a -I to the value of INC. This is incorrect because there should + already be a -I on the value. I.E. it's "perl Makefile.PL INC=-Ifoo" + not "perl Makefile.PL INC=foo" so Compat should not prefix a -I. + [Michael Schwern] + + - Native batch scripts under Windows should not be converted by + pl2bat. [Spotted by Ron Savage] + + - Tweaked the way we determine whether a file is executable on Unix. + We use this determination to decide whether to make it executable + during installation. [Julian Mehnle] + + - Replaced a vestigial 'next' with 'return' now that the code is in a + subroutine (htmlify_pods()), not a loop. [Ron Savage] + + - Fixed a guaranteed failure in t/signature.t when TEST_SIGNATURE was + set. [Eric R. Meyers] + + - Fixed a test failure that occurred when testing or installing in + unattended mode - the code to test whether unattended mode and + attended mode are working properly was assuming that we started out + in attended mode. [Steve Peters] + + - Improved our stand-in YAML generator that we use to generate + META.yaml when authors don't have a copy of YAML.pm installed on + their machine. It was unable to handle things like embedded + newlines in the data, now it has a much more extensive escaping + mechanism. [Stephen Adkins] + + - Revised the docs for --prefix and PREFIX. [Michael Schwern] + 0.28 Thu Apr 27 22:25:00 CDT 2006 - When y_n() or prompt() are called without a default value and the diff --git a/lib/Module/Build/Compat.pm b/lib/Module/Build/Compat.pm index 780ecd4..c573cc5 100644 --- a/lib/Module/Build/Compat.pm +++ b/lib/Module/Build/Compat.pm @@ -15,7 +15,7 @@ my %makefile_to_build = ( TEST_VERBOSE => 'verbose', VERBINST => 'verbose', - INC => sub { map {('--extra_compiler_flags', "-I$_")} Module::Build->split_like_shell(shift) }, + INC => sub { map {('--extra_compiler_flags', $_)} Module::Build->split_like_shell(shift) }, POLLUTE => sub { ('--extra_compiler_flags', '-DPERL_POLLUTE') }, INSTALLDIRS => sub {local $_ = shift; 'installdirs=' . (/^perl$/ ? 'core' : $_) }, LIB => sub { ('--install_path', 'lib='.shift()) }, diff --git a/lib/Module/Build/Cookbook.pm b/lib/Module/Build/Cookbook.pm index 376e2a3..6439b05 100644 --- a/lib/Module/Build/Cookbook.pm +++ b/lib/Module/Build/Cookbook.pm @@ -131,22 +131,69 @@ F directory. To install to a non-standard directory (for example, if you don't have permission to install in the system-wide directories), you can use the -C or C parameters: +C: ./Build install --install_base /foo/bar - or - ./Build install --prefix /foo/bar - -Note that these have somewhat different effects - C is an -emulation of C's old C setting, and -inherits all its nasty gotchas. C is more predictable, -and newer versions of C also support it, so it's -often your best choice. See L for a much more complete discussion of how installation paths are determined. +=head2 Installing in the same location as ExtUtils::MakeMaker + +With the introduction of C<--prefix> in Module::Build 0.28 and +C in ExtUtils::MakeMaker 6.31 its easy to get them both +to install to the same locations. + +First, ensure you have at least version 0.28 of Module::Build +installed and 6.31 of ExtUtils::MakeMaker. Prior versions have +differing installation behaviors. + +The following installation flags are equivalent between +ExtUtils::MakeMaker and Module::Build. + + MakeMaker Module::Build + PREFIX=... --prefix ... + INSTALL_BASE=... --install_base ... + DESTDIR=... --destdir ... + LIB=... --install_path lib=... + INSTALLDIRS=... --installdirs ... + INSTALLDIRS=perl --installdirs core + UNINST=... --uninst ... + INC=... --extra_compiler_flags ... + POLLUTE=1 --extra_compiler_flags -DPERL_POLLUTE + +For example, if you are currently installing MakeMaker modules with +this command: + + perl Makefile.PL PREFIX=~ + make test + make install UNINST=1 + +You can install into the same location with Module::Build using this: + + perl Build.PL --prefix ~ + ./Build test + ./Build install --uninst 1 + +=head3 C vs C + +The behavior of C is complicated and depends closely on +how your Perl is configured. The resulting installation locations +will vary from machine to machine and even different installations of +Perl on the same machine. Because of this, its difficult to document +where C will place your modules. + +In contrast, C has predictable, easy to explain +installation locations. Now that Module::Build and MakeMaker both +have C there is little reason to use C other +than to preserve your existing installation locations. If you are +starting a fresh Perl installation we encourage you to use +C. If you have an existing installation installed via +C, consider moving it to an installation structure matching +C and using that instead. + + =head2 Running a single test file C supports running a single test, which enables you to diff --git a/lib/Module/Build/Platform/Unix.pm b/lib/Module/Build/Platform/Unix.pm index e6060fe..18b6855 100644 --- a/lib/Module/Build/Platform/Unix.pm +++ b/lib/Module/Build/Platform/Unix.pm @@ -13,6 +13,17 @@ sub make_tarball { $self->SUPER::make_tarball(@_); } +sub is_executable { + # We consider the owner bit to be authoritative on a file, because + # -x will always return true if the user is root and *any* + # executable bit is set. The -x test seems to try to answer the + # question "can I execute this file", but I think we want "is this + # file executable". + + my ($self, $file) = @_; + return +(stat $file)[2] & 0100; +} + sub _startperl { "#! " . shift()->perl } sub _construct { diff --git a/lib/Module/Build/Platform/Windows.pm b/lib/Module/Build/Platform/Windows.pm index 9cde7a9..774db99 100644 --- a/lib/Module/Build/Platform/Windows.pm +++ b/lib/Module/Build/Platform/Windows.pm @@ -54,17 +54,26 @@ sub make_executable { $self->SUPER::make_executable(@_); foreach my $script (@_) { - my %opts = (); - if ( $script eq $self->build_script ) { - $opts{ntargs} = q(-x -S %0 --build_bat %*); - $opts{otherargs} = q(-x -S "%0" --build_bat %1 %2 %3 %4 %5 %6 %7 %8 %9); - } - my $out = eval {$self->pl2bat(in => $script, update => 1, %opts)}; - if ( $@ ) { - $self->log_warn("WARNING: Unable to convert file '$script' to an executable script:\n$@"); + # Native batch script + if ( $script =~ /\.(bat|cmd)$/ ) { + $self->SUPER::make_executable($script); + next; + + # Perl script that needs to be wrapped in a batch script } else { - $self->SUPER::make_executable($out); + my %opts = (); + if ( $script eq $self->build_script ) { + $opts{ntargs} = q(-x -S %0 --build_bat %*); + $opts{otherargs} = q(-x -S "%0" --build_bat %1 %2 %3 %4 %5 %6 %7 %8 %9); + } + + my $out = eval {$self->pl2bat(in => $script, update => 1, %opts)}; + if ( $@ ) { + $self->log_warn("WARNING: Unable to convert file '$script' to an executable script:\n$@"); + } else { + $self->SUPER::make_executable($out); + } } } } diff --git a/lib/Module/Build/YAML.pm b/lib/Module/Build/YAML.pm index cf52299..1b0605f 100644 --- a/lib/Module/Build/YAML.pm +++ b/lib/Module/Build/YAML.pm @@ -102,25 +102,30 @@ sub _yaml_chunk { } sub _yaml_value { - # XXX doesn't handle embedded newlines my ($value) = @_; - # undefs and empty strings will become empty strings - if (! defined $value || $value eq "") { - return('""'); + # undefs become ~ + if (! defined $value) { + return("~"); } - # allow simple scalars (without embedded quote chars) to be unquoted - elsif ($value !~ /["'\\]/) { - return($value); + # empty strings will become empty strings + elsif (! defined $value || $value eq "") { + return('""'); } - # strings without double-quotes get double-quoted - elsif ($value !~ /\"/) { - $value =~ s{\\}{\\\\}g; - return qq{"$value"}; + # quote and escape strings with special values + elsif ($value =~ /["'`~\n!\@\#^\&\*\(\)\{\}\[\]\|<>\?]/) { + if ($value !~ /['`~\n!\#^\&\*\(\)\{\}\[\]\|\?]/) { # nothing but " or @ or < or > (email addresses) + return("'" . $value . "'"); + } + else { + $value =~ s/\n/\\n/g; # handle embedded newlines + $value =~ s/"/\\"/g; # handle embedded quotes + return('"' . $value . '"'); + } } - # other strings get single-quoted + # allow simple scalars (without embedded quote chars) to be unquoted + # (includes $%_+=-\;:,./) else { - $value =~ s{([\\'])}{\\$1}g; - return qq{'$value'}; + return($value); } } diff --git a/lib/Module/Build/t/lib/MBTest.pm b/lib/Module/Build/t/lib/MBTest.pm index 28e5355..35bff92 100644 --- a/lib/Module/Build/t/lib/MBTest.pm +++ b/lib/Module/Build/t/lib/MBTest.pm @@ -44,7 +44,7 @@ $VERSION = 0.01; # We have a few extra exports, but Test::More has a special import() # that won't take extra additions. -my @extra_exports = qw(stdout_of stderr_of slurp find_in_path check_compiler); +my @extra_exports = qw(stdout_of stderr_of slurp find_in_path check_compiler have_module); push @EXPORT, @extra_exports; __PACKAGE__->export(scalar caller, @extra_exports); @@ -105,4 +105,9 @@ sub check_compiler { return ($have_c_compiler, $mb->feature('C_support')); } +sub have_module { + my $module = shift; + return eval "use $module; 1"; +} + 1; diff --git a/lib/Module/Build/t/mbyaml.t b/lib/Module/Build/t/mbyaml.t index 78b4869..01e27ae 100644 --- a/lib/Module/Build/t/mbyaml.t +++ b/lib/Module/Build/t/mbyaml.t @@ -9,9 +9,12 @@ $dir = "."; $dir = "t" if (-d "t"); { - use_ok("Module::Build::YAML"); - my ($expected, $got, $var); - $var = { + use_ok("Module::Build::YAML"); + my ($expected, $got, $var); + ########################################################## + # Test a typical-looking Module::Build structure (alphabetized) + ########################################################## + $var = { 'resources' => { 'license' => 'http://opensource.org/licenses/artistic-license.php' }, @@ -43,11 +46,11 @@ $dir = "t" if (-d "t"); }, 'abstract' => 'A framework for building dynamic widgets or full applications in Javascript' }; - $expected = <' + - '"Stephen Adkins" ' build_requires: App::Build: 0 File::Spec: 0 @@ -72,12 +75,15 @@ EOF $got = &Module::Build::YAML::Dump($var); is($got, $expected, "Dump(): single deep hash"); - $expected = <' + - '"Stephen Adkins" ' abstract: A framework for building dynamic widgets or full applications in Javascript license: lgpl resources: @@ -102,13 +108,16 @@ EOF $got = &Module::Build::YAML::Dump($var); is($got, $expected, "Dump(): single deep hash, ordered"); + ########################################################## + # Test that an array turns into multiple documents + ########################################################## $var = [ "e", 2.71828, [ "pi", "is", 3.1416 ], { fun => "under_sun", 6 => undef, "more", undef }, ]; - $expected = <new(); $got = $y->Dump($var); is($got, $expected, "Dump(): single array of various (OO)"); + + ########################################################## + # Test Quoting Conditions (newlines, quotes, tildas, undefs) + ########################################################## + $var = { + 'foo01' => '`~!@#$%^&*()_+-={}|[]\\;\':",./?<> +', + 'foo02' => '~!@#$%^&*()_+-={}|[]\\;:,./<>?', + 'foo03' => undef, + 'foo04' => '~', + }; + $expected = <<'EOF'; +--- +foo01: "`~!@#$%^&*()_+-={}|[]\;':\",./?<>\n" +foo02: "~!@#$%^&*()_+-={}|[]\;:,./<>?" +foo03: ~ +foo04: "~" +EOF + $got = &Module::Build::YAML::Dump($var); + is($got, $expected, "Dump(): tricky embedded characters"); + + $var = { + 'foo10' => undef, + 'foo40' => '!', + 'foo41' => '@', + 'foo42' => '#', + 'foo43' => '$', + 'foo44' => '%', + 'foo45' => '^', + 'foo47' => '&', + 'foo48' => '*', + 'foo49' => '(', + 'foo50' => ')', + 'foo51' => '_', + 'foo52' => '+', + 'foo53' => '-', + 'foo54' => '=', + 'foo55' => '{', + 'foo56' => '}', + 'foo57' => '|', + 'foo58' => '[', + 'foo59' => ']', + 'foo60' => '\\', + 'foo61' => ';', + 'foo62' => ':', + 'foo63' => ',', + 'foo64' => '.', + 'foo65' => '/', + 'foo66' => '<', + 'foo67' => '>', + 'foo68' => '?', + 'foo69' => '\'', + 'foo70' => '"', + 'foo71' => '`', + 'foo72' => ' +', + }; + $expected = <<'EOF'; +--- +foo10: ~ +foo40: "!" +foo41: '@' +foo42: "#" +foo43: $ +foo44: % +foo45: "^" +foo47: "&" +foo48: "*" +foo49: "(" +foo50: ")" +foo51: _ +foo52: + +foo53: - +foo54: = +foo55: "{" +foo56: "}" +foo57: "|" +foo58: "[" +foo59: "]" +foo60: \ +foo61: ; +foo62: : +foo63: , +foo64: . +foo65: / +foo66: '<' +foo67: '>' +foo68: "?" +foo69: "'" +foo70: '"' +foo71: "`" +foo72: "\n" +EOF + $got = &Module::Build::YAML::Dump($var); + is($got, $expected, "Dump(): tricky embedded characters (singles)"); + } diff --git a/lib/Module/Build/t/runthrough.t b/lib/Module/Build/t/runthrough.t index faf3cdb..1e52b62 100644 --- a/lib/Module/Build/t/runthrough.t +++ b/lib/Module/Build/t/runthrough.t @@ -2,7 +2,7 @@ use strict; use lib $ENV{PERL_CORE} ? '../lib/Module/Build/t/lib' : 't/lib'; -use MBTest tests => 28; +use MBTest tests => 32; use Module::Build; use Module::Build::ConfigData; @@ -197,6 +197,47 @@ ok ! -e $mb->build_script; ok ! -e $mb->config_dir; ok ! -e $mb->dist_dir; +chdir( $cwd ) or die "Can''t chdir to '$cwd': $!"; +$dist->remove; + +SKIP: { + skip( 'Windows only test', 4 ) unless $^O =~ /^MSWin/; + + my $script_data = <<'---'; +@echo off +echo Hello, World! +--- + + $dist = DistGen->new( dir => $tmp ); + $dist->change_file( 'Build.PL', <<'---' ); +use Module::Build; +my $build = new Module::Build( + module_name => 'Simple', + scripts => [ 'bin/script.bat' ], + license => 'perl', +); +$build->create_build_script; +--- + $dist->add_file( 'bin/script.bat', $script_data ); + + $dist->regen; + chdir( $dist->dirname ) or die "Can't chdir to '@{[$dist->dirname]}': $!"; + + $mb = Module::Build->new_from_context; + ok $mb; + + eval{ $mb->dispatch('build') }; + is $@, ''; + + my $script_file = File::Spec->catfile( qw(blib script), 'script.bat' ); + ok -f $script_file, "Native batch file copied to 'scripts'"; + + my $out = slurp( $script_file ); + is $out, $script_data, ' unmodified by pl2bat'; + + chdir( $cwd ) or die "Can''t chdir to '$cwd': $!"; + $dist->remove; +} # cleanup chdir( $cwd ) or die "Can''t chdir to '$cwd': $!";