summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--MANIFEST24
-rwxr-xr-xPorting/Maintainers.pl14
-rw-r--r--cpan/Module-Build/Changes355
-rw-r--r--cpan/Module-Build/lib/Module/Build.pm112
-rw-r--r--cpan/Module-Build/lib/Module/Build/API.pod105
-rw-r--r--cpan/Module-Build/lib/Module/Build/Base.pm1127
-rw-r--r--cpan/Module-Build/lib/Module/Build/Bundling.pod154
-rw-r--r--cpan/Module-Build/lib/Module/Build/Compat.pm143
-rw-r--r--cpan/Module-Build/lib/Module/Build/Config.pm2
-rw-r--r--cpan/Module-Build/lib/Module/Build/Cookbook.pm4
-rw-r--r--cpan/Module-Build/lib/Module/Build/Dumper.pm2
-rw-r--r--cpan/Module-Build/lib/Module/Build/ModuleInfo.pm30
-rw-r--r--cpan/Module-Build/lib/Module/Build/Notes.pm156
-rw-r--r--cpan/Module-Build/lib/Module/Build/PPMMaker.pm35
-rw-r--r--cpan/Module-Build/lib/Module/Build/Platform/Amiga.pm2
-rw-r--r--cpan/Module-Build/lib/Module/Build/Platform/Default.pm2
-rw-r--r--cpan/Module-Build/lib/Module/Build/Platform/EBCDIC.pm2
-rw-r--r--cpan/Module-Build/lib/Module/Build/Platform/MPEiX.pm2
-rw-r--r--cpan/Module-Build/lib/Module/Build/Platform/MacOS.pm22
-rw-r--r--cpan/Module-Build/lib/Module/Build/Platform/RiscOS.pm2
-rw-r--r--cpan/Module-Build/lib/Module/Build/Platform/Unix.pm2
-rw-r--r--cpan/Module-Build/lib/Module/Build/Platform/VMS.pm84
-rw-r--r--cpan/Module-Build/lib/Module/Build/Platform/VOS.pm2
-rw-r--r--cpan/Module-Build/lib/Module/Build/Platform/Windows.pm43
-rw-r--r--cpan/Module-Build/lib/Module/Build/Platform/aix.pm2
-rw-r--r--cpan/Module-Build/lib/Module/Build/Platform/cygwin.pm18
-rw-r--r--cpan/Module-Build/lib/Module/Build/Platform/darwin.pm2
-rw-r--r--cpan/Module-Build/lib/Module/Build/Platform/os2.pm12
-rw-r--r--cpan/Module-Build/lib/Module/Build/PodParser.pm20
-rw-r--r--cpan/Module-Build/lib/Module/Build/Version.pm48
-rw-r--r--cpan/Module-Build/lib/Module/Build/YAML.pm701
-rw-r--r--cpan/Module-Build/lib/inc/latest.pm250
-rw-r--r--cpan/Module-Build/lib/inc/latest/private.pm101
-rw-r--r--cpan/Module-Build/t/PL_files.t2
-rw-r--r--cpan/Module-Build/t/README.pod94
-rw-r--r--cpan/Module-Build/t/actions/installdeps.t48
-rw-r--r--cpan/Module-Build/t/add_property.t5
-rw-r--r--cpan/Module-Build/t/basic.t14
-rw-r--r--cpan/Module-Build/t/bundle_inc.t194
-rw-r--r--cpan/Module-Build/t/compat.t94
-rwxr-xr-x[-rw-r--r--]cpan/Module-Build/t/compat/exit.t11
-rw-r--r--cpan/Module-Build/t/debug.t10
-rw-r--r--cpan/Module-Build/t/destinations.t10
-rw-r--r--cpan/Module-Build/t/ext.t10
-rw-r--r--cpan/Module-Build/t/extend.t26
-rw-r--r--cpan/Module-Build/t/files.t7
-rw-r--r--cpan/Module-Build/t/help.t27
-rw-r--r--cpan/Module-Build/t/install.t13
-rw-r--r--cpan/Module-Build/t/install_extra_target.t30
-rw-r--r--cpan/Module-Build/t/lib/DistGen.pm235
-rw-r--r--cpan/Module-Build/t/lib/MBTest.pm73
-rw-r--r--cpan/Module-Build/t/manifypods.t16
-rw-r--r--cpan/Module-Build/t/mbyaml.t262
-rw-r--r--cpan/Module-Build/t/metadata.t20
-rw-r--r--cpan/Module-Build/t/metadata2.t28
-rw-r--r--cpan/Module-Build/t/moduleinfo.t192
-rw-r--r--cpan/Module-Build/t/mymeta.t30
-rw-r--r--cpan/Module-Build/t/new_from_context.t8
-rw-r--r--cpan/Module-Build/t/notes.t8
-rw-r--r--cpan/Module-Build/t/parents.t5
-rw-r--r--cpan/Module-Build/t/perl_mb_opt.t62
-rw-r--r--cpan/Module-Build/t/pod_parser.t28
-rw-r--r--cpan/Module-Build/t/ppm.t18
-rw-r--r--cpan/Module-Build/t/properties/module_name.t53
-rw-r--r--cpan/Module-Build/t/properties/needs_compiler.t122
-rw-r--r--cpan/Module-Build/t/properties/share_dir.t228
-rw-r--r--cpan/Module-Build/t/resume.t43
-rw-r--r--cpan/Module-Build/t/runthrough.t21
-rw-r--r--cpan/Module-Build/t/sample.t20
-rw-r--r--cpan/Module-Build/t/script_dist.t8
-rw-r--r--cpan/Module-Build/t/test_file_exts.t8
-rw-r--r--cpan/Module-Build/t/test_type.t7
-rw-r--r--cpan/Module-Build/t/test_types.t16
-rw-r--r--cpan/Module-Build/t/tilde.t8
-rw-r--r--cpan/Module-Build/t/use_tap_harness.t51
-rw-r--r--cpan/Module-Build/t/versions.t9
-rw-r--r--cpan/Module-Build/t/write_default_maniskip.t4
-rw-r--r--cpan/Module-Build/t/xs.t55
79 files changed, 4256 insertions, 1558 deletions
diff --git a/.gitignore b/.gitignore
index 74b65eba75..a20fbf93e2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -76,6 +76,7 @@ ext.libs
/uudmap.h
/bitcount.h
+lib/inc/
lib/Win32.pm
lib/Win32API/
lib/Win32CORE.pm
diff --git a/MANIFEST b/MANIFEST
index b8073eb771..2d76a3a7b8 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -1519,9 +1519,12 @@ cpan/MIME-Base64/t/quoted-print.t See whether MIME::QuotedPrint works
cpan/MIME-Base64/t/unicode.t See whether MIME::Base64 works
cpan/MIME-Base64/t/warn.t See whether MIME::Base64 works
cpan/Module-Build/Changes Module::Build
+cpan/Module-Build/lib/inc/latest.pm Module::Build
+cpan/Module-Build/lib/inc/latest/private.pm Module::Build
cpan/Module-Build/lib/Module/Build/API.pod Module::Build
cpan/Module-Build/lib/Module/Build/Authoring.pod Module::Build
cpan/Module-Build/lib/Module/Build/Base.pm Module::Build
+cpan/Module-Build/lib/Module/Build/Bundling.pod Module::Build
cpan/Module-Build/lib/Module/Build/Compat.pm Module::Build
cpan/Module-Build/lib/Module/Build/Config.pm Module::Build
cpan/Module-Build/lib/Module/Build/Cookbook.pm Module::Build
@@ -1548,33 +1551,42 @@ cpan/Module-Build/lib/Module/Build/PPMMaker.pm Module::Build
cpan/Module-Build/lib/Module/Build/Version.pm Module::Build
cpan/Module-Build/lib/Module/Build/YAML.pm Module::Build
cpan/Module-Build/scripts/config_data Module::Build
+cpan/Module-Build/t/actions/installdeps.t Module::Build
cpan/Module-Build/t/add_property.t Module::Build
cpan/Module-Build/t/basic.t Module::Build
-cpan/Module-Build/t/bundled/Tie/CPHash.pm Module::Build.pm
+cpan/Module-Build/t/bundled/Tie/CPHash.pm Module::Build
+cpan/Module-Build/t/bundle_inc.t Module::Build
cpan/Module-Build/t/compat/exit.t Module::Build
cpan/Module-Build/t/compat.t Module::Build
-cpan/Module-Build/t/debug.t Module::Build tests
+cpan/Module-Build/t/debug.t Module::Build
cpan/Module-Build/t/destinations.t Module::Build
cpan/Module-Build/t/extend.t Module::Build
cpan/Module-Build/t/ext.t Module::Build
cpan/Module-Build/t/files.t Module::Build
cpan/Module-Build/t/help.t Module::Build
-cpan/Module-Build/t/install_extra_target.t Module::Build tests
+cpan/Module-Build/t/install_extra_target.t Module::Build
cpan/Module-Build/t/install.t Module::Build
cpan/Module-Build/t/lib/DistGen.pm Module::Build
cpan/Module-Build/t/lib/MBTest.pm Module::Build
cpan/Module-Build/t/manifypods.t Module::Build
-cpan/Module-Build/t/mbyaml.t Module::Build
cpan/Module-Build/t/metadata2.t Module::Build
cpan/Module-Build/t/metadata.t Module::Build
cpan/Module-Build/t/moduleinfo.t Module::Build
+cpan/Module-Build/t/mymeta.t Module::Build
cpan/Module-Build/t/new_from_context.t Module::Build
cpan/Module-Build/t/notes.t Module::Build
cpan/Module-Build/t/parents.t Module::Build
-cpan/Module-Build/t/PL_files.t Module::Build tests
+cpan/Module-Build/t/perl_mb_opt.t Module::Build
+cpan/Module-Build/t/PL_files.t Module::Build
cpan/Module-Build/t/pod_parser.t Module::Build
cpan/Module-Build/t/ppm.t Module::Build
+cpan/Module-Build/t/properties/module_name.t Module::Build
+cpan/Module-Build/t/properties/needs_compiler.t Module::Build
+cpan/Module-Build/t/properties/share_dir.t Module::Build
+cpan/Module-Build/t/README.pod Module::Build
+cpan/Module-Build/t/resume.t Module::Build
cpan/Module-Build/t/runthrough.t Module::Build
+cpan/Module-Build/t/sample.t Module::Build
cpan/Module-Build/t/script_dist.t Module::Build
cpan/Module-Build/t/test_file_exts.t Module::Build
cpan/Module-Build/t/test_types.t Module::Build
@@ -1582,7 +1594,7 @@ cpan/Module-Build/t/test_type.t Module::Build
cpan/Module-Build/t/tilde.t Module::Build
cpan/Module-Build/t/use_tap_harness.t Module::Build
cpan/Module-Build/t/versions.t Module::Build
-cpan/Module-Build/t/write_default_maniskip.t Module::Build tests
+cpan/Module-Build/t/write_default_maniskip.t Module::Build
cpan/Module-Build/t/xs.t Module::Build
cpan/Module-Load-Conditional/lib/Module/Load/Conditional.pm Module::Conditional
cpan/Module-Load-Conditional/t/01_Module_Load_Conditional.t Module::Conditional tests
diff --git a/Porting/Maintainers.pl b/Porting/Maintainers.pl
index e5db2eb5a8..5ffa715ca1 100755
--- a/Porting/Maintainers.pl
+++ b/Porting/Maintainers.pl
@@ -104,7 +104,7 @@ use File::Glob qw(:case);
SIGNATURE THANKS TODO Todo VERSION WHATSNEW
);
-
+
# Each entry in the %Modules hash roughly represents a distribution,
# except in the case of CPAN=1, where it *exactly* represents a single
# CPAN distribution.
@@ -159,7 +159,7 @@ use File::Glob qw(:case);
# Each key reprepresents a string prefix, with longest prefixes checked
# first. The first match causes that prefix to be replaced with the
# corresponding key. For example, with the following MAP:
-# {
+# {
# 'lib/' => 'lib/',
# '' => 'lib/Foo/',
# },
@@ -167,7 +167,7 @@ use File::Glob qw(:case);
# these files are mapped as shown:
#
# README becomes lib/Foo/README
-# lib/Foo.pm becomes lib/Foo.pm
+# lib/Foo.pm becomes lib/Foo.pm
#
# The default is dependent on the type of module.
# For distributions which appear to be stored under ext/, it defaults to:
@@ -176,7 +176,7 @@ use File::Glob qw(:case);
#
# otherwise, it's
#
-# {
+# {
# 'lib/' => 'lib/',
# '' => 'lib/Foo/Bar/',
# }
@@ -1004,10 +1004,10 @@ use File::Glob qw(:case);
'Module::Build' =>
{
'MAINTAINER' => 'kwilliams',
- 'DISTRIBUTION' => 'DAGOLDEN/Module-Build-0.35.tar.gz',
+ 'DISTRIBUTION' => 'DAGOLDEN/Module-Build-0.35_08.tar.gz',
'FILES' => q[cpan/Module-Build],
- 'EXCLUDED' => [ qw{ t/par.t t/signature.t scripts/bundle.pl},
- qr!^contrib/! ],
+ 'EXCLUDED' => [ qw{ t/par.t t/signature.t },
+ qr!^contrib/!, qr!^devtools! ],
'CPAN' => 1,
'UPSTREAM' => 'cpan',
},
diff --git a/cpan/Module-Build/Changes b/cpan/Module-Build/Changes
index df66502dbd..f0f8d1b46d 100644
--- a/cpan/Module-Build/Changes
+++ b/cpan/Module-Build/Changes
@@ -1,24 +1,238 @@
Revision history for Perl extension Module::Build.
+0.35_08 - Mon Nov 16 22:38:28 EST 2009
+
+ Bug fixes:
+
+ - Multiple tests were failing due to dependency problems. Author
+ dependencies have been largely removed from core 'requires' into
+ optional features. Feature prereq detection and messaging have been
+ expanded and bugs on older Perls have been removed.
+
+0.35_07 - Sat Nov 14 17:14:39 EST 2009
+
+ Bug fixes:
+
+ - Auto-detection of abstract and author fixed for mixed-case POD headers
+ (RT#51117) [David Wheeler]
+
+ - resume() was not restoring additions to @INC added in Build.PL
+ (RT#50145) [David Golden]
+
+ - When tarball paths are less than 100 characters, disables 'prefix'
+ mode of Archive::Tar for maximum compatibility (RT#50571) [David Golden]
+
+0.35_06 - Fri Nov 13 14:51:28 EST 2009
+
+ Enhancements:
+
+ - Added experimental inc/ bundling; see Module::Build::Bundling for
+ details. [David Golden and Eric Wilhelm]
+
+ - Clarified that 'apache' in the license attribute indicates the Apache
+ License 2.0 and added 'apache_1_1' for the older version of the license
+ (RT#50614) [David Golden]
+
+ Bug fixes:
+
+ - Merging 'requires' and 'build_requires' in Module::Build::Compat could
+ lead to duplicate PREREQ_PM entries; now the highest version is used
+ for PREREQ_PM. (RT#50948) [David Golden]
+
+ - Module::Build::Compat will now die with an error if advanced,
+ non-numeric prerequisites are given, as these are not supported by
+ ExtUtils::MakeMaker in PREREQ_PM [David Golden]
+
+ - Made MYMETA generation non-fatal if fields required for META.yml
+ are missing [David Golden]
+
+ - Added Pod::Simple to requirements for manpage support; avoids
+ problems if a user has a broken Pod::Man/Pod::Simple. (RT#50081)
+ [David Golden]
+
+ - Won't die if installed Pod::Readme is broken [David Golden]
+
+ Other:
+
+ - Fixed Module::Build::Notes POD [David Golden]
+
+ - Some commands had become silent by default, so added a few short status
+ messages so users know something actually happened [David Golden]
+
+ - Cleaned up Changes file formatting [David Golden]
+
+ - Removed most PERL_CORE customizations from test files due to
+ reorganization of dual-life modules in core (RT#49522) [David Golden]
+
+0.35_05 - Wed Oct 28 17:20:59 EDT 2009
+
+ Bug fixes:
+
+ - Fix test failure in t/actions/installdeps.t when $^X is not the default
+ perl [David Golden]
+
+ - Work around $VERSION numbers in ActiveState with multiple underscores
+ that prevent Module::Build from installing on Win32 [David Golden]
+
+ - Fix bug cleaning compatibility Makefile when older ExtUtils::Manifest is
+ installed [David Golden with help from David Cantrell]
+
+ Other:
+
+ - Suppressed more warnings from tests [David Golden]
+
+ - Add provisional support for 'package NAME VERSION' syntax added in
+ Perl 5.11.1 [David Golden]
+
+0.35_04 - Fri Oct 23 11:20:41 EDT 2009
+
+ Bug fixes:
+
+ - Fix test failure if IPC::Cmd isn't installed [David Golden]
+
+ Other:
+
+ - Suppressed warning messages from various tests [David Golden]
+
+0.35_03 - Wed Oct 21 21:20:59 EDT 2009
+
+ *** API CHANGE ***
+
+ - The prepare_metadata() method used to take a YAML::Node object as an
+ argument for modification. The method now takes no arguments and just
+ returns a hash reference of metadata. [David Golden]
+
+ Enhancements
+
+ - Command line options may be set via the PERL_MB_OPT environment
+ variable (similar to PERL_MM_OPT in ExtUtils::MakeMaker)
+
+ Bug fixes:
+
+ - Updated PPM generation to PPM v4 (RT#49600) [Olivier Mengue]
+
+ - When c_source is specified, the directory scan will include additional,
+ less-common C++ extensions (RT49298) [David Golden]
+
+ - When module_name is not supplied, no packlist was being written; fixed
+ by guessing module_name from dist_version_from or the directory name
+ (just like ExtUtils::Manifest does without NAME) [David Golden]
+
+ - Bumped IO::File prereq to fix binmode failures in PPMMaker on Perl
+ prior to 5.8.8 [David Golden]
+
+ Other:
+
+ - Replaced use of YAML.pm with YAML::Tiny; Module::Build::YAML is now
+ based on YAML::Tiny as well [David Golden]
+
+ - Reduced amount of console output under normal operation (use --verbose
+ to see all output) [David Golden]
+
+0.35_02 - Mon Sep 7 22:37:42 EDT 2009
+
+ Enhancements:
+
+ - Added 'needs_compiler' property. Defaults to true if XS or c_source
+ exist. If true, ExtUtils::CBuilder is also added to build_requires.
+ [David Golden]
+
+ - File::ShareDir automatically added to 'requires' if 'share_dir' is set
+ [David Golden]
+
+ - Added 'Build installdeps' action to install needed dependencies via
+ a user-configurable command line program. (Defaults to 'cpan'.)
+ [Eric Wilhelm]
+
+ Bug fixes:
+
+ - Failure to detect a compiler will now warn during Build.PL and be a
+ fatal error when trying to compile during Build. (RT#48918) [David
+ Golden]
+
+ - Fixed directory sorting failure in share_dir.t [David Golden]
+
+ - Property defaults that are data structures were being assigned as
+ references to new objects. Changed so that defaults are cloned instead.
+ (This mostly affects testing, which often creates multiple objects in the
+ same process) [David Golden]
+
+ - Simplified error message on exit under use_tap_harness [suggested by
+ David Wheeler]
+
+ - Fixed typemap search to use a dist-level typemap if a typemap is not
+ found in the directory with the *.xs file; (was manifesting as warnings
+ in Perl 5.6 tests) [David Golden]
+
+ Other:
+
+ - Replaced guts of new_from_context(). Build.PL is now executed in a
+ separate process before resume() is called. (This is generally only of
+ interest to Module::Build or toolchain developers) (RT#49350) [David
+ Golden, Eric Wilhelm, Ken Williams]
+
+ - Revised test helper classes to fix potential bugs and add new features
+ to make writing tests simpler and easier. Changes incorporated into
+ t/README.pod and t/sample.t as examples for new testing. [David Golden]
+
+0.35_01 - Mon Aug 31 12:11:10 EDT 2009
+
+ Enhancements:
+
+ - Generates MYMETA.yml during Build.PL (new standard protocol for
+ communicating configuration results between toolchain components)
+ [David Golden]
+
+ - Added 'share_dir' property to provide File::ShareDir support;
+ set automatically if a directory called 'share' exists
+ [David Golden]
+
+ Bug fixes:
+
+ - Fix the t/destinations.t fix. [David Golden, with thanks to Eric Wilhelm]
+
+ - Fix recursive test files in generated Makefile.PL (RT#49254) [Sawyer X]
+
+ - Guard against trying :utf8 when :utf8 isn't available
+
+ - The "test" action now dies when using the 'use_tap_harness'
+ option and tests fail, matching the behavior under Test::Harness.
+ (RT#49080) [initial patch from David Wheeler; revised by David Golden]
+
+ Other:
+
+ - Added t/README.pod and t/sample.t to guide developers writing new tests
+ [David Golden, with some code from Eric Wilhelm]
+
+ - Module::Build::Compat 'passthrough' style has been deprecated. Using
+ 'passthrough' will issue warnings on Makefile.PL generation. See
+ Module::Build::Compat documentation for rationale.
+
0.35 - Thu Aug 27 09:12:02 EDT 2009
Bug fixes:
- - Fix t/destinations.t segfault on 5.6.2
+
+ - Fix t/destinations.t segfault on 5.6.2 [David Golden]
0.34_06 - Sat Aug 22 21:58:26 EDT 2009
Bug fixes:
+
- Multiple test fixes for OS2 [Ilya Zakharevich]
+
- Generated.ppd files use :utf8 if possible (RT#48827) [Olivier Mengue]
+
- Fixed preservation of custom install_paths on resume (RT#41166)
[David Golden]
+
- Warn instead of crashing when Pod::Man tries to create files with
colons on vfat partitions on unix (RT#45544) [David Golden]
0.34_05 - Sun Aug 9 22:31:37 EDT 2009
Bug fixes:
- - When auto_configure_requires is true (the default), Module::Build will
+
+ - When auto_configure_requires is true (the default), Module::Build will
only add last 'major' version of Module:Build (e.g. 0.XX) to
configure_requires to avoid specifying a minor development release not
available on CPAN [David Golden]
@@ -26,6 +240,7 @@ Revision history for Perl extension Module::Build.
0.34_04 - Sat Aug 8 11:02:24 EDT 2009
Other:
+
- Added documentation warning that 'get_options' should be capitalized
to avoid conflicting with future Module::Build options and changed
the examples accordingly.
@@ -33,12 +248,17 @@ Revision history for Perl extension Module::Build.
0.34_03 - Sat Aug 8 07:39:16 EDT 2009
Bug fixes:
+
- Fixed failing xs.t if /tmp is mounted noexec (RT#47331) [David Golden]
+
- Fixed failing debug.t on VMS (RT#48362) [Craig Berry]
+
- Prevent par.t from dying on error in .zip extraction [David Golden]
+
- Fixed potential runthrough.t failure on 5.6.2 [David Golden]
Other:
+
- Archive::Tar changed from 'requires' to 'recommends' so non-authors
without IO::Zlib can still use Module::Build to install modules
[reported by Matt Trout, fix by David Golden]
@@ -46,22 +266,26 @@ Revision history for Perl extension Module::Build.
0.340201 - Sun Aug 9 22:11:04 EDT 2009
Other:
+
- Version bump for Perl core for 5.10.1 release; no other changes
0.34_02 - Sun Jul 26 22:50:40 EDT 2009
Bug-fixes:
+
- Bundled Module::Build::Version updated to bring into sync with CPAN
version.pm 0.77 [John Peacock]
0.34_01 - Sat Jul 18 16:32:09 EDT 2009
Enhancements:
+
- Added --debug flag to trace Build action execution (RT#47933)
[David Golden]
Bug-fixes:
- - Bundled Module::Build::Version version code updated to fix unsafe use
+
+ - Bundled Module::Build::Version version code updated to fix unsafe use
of $@ (RT#47980) [John Peacock]
0.34 - Tue Jul 7 16:56:47 EDT 2009
@@ -71,27 +295,33 @@ Revision history for Perl extension Module::Build.
0.33_06 - Sun Jul 5 10:11:40 EDT 2009
Bug-fixes:
+
- Bundled version code will use pure Perl on 5.10.0 to work around
a corner case involving eval and locale [John Peacock]
+
- Reversed VMS patch from 0.33_03 [Craig Berry]
+
- PL_files in Build.PL that are in the bin/scripts directory should not be
- installed as if they are scripts (fixed for case-tolerant systems).
+ installed as if they are scripts (fixed for case-tolerant systems).
[David Golden, reported by Craig Berry]
0.33_05 - Sun Jun 28 22:06:49 EDT 2009
Enhancements:
+
- New 'auto_configure_requires' parameter (default 1) controls
whether Module::Build should add itself to configure_requires
in META.yml if not specified in Build.PL [David Golden]
Bug-fixes:
+
- The default MANIFEST.SKIP created by the "manifest" action
was out of date. It will now use the installed MANIFEST.SKIP
and add some Module::Build and distribution specific items
to it. [Michael Schwern]
Other:
+
- configure_requires do not necessarily need to be in requires
or build_requires; warning to that effect has been removed
[David Golden]
@@ -99,99 +329,141 @@ Revision history for Perl extension Module::Build.
0.33_04 - Fri Jun 26 07:09:06 EDT 2009
Bug-fixes:
+
- Don't try utf8 YAML I/O on Perl 5.6 [David Golden]
Other:
+
- configure_requires added to prereq report (RT#47254) [Curtis Jewell]
+
- updated Module::Build::Version to match forthcoming version.pm 0.77
(RT#47256) [John Peacock]
+
- skips xs.t and ppm.t when perl was not compiled with dynamic loading
- since Module::Buld does not support static linking (RT#46178)
+ since Module::Buld does not support static linking (RT#46178)
[David Golden]
+
- skip failing test in par.t if Archive::Zip is broken [David Golden]
+
- Added YAML utf8 patch in 0.33_03 changes list
+
- Added attribution for patches in 0.33_03 changes list
0.33_03 - Mon Jun 22 17:22:56 EDT 2009
Bug-fixes:
- - Removes Module::Build from its own configure/build_requires
+
+ - Removes Module::Build from its own configure/build_requires
[David Golden]
+
- ConfigData->feature() confirms that modules actually load successfully,
not just that they are present. (RT#43557) [David Golden]
- - Module::Build::Compat handling of INSTALL*LIB (RT#43827)
+
+ - Module::Build::Compat handling of INSTALL*LIB (RT#43827)
[Tony Payne, David Golden]
+
- Module::Build::Compat and recursive test files (RT#39171) [Dave Rolsky]
+
- Fixed bug linking non-standard XS names on Windows (RT#38065) ["snaury"]
- - Run PL files that don't generate any file (RT#39365)
+
+ - Run PL files that don't generate any file (RT#39365)
[Matisse Enzer, David Golden]
+
- HTML generation failure no longer fatal (RT#36660) [David Golden]
- - realclean might not delete Build.bat on Windows (RT#43863)
+
+ - realclean might not delete Build.bat on Windows (RT#43863)
[Roy Ivy, David Golden]
+
- include_dirs parameter now works correctly when given a single
string argument (RT#40177) [David Wheeler]
+
- Lots of spelling fixes in the POD (RT#45528r) [Lars Dieckow]
+
- On Unix-like systems, tilde expansion is more liberal in username
characters accepted (RT#33492) [Jon Jensen]
Other
+
- On MSWin32, bumped File::Spec prereq to 3.30 for a variety of fixes
+
- Add support for VMS in Unix compatibility mode (RT#42157)
[John E. Malmberg
- - Added a can_action($name) method (RT#45172) [brian d foy]
+
+ - Added a can_action($name) method (RT#45172) [brian d foy]
+
- Documented that subclass methods should not permanently change
current directory (RT#46919) [David Wheeler]
+
- META.yml encoded in UTF-8 (RT#43765) [Olivier Mengue]
0.33_02 - Mon Jun 15 12:23:55 EDT 2009
Bug-fixes:
+
- Fixed tests for bleadperl
0.33_01 - Sat Jun 13 20:24:42 EDT 2009
Bug-fixes:
+
- Fixed RT#42724: consolidated VMS fixes [patch by Craig Berry]
+
- Fixed RT#46338: passthrough Makefile.PL cleans Makefile during distclean
+
- Fixed RT#45700: t/compat.t for HP/UX make
Other:
- - Adds current Module::Build to configure_requires (and build_requires)
+
+ - Adds current Module::Build to configure_requires (and build_requires)
if no configure_requires is specified
+
- Always normalizes version number tuples in META.yml (e.g. 'v1.2.0')
- (Partially addresses RT#46150)
- - Normalizes a generated dist_version (e.g. from a .pm file) --
+ (Partially addresses RT#46150)
+
+ - Normalizes a generated dist_version (e.g. from a .pm file) --
dist_version set manually in Build.PL is not normalized
+
- Documentation update for create_license
+
- Minor POD cleanup
0.33 - Sun May 3 20:16:34 PDT 2009
Bug-fixes:
+
- Fixed RT#45462: Compat.pm needs to reference 'Build.com' on VMS
[patch from John Malmberg]
+
- Fixed RT#45461: ext.t on VMS [patch from John Malmberg]
+
- Fixed RT#43861: Module::Build::PPMMaker has broken PPD name
versioning for v5.10+
0.32_01 - Tue Apr 14 17:14:22 PDT 2009
Bug-fixes:
+
- Module::Build::Compat had stopped adding "PL_FILES => {}" when no
PL_files property was set in Build.PL; restored old behavior and fixed
tests and documentation related to this issue [David Golden]
- - Caches ExtUtils::CBuilder object in a temporary stash instead of properties
+
+ - Caches ExtUtils::CBuilder object in a temporary stash instead of properties
+
- Fixed undef resources->license in META.yml (RT #44453).
+
- Use $^X instead of 'perl' in t/ext.t [David Golden] (RT #43485)
Other:
+
- Generated META.yml will indicate version 1.4 of the specification
(RT #37478) [patch from Alexandr Ciornii]
+
- Archive::Tar now the default for generating tarballs on all platforms
(avoids problems with incompatible tar binaries)
+
- dist_dir() now uses dist_name() and dist_version() accessors rather
than using its properties directly. [brian d foy] (RT #45038)
-
+
0.32 - Wed Feb 25 17:40:02 PST 2009
No changes since 0.31_04.
@@ -199,100 +471,129 @@ Revision history for Perl extension Module::Build.
0.31_04 - Fri Feb 20 11:04:59 PST 2009
Other
- - Bumped Test::Harness prereq to 3.16 for latest PERL5LIB fixes (solves
+
+- Bumped Test::Harness prereq to 3.16 for latest PERL5LIB fixes (solves
test failures when installing Module::Build using CPANPLUS::Dist::Build)
[David Golden]
0.31_03 - Sun Feb 8 14:54:01 PST 2009
Enhancements
+
- added a "prereq_data" action that prints a Perl data structure of
all prerequisites; can be loaded by external tools using eval()
[David Golden]
Bug-fixes
+
- 'fakeinstall' action warns and skips without ExtUtils::Install 1.32+
[David Golden, reported by Zefram]
+
- allows Module::Build version mismatch when installing self; works around
limitations in CPANPLUS::Dist::Build [David Golden]
0.31_02 - Tue Jan 27 09:16:43 PST 2009
Other
+
- tests now use File::Temp (added to build_requires); appears to fix
Win32 testing heisenbug on directory removal during high system loads
+
- use_tap_harness.t will skip unless a release version of TAP::Harness
is installed
+
- improved diagnostics to ensure_blib() tests in t/lib/MBTest.pm
Compat
+
- passthrough Makefile.PL will now play nice with cpantesters' on
exit(0) (RT#32018) [Eric Wilhelm]
Bug Fixes
+
- fix for doubling-up of --prefix (RT#19951)
0.31012 - Wed Jan 14 01:36:19 PST 2009
Bug Fixes
+
- t/tilde.t maybe actually fixed on MSWin32 now.
0.31011 - Mon Jan 12 21:57:04 PST 2009
Bug Fixes
+
- t/tilde.t had been failing on MSWin32 (RT#42349)
0.3101 - Mon Jan 12 13:52:36 PST 2009
Other
+
- added 'mirbsd' as a Unix-type OS [BinGOs]
+
- added 'haiku' as a Unix-type OS (backported from bleadperl)
+
- skips certain tests on VMS (backported from bleadperl)
+
- sets $^X to absolute path in tests (backported from bleadperl)
0.31 - Sat Dec 20 15:03:33 2008
Deprecations
+
- Use of attributes as class methods is deprecated (this was never a
documented feature and appears to only have worked accidentally.)
0.30_02 - Mon Dec 15 12:23:55 PST 2008
Bug Fixes
+
- make Software::License dependency "softer".
0.30_01 - Thu Dec 11 18:25:53 PST 2008
New Docs
+
- Added a recipe for writing a new action to the Cookbook
+
- Added a recipe for bundling Module::Build to the Cookbook.
Doc Fixes
+
- Clarified dist_abstract search procedure in API.pod (RT#41056) [Mario
Domgoergen]
Bug Fixes
+
- Workaround HARNESS_TIMER env issue in t/compat.t (RT#39635)
+
- Fix ~ expansion when $HOME is different from /etc/passwd as
when running sudo. [rt.cpan.org 39662]
+
- Fixed a small POD error in the Cookbook. [Damyan Ivanov]
+
- Unset group/other write permission bits when using Archive::Tar to
build the dist tarball. (RT#39804) [David Golden]
Enhancements
+
- We now support a 'create_license' parameter to new() that will
create a LICENSE file during the 'dist' phase with the full text of
the license. This requires Software::License on the author's
machine.
+
- Added lgpl2/lgpl3 entries to the supported licenses (RT#40532).
+
- Support for validating properties with a check subref. [David
Wheeler]
Test Fixes
+
- Defend against more stray environment variables interfering
with the tests.
Other
+
- Updated our embedded version.pm to 0.76, enhanced documentation on
dist_version_from. [John Peacock]
@@ -484,11 +785,11 @@ Revision history for Perl extension Module::Build.
have stopped, but it didn't. Fixed. [Matthew Cast and David
Golden]
- - Module::Build::Compat adds "require 5.XXXXX" to Makefile.PL when
+ - Module::Build::Compat adds "require 5.XXXXX" to Makefile.PL when
'perl' is specified as a 'requires' prerequisite [David Golden]
- - Refactored t/compat.t for modularity and transparency; added
- labels for all tests; supressed subprocess output to
+ - Refactored t/compat.t for modularity and transparency; added
+ labels for all tests; supressed subprocess output to
STDOUT and STDERR [David Golden]
- Fixed bug in perl_version_to_float when version is already a float
@@ -1015,7 +1316,7 @@ Revision history for Perl extension Module::Build.
- The synonyms 'scripts' and 'prereq' for 'script_files' and
'requires' were broken in a previous version (0.27_01, probably),
but now they're fixed. [David Golden]
-
+
- Previously, we assumed that any custom subclass of Module::Build
was located in _build/lib/. This is only true if the author used
the subclass() method, though. We now use %INC to find where the
@@ -2162,13 +2463,13 @@ Revision history for Perl extension Module::Build.
- Added experimental code to build a .ppd file, in support of
ActiveState's "Perl Package Manager". [original patch by Dave
Rolsky]
-
+
- For authors who use Module::Signature to sign their distributions,
we now create the SIGNATURE file right in the distribution
directory, rather than creating it in the top-level directory and
copying it into place. This solves problems related to having
files get out of date with respect to their signatures.
-
+
- We now don't depend on Module::Info to scan for packages during the
'dist' action anymore, because it's way too aggressive about
loading other modules that you may not want loaded. We now just
@@ -2231,12 +2532,12 @@ Revision history for Perl extension Module::Build.
- The distribution directory (e.g. Sample-Module-0.13/ ) will now be
deleted during the 'clean' or 'realclean' actions.
-
+
- During testing of modules, blib/lib and blib/arch are now added as
absolute paths, not relative. This helps tests that load the
modules at runtime and may change the current working directory
(like Module::Build itself does during testing).
-
+
- The $Config{cc} entry on some people's systems is something like
'ccache gcc', so we now split that string using split_like_shell().
[Richard Clamp]
@@ -2266,7 +2567,7 @@ Revision history for Perl extension Module::Build.
- When compiling C code, we now respect 'pollute' and 'inc'
parameters. (XXX - needs docs) [Dave Rolsky]
-
+
- Made the creation of the "install map" more generic. (XXX - needs
documentation)
@@ -2623,7 +2924,7 @@ Revision history for Perl extension Module::Build.
- Renamed module_name_to_file() to find_module_by_name(), and added
a parameter specifying the directories to search in. Previously
we searched in 'lib' and @INC, which wasn't correct in all
- situations.
+ situations.
- Patched the docs to change "Build test" to "./Build test"
[Elizabeth Mattijsen]
@@ -2817,7 +3118,7 @@ Revision history for Perl extension Module::Build.
- For the 'Build dist' action, we'll use the 'tar' and 'gzip'
programs (as specified by Config.pm) on Unix platforms, otherwise
we'll use Archive::Tar and Compress::Zlib.
-
+
0.02 Wed Sep 5 00:53:04 CDT 2001
- Added POD documentation.
diff --git a/cpan/Module-Build/lib/Module/Build.pm b/cpan/Module-Build/lib/Module/Build.pm
index be8c1f7079..efae7f9abb 100644
--- a/cpan/Module-Build/lib/Module/Build.pm
+++ b/cpan/Module-Build/lib/Module/Build.pm
@@ -15,7 +15,7 @@ use Module::Build::Base;
use vars qw($VERSION @ISA);
@ISA = qw(Module::Build::Base);
-$VERSION = '0.35';
+$VERSION = '0.35_08';
$VERSION = eval $VERSION;
# Okay, this is the brute-force method of finding out what kind of
@@ -167,24 +167,24 @@ This illustrates initial configuration and the running of three
'actions'. In this case the actions run are 'build' (the default
action), 'test', and 'install'. Other actions defined so far include:
- build manpages
- clean pardist
- code ppd
- config_data ppmdist
- diff prereq_data
- dist prereq_report
- distcheck pure_install
- distclean realclean
- distdir retest
- distmeta skipcheck
- distsign test
- disttest testall
- docs testcover
- fakeinstall testdb
- help testpod
- html testpodcoverage
- install versioninstall
- manifest
+ build manifest
+ clean manpages
+ code pardist
+ config_data ppd
+ diff ppmdist
+ dist prereq_data
+ distcheck prereq_report
+ distclean pure_install
+ distdir realclean
+ distmeta retest
+ distsign skipcheck
+ disttest test
+ docs testall
+ fakeinstall testcover
+ help testdb
+ html testpod
+ install testpodcoverage
+ installdeps versioninstall
You can run the 'help' action for a complete list of actions.
@@ -318,7 +318,7 @@ tarball of the files listed in F<MANIFEST> and compress the tarball using
GZIP compression.
By default, this action will use the C<Archive::Tar> module. However, you can
-force it to use binary "tar" and "gzip" executables by supplying an explicit
+force it to use binary "tar" and "gzip" executables by supplying an explicit
C<tar> (and optional C<gzip>) parameter:
./Build dist --tar C:\path\to\tar.exe --gzip C:\path\to\zip.exe
@@ -355,8 +355,8 @@ F<META.yml> is a file containing various bits of I<metadata> about the
distribution. The metadata includes the distribution name, version,
abstract, prerequisites, license, and various other data about the
distribution. This file is created as F<META.yml> in YAML format.
-It is recommended that the C<YAML> module be installed to create it.
-If the C<YAML> module is not installed, an internal module supplied
+It is recommended that the C<YAML::Tiny> module be installed to create it.
+If the C<YAML::Tiny> module is not installed, an internal module supplied
with Module::Build will be used to write the META.yml file, and this
will most likely be fine.
@@ -445,6 +445,24 @@ This can be a good idea, as it helps prevent multiple versions of a
module from being present on your system, which can be a confusing
situation indeed.
+=item installdeps
+
+[version 0.36]
+
+This action will use the C<cpan_client> parameter as a command to install
+missing prerequisites. You will be prompted whether to install
+optional dependencies.
+
+The C<cpan_client> option defaults to 'cpan' but can be set as an option or in
+F<.modulebuildrc>. It must be a shell command that takes a list of modules to
+install as arguments (e.g. 'cpanp -i' for CPANPLUS). If the program part is a
+relative path (e.g. 'cpan' or 'cpanp'), it will be located relative to the perl
+program that executed Build.PL.
+
+ /opt/perl/5.8.9/bin/perl Build.PL
+ ./Build installdeps --cpan_client 'cpanp -i'
+ # installs to 5.8.9
+
=item manifest
[version 0.05]
@@ -541,7 +559,7 @@ for a bug report.
[version 0.28]
This action is identical to the C<install> action. In the future,
-though, when C<install> starts writing to the file
+though, when C<install> starts writing to the file
F<$(INSTALLARCHLIB)/perllocal.pod>, C<pure_install> won't, and that
will be the only difference between them.
@@ -666,7 +684,7 @@ argument.
[version 0.25]
-This checks all the files described in the C<docs> action and
+This checks all the files described in the C<docs> action and
produces C<Test::Harness>-style output. If you are a module author,
this is useful to run before creating a new release.
@@ -674,7 +692,7 @@ this is useful to run before creating a new release.
[version 0.28]
-This checks the pod coverage of the distribution and
+This checks the pod coverage of the distribution and
produces C<Test::Harness>-style output. If you are a module author,
this is useful to run before creating a new release.
@@ -731,15 +749,20 @@ C<no> or C<no-> (e.g. C<--noverbose> or C<--no-verbose>).
Suppress informative messages on output.
+=item verbose
+
+Display extra information about the Build on output.
+
+=item cpan_client
+
+Sets the C<cpan_client> command for use with the C<installdeps> action.
+See C<installdeps> for more details.
+
=item use_rcfile
Load the F<~/.modulebuildrc> option file. This option can be set to
false to prevent the custom resource file from being loaded.
-=item verbose
-
-Display extra information about the Build on output.
-
=item allow_mb_mismatch
Suppresses the check upon startup that the version of Module::Build
@@ -754,7 +777,6 @@ executed build actions.
=back
-
=head2 Default Options File (F<.modulebuildrc>)
[version 0.28]
@@ -782,15 +804,35 @@ key C<*> (asterisk) denotes any global options that should be applied
to all actions, and the key 'Build_PL' specifies options to be applied
when you invoke C<perl Build.PL>.
- * verbose=1 # global options
- diff flags=-u
- install --install_base /home/ken
- --install_path html=/home/ken/docs/html
+ * verbose=1 # global options
+ diff flags=-u
+ install --install_base /home/ken
+ --install_path html=/home/ken/docs/html
+ installdeps --cpan_client 'cpanp -i'
If you wish to locate your resource file in a different location, you
can set the environment variable C<MODULEBUILDRC> to the complete
absolute path of the file containing your options.
+=head2 Environment variables
+
+=over
+
+=item MODULEBUILDRC
+
+[version 0.28]
+
+Specifies an alternate location for a default options file as described above.
+
+=item PERL_MB_OPT
+
+[version 0.36]
+
+Command line options that are applied to Build.PL or any Build action. The
+string is split as the shell would (e.g. whitespace) and the result is
+prepended to any actual command-line arguments.
+
+=back
=head1 INSTALL PATHS
@@ -1091,7 +1133,7 @@ modify it under the same terms as Perl itself.
=head1 SEE ALSO
perl(1), L<Module::Build::Cookbook>, L<Module::Build::Authoring>,
-L<Module::Build::API>, L<ExtUtils::MakeMaker>, L<YAML>
+L<Module::Build::API>, L<ExtUtils::MakeMaker>, L<YAML::Tiny>
F<META.yml> Specification:
L<http://module-build.sourceforge.net/META-spec-current.html>
diff --git a/cpan/Module-Build/lib/Module/Build/API.pod b/cpan/Module-Build/lib/Module/Build/API.pod
index f4e4cea09d..1f5d51f777 100644
--- a/cpan/Module-Build/lib/Module/Build/API.pod
+++ b/cpan/Module-Build/lib/Module/Build/API.pod
@@ -454,8 +454,13 @@ Specifies the licensing terms of your distribution. Valid options include:
=item apache
-The distribution is licensed under the Apache Software License
-(L<http://opensource.org/licenses/apachepl.php>).
+The distribution is licensed under the Apache License, Version 2.0
+(L<http://apache.org/licenses/LICENSE-2.0>).
+
+=item apache_1_1
+
+The distribution is licensed under the Apache Software License, Version 1.1
+(L<http://apache.org/licenses/LICENSE-1.1>).
=item artistic
@@ -580,6 +585,18 @@ used to set C<dist_version>.
Setting C<module_name> won't override a C<dist_*> parameter you
specify explicitly.
+=item needs_compiler
+
+[version 0.36]
+
+The C<needs_compiler> parameter indicates whether a compiler is required to
+build the distsribution. The default is false, unless XS files are found or
+the C<c_source> parameter is set, in which case it is true. If true,
+L<ExtUtils::CBuilder> is automatically added to C<build_requires> if needed.
+
+For a distribution where a compiler is I<optional>, e.g. a dual XS/pure-Perl
+distribution, C<needs_compiler> should explicitly be set to a false value.
+
=item PL_files
[version 0.06]
@@ -737,6 +754,35 @@ For backward compatibility, you may use the parameter C<scripts>
instead of C<script_files>. Please consider this usage deprecated,
though it will continue to exist for several version releases.
+=item share_dir
+
+[version 0.36]
+
+An optional parameter specifying directories of static data files to
+be installed as read-only files for use with L<File::ShareDir>. The
+C<share_dir> property supports both distribution-level and
+module-level share files.
+
+The default when C<share_dir> is not set is for any files in a F<share>
+directory at the top level of the distribution to be installed in
+distribution-level share directory. Alternatively, C<share_dir> can be set to
+a directory name or an arrayref of directory names containing files to be
+installed in the distribution-level share directory.
+
+If C<share_dir> is a hashref, it may have C<dist> or C<module> keys
+providing full flexibility in defining share directories to install.
+
+ share_dir => {
+ dist => [ 'examples', 'more_examples' ],
+ module => {
+ Foo::Templates => ['share/html', 'share/text'],
+ Foo::Config => 'share/config',
+ }
+ }
+
+If C<share_dir> is set (manually or automatically), then File::ShareDir
+will automatically be added to the C<requires> hash.
+
=item sign
[version 0.16]
@@ -802,25 +848,23 @@ files in your distribution.
[version 0.28]
-When called from a directory containing a F<Build.PL> script and a
-F<META.yml> file (in other words, the base directory of a
-distribution), this method will run the F<Build.PL> and return the
-resulting C<Module::Build> object to the caller. Any key-value
-arguments given to C<new_from_context()> are essentially like
-command line arguments given to the F<Build.PL> script, so for example
-you could pass C<< verbose => 1 >> to this method to turn on
-verbosity.
+When called from a directory containing a F<Build.PL> script (in other words,
+the base directory of a distribution), this method will run the F<Build.PL> and
+call C<resume()> to return the resulting C<Module::Build> object to the caller.
+Any key-value arguments given to C<new_from_context()> are essentially like
+command line arguments given to the F<Build.PL> script, so for example you
+could pass C<< verbose => 1 >> to this method to turn on verbosity.
=item resume()
[version 0.03]
-You'll probably never call this method directly, it's only called from
-the auto-generated C<Build> script. The C<new()> method is only
-called once, when the user runs C<perl Build.PL>. Thereafter, when
-the user runs C<Build test> or another action, the C<Module::Build>
-object is created using the C<resume()> method to re-instantiate with
-the settings given earlier to C<new()>.
+You'll probably never call this method directly, it's only called from the
+auto-generated C<Build> script (and the C<new_from_context> method). The
+C<new()> method is only called once, when the user runs C<perl Build.PL>.
+Thereafter, when the user runs C<Build test> or another action, the
+C<Module::Build> object is created using the C<resume()> method to
+re-instantiate with the settings given earlier to C<new()>.
=item subclass()
@@ -1527,22 +1571,25 @@ Assigning the value C<undef> to an element causes it to be removed.
=item prepare_metadata()
-[version 0.28]
+[version 0.36]
-This method is provided for authors to override to customize the
-fields of F<META.yml>. It is passed a YAML::Node node object which can
-be modified as desired and then returned. E.g.
+This method returns a hash reference of metadata that can be used to create a
+YAML datastream. It is provided for authors to override or customize the fields
+of F<META.yml>. E.g.
package My::Builder;
use base 'Module::Build';
sub prepare_metadata {
my $self = shift;
- my $node = $self->SUPER::prepare_metadata( shift );
- $node->{custom_field} = 'foo';
- return $node;
+ my $data = $self->SUPER::prepare_metadata();
+ $data->{custom_field} = 'foo';
+ return $data;
}
+Prior to version 0.36, this method took a YAML::Node as an argument to hold
+assembled metadata.
+
=item prereq_failures()
[version 0.11]
@@ -1782,6 +1829,10 @@ accessor methods for the following properties:
=item build_script()
+=item bundle_inc()
+
+=item bundle_inc_preload()
+
=item c_source()
=item config_dir()
@@ -1790,6 +1841,8 @@ accessor methods for the following properties:
=item conflicts()
+=item cpan_client()
+
=item create_license()
=item create_makefile_pl()
@@ -1830,6 +1883,10 @@ accessor methods for the following properties:
=item module_name()
+=item mymetafile()
+
+=item needs_compiler()
+
=item orig_dir()
=item perl()
@@ -1920,7 +1977,7 @@ modify it under the same terms as Perl itself.
=head1 SEE ALSO
perl(1), L<Module::Build>(3), L<Module::Build::Authoring>(3),
-L<Module::Build::Cookbook>(3), L<ExtUtils::MakeMaker>(3), L<YAML>(3)
+L<Module::Build::Cookbook>(3), L<ExtUtils::MakeMaker>(3), L<YAML::Tiny>(3)
F<META.yml> Specification:
L<http://module-build.sourceforge.net/META-spec-current.html>
diff --git a/cpan/Module-Build/lib/Module/Build/Base.pm b/cpan/Module-Build/lib/Module/Build/Base.pm
index 531c35487e..abeea2ef0a 100644
--- a/cpan/Module-Build/lib/Module/Build/Base.pm
+++ b/cpan/Module-Build/lib/Module/Build/Base.pm
@@ -4,7 +4,7 @@ package Module::Build::Base;
use strict;
use vars qw($VERSION);
-$VERSION = '0.35';
+$VERSION = '0.35_08';
$VERSION = eval $VERSION;
BEGIN { require 5.00503 }
@@ -23,6 +23,7 @@ use Text::ParseWords ();
use Module::Build::ModuleInfo;
use Module::Build::Notes;
use Module::Build::Config;
+use Module::Build::Version;
#################### Constructors ###########################
@@ -31,16 +32,37 @@ sub new {
$self->{invoked_action} = $self->{action} ||= 'Build_PL';
$self->cull_args(@ARGV);
-
+
die "Too early to specify a build action '$self->{action}'. Do 'Build $self->{action}' instead.\n"
if $self->{action} && $self->{action} ne 'Build_PL';
$self->check_manifest;
- $self->check_prereq;
- $self->check_autofeatures;
+ $self->auto_require;
+ if ( $self->check_prereq + $self->check_autofeatures != 2) {
+ $self->log_warn(<<EOF);
+
+ERRORS/WARNINGS FOUND IN PREREQUISITES. You may wish to install the versions
+of the modules indicated above before proceeding with this installation
+
+EOF
+ unless (
+ $self->dist_name eq 'Module-Build' ||
+ $ENV{PERL5_CPANPLUS_IS_RUNNING} || $ENV{PERL5_CPAN_IS_RUNNING}
+ ) {
+ $self->log_warn(
+ "Run 'Build installdeps' to install missing prerequisites.\n\n"
+ );
+ }
+ }
+
+ # record for later use in resume;
+ $self->{properties}{_added_to_INC} = [ $self->_added_to_INC ];
+
+ $self->set_bundle_inc;
$self->dist_name;
$self->dist_version;
+ $self->_guess_module_name unless $self->module_name;
$self->_find_nested_builds;
@@ -52,6 +74,8 @@ sub resume {
my $self = $package->_construct(@_);
$self->read_config;
+ unshift @INC, @{ $self->{properties}{_added_to_INC} || [] };
+
# If someone called Module::Build->current() or
# Module::Build->new_from_context() and the correct class to use is
# actually a *subclass* of Module::Build, we may need to load that
@@ -72,7 +96,7 @@ sub resume {
$self->log_warn(" * WARNING: Configuration was initially created with '$self->{properties}{perl}',\n".
" but we are now using '$perl'.\n");
}
-
+
$self->cull_args(@ARGV);
unless ($self->allow_mb_mismatch) {
@@ -82,7 +106,7 @@ sub resume {
" or use --allow_mb_mismatch 1 to skip this version check.\n")
if $mb_version ne $self->{properties}{mb_version};
}
-
+
$self->{invoked_action} = $self->{action} ||= 'build';
return $self;
@@ -90,18 +114,8 @@ sub resume {
sub new_from_context {
my ($package, %args) = @_;
-
- # XXX Read the META.yml and see whether we need to run the Build.PL?
-
- # Run the Build.PL. We use do() rather than run_perl_script() so
- # that it runs in this process rather than a subprocess, because we
- # need to make sure that the environment is the same during Build.PL
- # as it is during resume() (and thereafter).
- {
- local @ARGV = $package->unparse_args(\%args);
- do './Build.PL';
- die $@ if $@;
- }
+
+ $package->run_perl_script('Build.PL',[],[$package->unparse_args(\%args)]);
return $package->resume;
}
@@ -497,6 +511,28 @@ sub _discover_perl_interpreter {
"in (@paths)\n";
}
+# Adapted from IPC::Cmd::can_run()
+sub find_command {
+ my ($self, $command) = @_;
+
+ if( File::Spec->file_name_is_absolute($command) ) {
+ return $self->_maybe_command($command);
+
+ } else {
+ for my $dir ( File::Spec->path ) {
+ my $abs = File::Spec->catfile($dir, $command);
+ return $abs if $abs = $self->_maybe_command($abs);
+ }
+ }
+}
+
+# Copied from ExtUtils::MM_Unix::maybe_command
+sub _maybe_command {
+ my($self,$file) = @_;
+ return $file if -x $file && ! -d $file;
+ return;
+}
+
sub _is_interactive {
return -t STDIN && (-t STDOUT || !(-f STDOUT || -c STDOUT)) ; # Pipe?
}
@@ -588,10 +624,18 @@ sub features {
}
if (my $info = $ph->{auto_features}->access($key)) {
- my $failures = $self->prereq_failures($info);
- my $disabled = grep( /^(?:\w+_)?(?:requires|conflicts)$/,
- keys %$failures ) ? 1 : 0;
- return !$disabled;
+ my $disabled;
+ for my $type ( @{$self->prereq_action_types} ) {
+ next if $type eq 'description' || $type eq 'recommends' || ! exists $info->{$type};
+ my $prereqs = $info->{$type};
+ for my $modname ( sort keys %$prereqs ) {
+ my $spec = $prereqs->{$modname};
+ my $status = $self->check_installed_status($modname, $spec);
+ if ((!$status->{ok}) xor ($type =~ /conflicts$/)) { return 0; }
+ if ( ! eval "require $modname; 1" ) { return 0; }
+ }
+ }
+ return 1;
}
return $ph->{features}->access($key, @_);
@@ -614,7 +658,7 @@ BEGIN { *feature = \&features } # Alias
sub _mb_feature {
my $self = shift;
-
+
if (($self->module_name || '') eq 'Module::Build') {
# We're building Module::Build itself, so ...::ConfigData isn't
# valid, but $self->features() should be.
@@ -625,6 +669,15 @@ sub _mb_feature {
}
}
+sub _warn_mb_feature_deps {
+ my $self = shift;
+ my $name = shift;
+ $self->log_warn(
+ "The '$name' feature is not available. Please install missing\n" .
+ "feature dependencies and try again.\n".
+ $self->_feature_deps_msg($name) . "\n"
+ );
+}
sub add_build_element {
my ($self, $elem) = @_;
@@ -635,7 +688,7 @@ sub add_build_element {
sub ACTION_config_data {
my $self = shift;
return unless $self->has_config_data;
-
+
my $module_name = $self->module_name
or die "The config_data feature requires that 'module_name' be set";
my $notes_name = $module_name . '::ConfigData'; # TODO: Customize name ???
@@ -646,7 +699,7 @@ sub ACTION_config_data {
$self->config_file('features')
], $notes_pm);
- $self->log_info("Writing config notes to $notes_pm\n");
+ $self->log_verbose("Writing config notes to $notes_pm\n");
File::Path::mkpath(File::Basename::dirname($notes_pm));
Module::Build::Notes->write_config_data
@@ -661,7 +714,7 @@ sub ACTION_config_data {
}
########################################################################
-{ # enclosing these lexicals -- TODO
+{ # enclosing these lexicals -- TODO
my %valid_properties = ( __PACKAGE__, {} );
my %additive_properties;
@@ -681,10 +734,10 @@ sub ACTION_config_data {
sub valid_properties_defaults {
my %out;
- for (reverse shift->_mb_classes) {
- @out{ keys %{ $valid_properties{$_} } } = map {
+ for my $class (reverse shift->_mb_classes) {
+ @out{ keys %{ $valid_properties{$class} } } = map {
$_->()
- } values %{ $valid_properties{$_} };
+ } values %{ $valid_properties{$class} };
}
return \%out;
}
@@ -710,9 +763,11 @@ sub ACTION_config_data {
my %p = @_ == 1 ? ( default => shift ) : @_;
my $type = ref $p{default};
- $valid_properties{$class}{$property} = $type eq 'CODE'
- ? $p{default}
- : sub { $p{default} };
+ $valid_properties{$class}{$property} =
+ $type eq 'CODE' ? $p{default} :
+ $type eq 'HASH' ? sub { return { %{ $p{default} } } } :
+ $type eq 'ARRAY'? sub { return [ @{ $p{default} } ] } :
+ sub { return $p{default} } ;
push @{$additive_properties{$class}->{$type}}, $property
if $type;
@@ -831,12 +886,16 @@ sub _make_accessor {
__PACKAGE__->add_property(auto_configure_requires => 1);
__PACKAGE__->add_property(blib => 'blib');
__PACKAGE__->add_property(build_class => 'Module::Build');
-__PACKAGE__->add_property(build_elements => [qw(PL support pm xs pod script)]);
+__PACKAGE__->add_property(build_elements => [qw(PL support pm xs share_dir pod script)]);
__PACKAGE__->add_property(build_script => 'Build');
__PACKAGE__->add_property(build_bat => 0);
+__PACKAGE__->add_property(bundle_inc => []);
+__PACKAGE__->add_property(bundle_inc_preload => []);
__PACKAGE__->add_property(config_dir => '_build');
__PACKAGE__->add_property(include_dirs => []);
+__PACKAGE__->add_property(license => 'unknown');
__PACKAGE__->add_property(metafile => 'META.yml');
+__PACKAGE__->add_property(mymetafile => 'MYMETA.yml');
__PACKAGE__->add_property(recurse_into => []);
__PACKAGE__->add_property(use_rcfile => 1);
__PACKAGE__->add_property(create_packlist => 1);
@@ -844,6 +903,7 @@ __PACKAGE__->add_property(allow_mb_mismatch => 0);
__PACKAGE__->add_property(config => undef);
__PACKAGE__->add_property(test_file_exts => ['.t']);
__PACKAGE__->add_property(use_tap_harness => 0);
+__PACKAGE__->add_property(cpan_client => 'cpan');
__PACKAGE__->add_property(tap_harness_args => {});
__PACKAGE__->add_property(
'installdirs',
@@ -906,10 +966,10 @@ __PACKAGE__->add_property($_) for qw(
has_config_data
install_base
libdoc_dirs
- license
magic_number
mb_version
module_name
+ needs_compiler
orig_dir
perl
pm_files
@@ -921,6 +981,7 @@ __PACKAGE__->add_property($_) for qw(
recursive_test_files
script_files
scripts
+ share_dir
sign
test_files
verbose
@@ -993,14 +1054,14 @@ sub subclass {
$opts{code} ||= '';
$opts{class} ||= 'MyModuleBuilder';
-
+
my $filename = File::Spec->catfile($build_dir, 'lib', split '::', $opts{class}) . '.pm';
my $filedir = File::Basename::dirname($filename);
- $pack->log_info("Creating custom builder $filename in $filedir\n");
-
+ $pack->log_verbose("Creating custom builder $filename in $filedir\n");
+
File::Path::mkpath($filedir);
die "Can't create directory $filedir: $!" unless -d $filedir;
-
+
my $fh = IO::File->new("> $filename") or die "Can't create $filename: $!";
print $fh <<EOF;
package $opts{class};
@@ -1010,7 +1071,7 @@ $opts{code}
1;
EOF
close $fh;
-
+
unshift @INC, File::Spec->catdir(File::Spec->rel2abs($build_dir), 'lib');
eval "use $opts{class}";
die $@ if $@;
@@ -1018,16 +1079,43 @@ EOF
return $opts{class};
}
+sub _guess_module_name {
+ my $self = shift;
+ my $p = $self->{properties};
+ return if $p->{module_name};
+ if ( $p->{dist_version_from} && -e $p->{dist_version_from} ) {
+ my $mi = Module::Build::ModuleInfo->new_from_file($self->dist_version_from);
+ $p->{module_name} = $mi->name;
+ }
+ else {
+ my $mod_path = my $mod_name = File::Basename::basename($self->base_dir);
+ $mod_name =~ s{-}{::}g;
+ $mod_path =~ s{-}{/}g;
+ $mod_path .= ".pm";
+ if ( -e $mod_path || -e File::Spec->catfile('lib', $mod_path) ) {
+ $p->{module_name} = $mod_name;
+ }
+ else {
+ $self->log_warn( << 'END_WARN' );
+No 'module_name' was provided and it could not be inferred
+from other properties. This will prevent a packlist from
+being written for this file. Please set either 'module_name'
+or 'dist_version_from' in Build.PL.
+END_WARN
+ }
+ }
+}
+
sub dist_name {
my $self = shift;
my $p = $self->{properties};
return $p->{dist_name} if defined $p->{dist_name};
-
+
die "Can't determine distribution name, must supply either 'dist_name' or 'module_name' parameter"
unless $self->module_name;
-
+
($p->{dist_name} = $self->module_name) =~ s/::/-/g;
-
+
return $p->{dist_name};
}
@@ -1069,12 +1157,12 @@ sub _pod_parse {
my $p = $self->{properties};
my $member = "dist_$part";
return $p->{$member} if defined $p->{$member};
-
+
my $docfile = $self->_main_docfile
or return;
my $fh = IO::File->new($docfile)
or return;
-
+
require Module::Build::PodParser;
my $parser = Module::Build::PodParser->new(fh => $fh);
my $method = "get_$part";
@@ -1109,7 +1197,7 @@ sub config_file {
sub read_config {
my ($self) = @_;
-
+
my $file = $self->config_file('build_params')
or die "Can't find 'build_params' in " . $self->config_dir;
my $fh = IO::File->new($file) or die "Can't read '$file': $!";
@@ -1128,7 +1216,7 @@ sub has_config_data {
sub _write_data {
my ($self, $filename, $data) = @_;
-
+
my $file = $self->config_file($filename);
my $fh = IO::File->new("> $file") or die "Can't create '$file': $!";
unless (ref($data)) { # e.g. magicnum
@@ -1141,10 +1229,10 @@ sub _write_data {
sub write_config {
my ($self) = @_;
-
+
File::Path::mkpath($self->{properties}{config_dir});
-d $self->{properties}{config_dir} or die "Can't mkdir $self->{properties}{config_dir}: $!";
-
+
my @items = @{ $self->prereq_action_types };
$self->_write_data('prereqs', { map { $_, $self->$_() } @items });
$self->_write_data('build_params', [$self->{args}, $self->{config}->values_set, $self->{properties}]);
@@ -1155,13 +1243,74 @@ sub write_config {
$self->{phash}{$_}->write() foreach qw(notes cleanup features auto_features config_data runtime_params);
}
+{
+ # packfile map -- keys are guts of regular expressions; If they match,
+ # values are module names corresponding to the packlist
+ my %packlist_map = (
+ '^File::Spec' => 'Cwd',
+ '^Devel::AssertOS' => 'Devel::CheckOS',
+ );
+
+ sub _find_packlist {
+ my ($self, $inst, $mod) = @_;
+ my $lookup = $mod;
+ my $packlist = eval { $inst->packlist($lookup) };
+ if ( ! $packlist ) {
+ # try from packlist_map
+ while ( my ($re, $new_mod) = each %packlist_map ) {
+ if ( $mod =~ qr/$re/ ) {
+ $lookup = $new_mod;
+ $packlist = eval { $inst->packlist($lookup) };
+ last;
+ }
+ }
+ }
+ return $packlist ? $lookup : undef;
+ }
+
+ sub set_bundle_inc {
+ my $self = shift;
+
+ my $bundle_inc = $self->{properties}{bundle_inc};
+ my $bundle_inc_preload = $self->{properties}{bundle_inc_preload};
+ # We're in author mode if inc::latest is loaded, but not from cwd
+ return unless inc::latest->can('loaded_modules');
+ require ExtUtils::Installed;
+ # ExtUtils::Installed is buggy about finding additions to default @INC
+ my $inst = ExtUtils::Installed->new(extra_libs => [@INC]);
+ my @bundle_list = map { [ $_, 0 ] } inc::latest->loaded_modules;
+
+ # XXX TODO: Need to get ordering of prerequisites correct so they are
+ # are loaded in the right order. Use an actual tree?!
+
+ while( @bundle_list ) {
+ my ($mod, $prereq) = @{ shift @bundle_list };
+
+ # XXX TODO: Append prereqs to list
+ # skip if core or already in bundle or preload lists
+ # push @bundle_list, [$_, 1] for prereqs()
+
+ # Locate packlist for bundling
+ my $lookup = $self->_find_packlist($inst,$mod);
+ if ( ! $lookup ) {
+ # XXX Really needs a more helpful error message here
+ die << "NO_PACKLIST";
+Could not find a packlist for '$mod'. If it's a core module, try
+force installing it from CPAN.
+NO_PACKLIST
+ }
+ else {
+ push @{ $prereq ? $bundle_inc_preload : $bundle_inc }, $lookup;
+ }
+ }
+ } # sub check_bundling
+}
+
sub check_autofeatures {
my ($self) = @_;
my $features = $self->auto_features;
-
- return unless %$features;
- $self->log_info("Checking features:\n");
+ return 1 unless %$features;
# TODO refactor into ::Util
my $longest = sub {
@@ -1177,30 +1326,117 @@ sub check_autofeatures {
};
my $max_name_len = length($longest->(keys %$features));
- while (my ($name, $info) = each %$features) {
- $self->log_info(" $name" . '.' x ($max_name_len - length($name) + 4));
+ my ($num_disabled, $log_text) = (0, "\nChecking optional features...\n");
+ for my $name ( sort keys %$features ) {
+ $log_text .= $self->_feature_deps_msg($name, $max_name_len);
+ }
+
+ $num_disabled = () = $log_text =~ /disabled/g;
+
+ # warn user if features disabled
+ if ( $num_disabled ) {
+ $self->log_warn( $log_text );
+ return 0;
+ }
+ else {
+ $self->log_verbose( $log_text );
+ return 1;
+ }
+}
+
+sub _feature_deps_msg {
+ my ($self, $name, $max_name_len) = @_;
+ $max_name_len ||= length $name;
+ my $features = $self->auto_features;
+ my $info = $features->{$name};
+ my $feature_text = "$name" . '.' x ($max_name_len - length($name) + 4);
+ my ($log_text, $disabled) = ('','');
if ( my $failures = $self->prereq_failures($info) ) {
- my $disabled = grep( /^(?:\w+_)?(?:requires|conflicts)$/,
- keys %$failures ) ? 1 : 0;
- $self->log_info( $disabled ? "disabled\n" : "enabled\n" );
-
- my $log_text;
- while (my ($type, $prereqs) = each %$failures) {
- while (my ($module, $status) = each %$prereqs) {
- my $required =
- ($type =~ /^(?:\w+_)?(?:requires|conflicts)$/) ? 1 : 0;
- my $prefix = ($required) ? '-' : '*';
- $log_text .= " $prefix $status->{message}\n";
- }
+ $disabled = grep( /^(?:\w+_)?(?:requires|conflicts)$/,
+ keys %$failures ) ? 1 : 0;
+ $feature_text .= $disabled ? "disabled\n" : "enabled\n";
+
+ for my $type ( @{ $self->prereq_action_types } ) {
+ next unless exists $failures->{$type};
+ $feature_text .= " $type:\n";
+ my $prereqs = $failures->{$type};
+ for my $module ( sort keys %$prereqs ) {
+ my $status = $prereqs->{$module};
+ my $required =
+ ($type =~ /^(?:\w+_)?(?:requires|conflicts)$/) ? 1 : 0;
+ my $prefix = ($required) ? '!' : '*';
+ $feature_text .= " $prefix $status->{message}\n";
+ }
}
- $self->log_warn("$log_text") unless $self->quiet;
} else {
- $self->log_info("enabled\n");
+ $feature_text .= "enabled\n";
+ }
+ $log_text .= $feature_text if $disabled || $self->verbose;
+ return $log_text;
+}
+
+# Automatically detect and add prerequisites based on configuration
+sub auto_require {
+ my ($self) = @_;
+ my $p = $self->{properties};
+
+ # add current Module::Build to configure_requires if there
+ # isn't one already specified (but not ourself, so we're not circular)
+ if ( $self->dist_name ne 'Module-Build'
+ && $self->auto_configure_requires
+ && ! exists $p->{configure_requires}{'Module::Build'}
+ ) {
+ (my $ver = $VERSION) =~ s/^(\d+\.\d\d).*$/$1/; # last major release only
+ $self->_add_prereq('configure_requires', 'Module::Build', $ver);
+ }
+
+ # if we're in author mode, add inc::latest modules to
+ # configure_requires if not already set. If we're not in author mode
+ # then configure_requires will have been satisfied, or we'll just
+ # live with what we've bundled
+ if ( inc::latest->can('loaded_module') ) {
+ for my $mod ( inc::latest->loaded_modules ) {
+ next if exists $p->{configure_requires}{$mod};
+ $self->_add_prereq('configure_requires', $mod, $mod->VERSION);
}
}
- $self->log_warn("\n") unless $self->quiet;
+ # If needs_compiler is not explictly set, automatically set it
+ # If set, we need ExtUtils::CBuilder (and a compiler)
+ my $xs_files = $self->find_xs_files;
+ if ( ! defined $p->{needs_compiler} ) {
+ $self->needs_compiler( keys %$xs_files || defined $self->c_source );
+ }
+ if ($self->needs_compiler) {
+ $self->_add_prereq('build_requires', 'ExtUtils::CBuilder', 0);
+ if ( ! $self->have_c_compiler ) {
+ $self->log_warn(<<'EOM');
+Warning: ExtUtils::CBuilder not installed or no compiler detected
+Proceeding with configuration, but compilation may fail during Build
+
+EOM
+ }
+ }
+
+ # If using share_dir, require File::ShareDir
+ if ( $self->share_dir ) {
+ $self->_add_prereq( 'requires', 'File::ShareDir', '1.00' );
+ }
+
+ return;
+}
+
+sub _add_prereq {
+ my ($self, $type, $module, $version) = @_;
+ my $p = $self->{properties};
+ $version = 0 unless defined $version;
+ if ( exists $p->{$type}{$module} ) {
+ return if $self->compare_versions( $version, '<=', $p->{$type}{$module} );
+ }
+ $self->log_verbose("Adding to $type\: $module => $version\n");
+ $p->{$type}{$module} = $version;
+ return 1;
}
sub prereq_failures {
@@ -1213,7 +1449,8 @@ sub prereq_failures {
foreach my $type (@types) {
my $prereqs = $info->{$type};
- while ( my ($modname, $spec) = each %$prereqs ) {
+ for my $modname ( keys %$prereqs ) {
+ my $spec = $prereqs->{$modname};
my $status = $self->check_installed_status($modname, $spec);
if ($type =~ /^(?:\w+_)?conflicts$/) {
@@ -1224,7 +1461,7 @@ sub prereq_failures {
} elsif ($type =~ /^(?:\w+_)?recommends$/) {
next if $status->{ok};
$status->{message} = (!ref($status->{have}) && $status->{have} eq '<none>'
- ? "Optional prerequisite $modname is not installed"
+ ? "$modname is not installed"
: "$modname ($status->{have}) is installed, but we prefer to have $spec");
} else {
next if $status->{ok};
@@ -1253,44 +1490,29 @@ sub _enum_prereqs {
sub check_prereq {
my $self = shift;
- # If we have XS files, make sure we can process them.
- my $xs_files = $self->find_xs_files;
- if (keys %$xs_files && !$self->_mb_feature('C_support')) {
- $self->log_warn("Warning: this distribution contains XS files, ".
- "but Module::Build is not configured with C_support. ".
- "Please install ExtUtils::CBuilder to enable C_support.\n");
- }
-
# Check to see if there are any prereqs to check
my $info = $self->_enum_prereqs;
return 1 unless $info;
- $self->log_info("Checking prerequisites...\n");
+ my $log_text = "Checking prerequisites...\n";
my $failures = $self->prereq_failures($info);
if ( $failures ) {
-
- while (my ($type, $prereqs) = each %$failures) {
- while (my ($module, $status) = each %$prereqs) {
- my $prefix = ($type =~ /^(?:\w+_)?recommends$/) ? '*' : '- ERROR:';
- $self->log_warn(" $prefix $status->{message}\n");
+ $self->log_warn($log_text);
+ for my $type ( @{ $self->prereq_action_types } ) {
+ my $prereqs = $failures->{$type};
+ $self->log_warn(" ${type}:\n") if keys %$prereqs;
+ for my $module ( sort keys %$prereqs ) {
+ my $status = $prereqs->{$module};
+ my $prefix = ($type =~ /^(?:\w+_)?recommends$/) ? "* " : "! ";
+ $self->log_warn(" $prefix $status->{message}\n");
}
}
-
- $self->log_warn(<<EOF);
-
-ERRORS/WARNINGS FOUND IN PREREQUISITES. You may wish to install the versions
-of the modules indicated above before proceeding with this installation
-
-EOF
return 0;
-
} else {
-
- $self->log_info("Looks good\n\n");
+ $self->log_verbose($log_text . "Looks good\n\n");
return 1;
-
}
}
@@ -1323,44 +1545,44 @@ sub _parse_conditions {
sub check_installed_status {
my ($self, $modname, $spec) = @_;
my %status = (need => $spec);
-
+
if ($modname eq 'perl') {
$status{have} = $self->perl_version;
-
+
} elsif (eval { no strict; $status{have} = ${"${modname}::VERSION"} }) {
# Don't try to load if it's already loaded
-
+
} else {
my $pm_info = Module::Build::ModuleInfo->new_from_module( $modname );
unless (defined( $pm_info )) {
@status{ qw(have message) } = ('<none>', "$modname is not installed");
return \%status;
}
-
+
$status{have} = $pm_info->version();
if ($spec and !defined($status{have})) {
@status{ qw(have message) } = (undef, "Couldn't find a \$VERSION in prerequisite $modname");
return \%status;
}
}
-
+
my @conditions = $self->_parse_conditions($spec);
-
+
foreach (@conditions) {
my ($op, $version) = /^\s* (<=?|>=?|==|!=) \s* ([\w.]+) \s*$/x
or die "Invalid prerequisite condition '$_' for $modname";
-
+
$version = $self->perl_version_to_float($version)
if $modname eq 'perl';
-
+
next if $op eq '>=' and !$version; # Module doesn't have to actually define a $VERSION
-
+
unless ($self->compare_versions( $status{have}, $op, $version )) {
$status{message} = "$modname ($status{have}) is installed, but we need version $op $version";
return \%status;
}
}
-
+
$status{ok} = 1;
return \%status;
}
@@ -1368,7 +1590,7 @@ sub check_installed_status {
sub compare_versions {
my $self = shift;
my ($v1, $op, $v2) = @_;
- $v1 = Module::Build::Version->new($v1)
+ $v1 = Module::Build::Version->new($v1)
unless UNIVERSAL::isa($v1,'Module::Build::Version');
my $eval_str = "\$v1 $op \$v2";
@@ -1381,14 +1603,14 @@ sub compare_versions {
# I wish I could set $! to a string, but I can't, so I use $@
sub check_installed_version {
my ($self, $modname, $spec) = @_;
-
+
my $status = $self->check_installed_status($modname, $spec);
-
+
if ($status->{ok}) {
return $status->{have} if $status->{have} and "$status->{have}" ne '<none>';
return '0 but true';
}
-
+
$@ = $status->{message};
return 0;
}
@@ -1430,23 +1652,23 @@ sub _added_to_INC {
sub _default_INC {
my $self = shift;
return @default_inc if @default_inc;
-
+
local $ENV{PERL5LIB}; # this is not considered part of the default.
-
+
my $perl = ref($self) ? $self->perl : $self->find_perl_interpreter;
-
+
my @inc = $self->_backticks($perl, '-le', 'print for @INC');
chomp @inc;
-
+
return @default_inc = @inc;
}
}
sub print_build_script {
my ($self, $fh) = @_;
-
+
my $build_package = $self->build_class;
-
+
my $closedata="";
my %q = map {$_, $self->$_()} qw(config_dir base_dir);
@@ -1532,20 +1754,29 @@ EOF
sub create_build_script {
my ($self) = @_;
$self->write_config;
-
+
+ # Create MYMETA.yml
+ my $mymetafile = $self->mymetafile;
+ if ( $self->delete_filetree($mymetafile) ) {
+ $self->log_verbose("Removed previous '$mymetafile'\n");
+ }
+ $self->log_info("Creating new '$mymetafile' with configuration results\n");
+ $self->write_metafile( $mymetafile, $self->prepare_metadata( fatal => 0 ) );
+
+ # Create Build
my ($build_script, $dist_name, $dist_version)
= map $self->$_(), qw(build_script dist_name dist_version);
-
+
if ( $self->delete_filetree($build_script) ) {
- $self->log_info("Removed previous script '$build_script'\n\n");
+ $self->log_verbose("Removed previous script '$build_script'\n");
}
$self->log_info("Creating new '$build_script' script for ",
- "'$dist_name' version '$dist_version'\n");
+ "'$dist_name' version '$dist_version'\n");
my $fh = IO::File->new(">$build_script") or die "Can't create '$build_script': $!";
$self->print_build_script($fh);
close $fh;
-
+
$self->make_executable($build_script);
return 1;
@@ -1554,20 +1785,20 @@ sub create_build_script {
sub check_manifest {
my $self = shift;
return unless -e 'MANIFEST';
-
+
# Stolen nearly verbatim from MakeMaker. But ExtUtils::Manifest
# could easily be re-written into a modern Perl dialect.
require ExtUtils::Manifest; # ExtUtils::Manifest is not warnings clean.
local ($^W, $ExtUtils::Manifest::Quiet) = (0,1);
-
- $self->log_info("Checking whether your kit is complete...\n");
+
+ $self->log_verbose("Checking whether your kit is complete...\n");
if (my @missed = ExtUtils::Manifest::manicheck()) {
$self->log_warn("WARNING: the following files are missing in your kit:\n",
"\t", join("\n\t", @missed), "\n",
"Please inform the author.\n\n");
} else {
- $self->log_info("Looks good\n\n");
+ $self->log_verbose("Looks good\n\n");
}
}
@@ -1692,6 +1923,7 @@ sub _translate_option {
use_rcfile
use_tap_harness
tap_harness_args
+ cpan_client
); # normalize only selected option names
return $opt;
@@ -1824,7 +2056,7 @@ sub read_args {
require Module::Build::Compat;
%args = (%args, Module::Build::Compat->makefile_to_build_macros);
}
-
+
return \%args, $action;
}
@@ -1977,7 +2209,10 @@ sub merge_args {
sub cull_args {
my $self = shift;
- my ($args, $action) = $self->read_args(@_);
+ my @arg_list = @_;
+ unshift @arg_list, $self->split_like_shell($ENV{PERL_MB_OPT})
+ if $ENV{PERL_MB_OPT};
+ my ($args, $action) = $self->read_args(@arg_list);
$self->merge_args($action, %$args);
$self->merge_modulebuildrc( $action, %$args );
}
@@ -1986,7 +2221,7 @@ sub super_classes {
my ($self, $class, $seen) = @_;
$class ||= ref($self) || $self;
$seen ||= {};
-
+
no strict 'refs';
my @super = grep {not $seen->{$_}++} $class, @{ $class . '::ISA' };
return @super, map {$self->super_classes($_,$seen)} @super;
@@ -1997,7 +2232,7 @@ sub known_actions {
my %actions;
no strict 'refs';
-
+
foreach my $class ($self->super_classes) {
foreach ( keys %{ $class . '::' } ) {
$actions{$1}++ if /^ACTION_(\w+)/;
@@ -2073,7 +2308,7 @@ sub get_action_docs {
$@ = "Couldn't find any docs for action '$action'";
return;
}
-
+
return join '', @docs;
}
@@ -2147,7 +2382,7 @@ sub prereq_report {
sub ACTION_help {
my ($self) = @_;
my $actions = $self->known_actions;
-
+
if (@{$self->{args}{ARGV}}) {
my $msg = eval {$self->get_action_docs($self->{args}{ARGV}[0], $actions)};
print $@ ? "$@\n" : $msg;
@@ -2158,10 +2393,10 @@ sub ACTION_help {
Usage: $0 <action> arg1=value arg2=value ...
Example: $0 test verbose=1
-
+
Actions defined:
EOF
-
+
print $self->_action_listing($actions);
print "\nRun `Build help <action>` for details on an individual action.\n";
@@ -2174,7 +2409,7 @@ sub _action_listing {
# Flow down columns, not across rows
my @actions = sort keys %$actions;
@actions = map $actions[($_ + ($_ % 2) * @actions) / 2], 0..$#actions;
-
+
my $out = '';
while (my ($one, $two) = splice @actions, 0, 2) {
$out .= sprintf(" %-12s %-12s\n", $one, $two||'');
@@ -2184,7 +2419,7 @@ sub _action_listing {
sub ACTION_retest {
my ($self) = @_;
-
+
# Protect others against our @INC changes
local @INC = @INC;
@@ -2232,7 +2467,7 @@ sub generic_test {
my $p = $self->{properties};
my @types = (
- (exists($args{type}) ? $args{type} : ()),
+ (exists($args{type}) ? $args{type} : ()),
(exists($args{types}) ? @{$args{types}} : ()),
);
@types or croak "need some types of tests to check";
@@ -2265,6 +2500,8 @@ sub generic_test {
$self->do_tests;
}
+# Test::Harness dies on failure but TAP::Harness does not, so we must
+# die if running under TAP::Harness
sub do_tests {
my $self = shift;
@@ -2273,7 +2510,10 @@ sub do_tests {
if(@$tests) {
my $args = $self->tap_harness_args;
if($self->use_tap_harness or ($args and %$args)) {
- $self->run_tap_harness($tests);
+ my $aggregate = $self->run_tap_harness($tests);
+ if ( $aggregate->has_errors ) {
+ die "Errors in testing. Cannot continue.\n";
+ }
}
else {
$self->run_test_harness($tests);
@@ -2293,12 +2533,14 @@ sub run_tap_harness {
# TODO allow the test @INC to be set via our API?
- TAP::Harness->new({
+ my $aggregate = TAP::Harness->new({
lib => [@INC],
verbosity => $self->{properties}{verbose},
switches => [ $self->harness_switches ],
%{ $self->tap_harness_args },
})->runtests(@$tests);
+
+ return $aggregate;
}
sub run_test_harness {
@@ -2382,14 +2624,14 @@ sub ACTION_testcover {
my $pm_files = $self->rscan_dir
(File::Spec->catdir($self->blib, 'lib'), file_qr('\.pm$') );
my $cover_files = $self->rscan_dir('cover_db', sub {-f $_ and not /\.html$/});
-
+
$self->do_system(qw(cover -delete))
unless $self->up_to_date($pm_files, $cover_files)
&& $self->up_to_date($self->test_files, $cover_files);
}
- local $Test::Harness::switches =
- local $Test::Harness::Switches =
+ local $Test::Harness::switches =
+ local $Test::Harness::Switches =
local $ENV{HARNESS_PERL_SWITCHES} = "-MDevel::Cover";
$self->depends_on('test');
@@ -2398,17 +2640,17 @@ sub ACTION_testcover {
sub ACTION_code {
my ($self) = @_;
-
+
# All installable stuff gets created in blib/ .
# Create blib/arch to keep blib.pm happy
my $blib = $self->blib;
$self->add_to_cleanup($blib);
File::Path::mkpath( File::Spec->catdir($blib, 'arch') );
-
+
if (my $split = $self->autosplit) {
$self->autosplit_file($_, $blib) for ref($split) ? @$split : ($split);
}
-
+
foreach my $element (@{$self->build_elements}) {
my $method = "process_${element}_files";
$method = "process_files_by_extension" unless $self->can($method);
@@ -2420,16 +2662,17 @@ sub ACTION_code {
sub ACTION_build {
my $self = shift;
+ $self->log_info("Building " . $self->dist_name . "\n");
$self->depends_on('code');
$self->depends_on('docs');
}
sub process_files_by_extension {
my ($self, $ext) = @_;
-
+
my $method = "find_${ext}_files";
my $files = $self->can($method) ? $self->$method() : $self->_find_file_by_type($ext, 'lib');
-
+
while (my ($file, $dest) = each %$files) {
$self->copy_if_modified(from => $file, to => File::Spec->catfile($self->blib, $dest) );
}
@@ -2439,19 +2682,70 @@ sub process_support_files {
my $self = shift;
my $p = $self->{properties};
return unless $p->{c_source};
-
+
push @{$p->{include_dirs}}, $p->{c_source};
-
- my $files = $self->rscan_dir($p->{c_source}, file_qr('\.c(pp)?$'));
+
+ my $files = $self->rscan_dir($p->{c_source}, file_qr('\.c(c|p|pp|xx|\+\+)?$'));
foreach my $file (@$files) {
push @{$p->{objects}}, $self->compile_c($file);
}
}
+sub process_share_dir_files {
+ my $self = shift;
+ my $files = $self->_find_share_dir_files;
+ return unless $files;
+
+ # root for all File::ShareDir paths
+ my $share_prefix = File::Spec->catdir($self->blib, qw/lib auto share/);
+
+ # copy all share files to blib
+ while (my ($file, $dest) = each %$files) {
+ $self->copy_if_modified(
+ from => $file, to => File::Spec->catfile( $share_prefix, $dest )
+ );
+ }
+}
+
+sub _find_share_dir_files {
+ my $self = shift;
+ my $share_dir = $self->share_dir;
+ return unless $share_dir;
+
+ my @file_map;
+ if ( $share_dir->{dist} ) {
+ my $prefix = File::Spec->catdir( "dist", $self->dist_name );
+ push @file_map, $self->_share_dir_map( $prefix, $share_dir->{dist} );
+ }
+
+ if ( $share_dir->{module} ) {
+ for my $mod ( keys %{ $share_dir->{module} } ) {
+ (my $altmod = $mod) =~ s{::}{-}g;
+ my $prefix = File::Spec->catdir("module", $altmod);
+ push @file_map, $self->_share_dir_map($prefix, $share_dir->{module}{$mod});
+ }
+ }
+
+ return { @file_map };
+}
+
+sub _share_dir_map {
+ my ($self, $prefix, $list) = @_;
+ my %files;
+ for my $dir ( @$list ) {
+ for my $f ( @{ $self->rscan_dir( $dir, sub {-f} )} ) {
+ $files{File::Spec->canonpath($f)} = File::Spec->catfile(
+ $prefix, File::Spec->abs2rel( $f, $dir )
+ );
+ }
+ }
+ return %files;
+}
+
sub process_PL_files {
my ($self) = @_;
my $files = $self->find_PL_files;
-
+
while (my ($file, $to) = each %$files) {
unless ($self->up_to_date( $file, $to )) {
$self->run_perl_script($file, [], [@$to]) or die "$file failed";
@@ -2482,7 +2776,7 @@ sub process_script_files {
my $script_dir = File::Spec->catdir($self->blib, 'script');
File::Path::mkpath( $script_dir );
-
+
foreach my $file (keys %$files) {
my $result = $self->copy_if_modified($file, $script_dir, 'flatten') or next;
$self->fix_shebang_line($result) unless $self->is_vmsish;
@@ -2494,7 +2788,7 @@ sub find_PL_files {
my $self = shift;
if (my $files = $self->{properties}{PL_files}) {
# 'PL_files' is given as a Unix file spec, so we localize_file_path().
-
+
if (UNIVERSAL::isa($files, 'ARRAY')) {
return { map {$_, [/^(.*)\.PL$/]}
map $self->localize_file_path($_),
@@ -2512,7 +2806,7 @@ sub find_PL_files {
die "'PL_files' must be a hash reference or array reference";
}
}
-
+
return unless -d 'lib';
return { map {$_, [/^(.*)\.PL$/i ]} @{ $self->rscan_dir('lib',
file_qr('\.PL$')) } };
@@ -2529,7 +2823,7 @@ sub find_script_files {
# meaningless, but we preserve if present.
return { map {$self->localize_file_path($_), $files->{$_}} keys %$files };
}
-
+
# No default location for script files
return {};
}
@@ -2543,10 +2837,10 @@ sub find_test_files {
$files = [map { -d $_ ? $self->expand_test_dir($_) : $_ }
map glob,
$self->split_like_shell($files)];
-
+
# Always given as a Unix file spec.
return [ map $self->localize_file_path($_), @$files ];
-
+
} else {
# Find all possible tests in t/ or test.pl
my @tests;
@@ -2558,12 +2852,12 @@ sub find_test_files {
sub _find_file_by_type {
my ($self, $type, $dir) = @_;
-
+
if (my $files = $self->{properties}{"${type}_files"}) {
# Always given as a Unix file spec
return { map $self->localize_file_path($_), %$files };
}
-
+
return {} unless -d $dir;
return { map {$_, $_}
map $self->localize_file_path($_),
@@ -2584,48 +2878,48 @@ sub localize_dir_path {
sub fix_shebang_line { # Adapted from fixin() in ExtUtils::MM_Unix 1.35
my ($self, @files) = @_;
my $c = ref($self) ? $self->{config} : 'Module::Build::Config';
-
+
my ($does_shbang) = $c->get('sharpbang') =~ /^\s*\#\!/;
for my $file (@files) {
my $FIXIN = IO::File->new($file) or die "Can't process '$file': $!";
local $/ = "\n";
chomp(my $line = <$FIXIN>);
next unless $line =~ s/^\s*\#!\s*//; # Not a shbang file.
-
+
my ($cmd, $arg) = (split(' ', $line, 2), '');
next unless $cmd =~ /perl/i;
my $interpreter = $self->{properties}{perl};
-
+
$self->log_verbose("Changing sharpbang in $file to $interpreter");
my $shb = '';
$shb .= $c->get('sharpbang')."$interpreter $arg\n" if $does_shbang;
-
+
# I'm not smart enough to know the ramifications of changing the
# embedded newlines here to \n, so I leave 'em in.
$shb .= qq{
eval 'exec $interpreter $arg -S \$0 \${1+"\$\@"}'
if 0; # not running under some shell
} unless $self->is_windowsish; # this won't work on win32, so don't
-
+
my $FIXOUT = IO::File->new(">$file.new")
or die "Can't create new $file: $!\n";
-
+
# Print out the new #! line (or equivalent).
local $\;
undef $/; # Was localized above
print $FIXOUT $shb, <$FIXIN>;
close $FIXIN;
close $FIXOUT;
-
+
rename($file, "$file.bak")
or die "Can't rename $file to $file.bak: $!";
-
+
rename("$file.new", $file)
or die "Can't rename $file.new to $file: $!";
-
+
$self->delete_filetree("$file.bak")
or $self->log_warn("Couldn't clean up $file.bak, leaving it there");
-
+
$self->do_system($c->get('eunicefix'), $file) if $c->get('eunicefix') ne ':';
}
}
@@ -2634,7 +2928,7 @@ eval 'exec $interpreter $arg -S \$0 \${1+"\$\@"}'
sub ACTION_testpod {
my $self = shift;
$self->depends_on('docs');
-
+
eval q{use Test::Pod 0.95; 1}
or die "The 'testpod' action requires Test::Pod version 0.95";
@@ -2655,7 +2949,7 @@ sub ACTION_testpodcoverage {
my $self = shift;
$self->depends_on('docs');
-
+
eval q{use Test::Pod::Coverage 1.00; 1}
or die "The 'testpodcoverage' action requires ",
"Test::Pod::Coverage version 1.00";
@@ -2738,9 +3032,9 @@ sub manify_bin_pods {
$self->config( 'man1ext' );
my $outfile = File::Spec->catfile($mandir, $manpage);
next if $self->up_to_date( $file, $outfile );
- $self->log_info("Manifying $file -> $outfile\n");
+ $self->log_verbose("Manifying $file -> $outfile\n");
eval { $parser->parse_from_file( $file, $outfile ); 1 }
- or $self->log_warn("Error creating '$outfile': $@\n");
+ or $self->log_warn("Error creating '$outfile': $@\n");
$files->{$file} = $outfile;
}
}
@@ -2763,9 +3057,9 @@ sub manify_lib_pods {
$self->config( 'man3ext' );
my $outfile = File::Spec->catfile( $mandir, $manpage);
next if $self->up_to_date( $file, $outfile );
- $self->log_info("Manifying $file -> $outfile\n");
+ $self->log_verbose("Manifying $file -> $outfile\n");
eval { $parser->parse_from_file( $file, $outfile ); 1 }
- or $self->log_warn("Error creating '$outfile': $@\n");
+ or $self->log_warn("Error creating '$outfile': $@\n");
$files->{$file} = $outfile;
}
}
@@ -2790,12 +3084,12 @@ sub _find_pods {
sub contains_pod {
my ($self, $file) = @_;
return '' unless -T $file; # Only look at text files
-
+
my $fh = IO::File->new( $file ) or die "Can't open $file: $!";
while (my $line = <$fh>) {
return 1 if $line =~ /^\=(?:head|pod|item)/;
}
-
+
return '';
}
@@ -2808,7 +3102,7 @@ sub ACTION_html {
foreach my $type ( qw(bin lib) ) {
my $files = $self->_find_pods( $self->{properties}{"${type}doc_dirs"},
- exclude =>
+ exclude =>
[ file_qr('\.(?:bat|com|html)$') ] );
next unless %$files;
@@ -2897,9 +3191,9 @@ sub htmlify_pods {
push( @opts, "--css=$path2root/" . $self->html_css) if $self->html_css;
}
- $self->log_info("HTMLifying $infile -> $outfile\n");
+ $self->log_verbose("HTMLifying $infile -> $outfile\n");
$self->log_verbose("pod2html @opts\n");
- eval { Pod::Html::pod2html(@opts); 1 }
+ eval { Pod::Html::pod2html(@opts); 1 }
or $self->log_warn("pod2html @opts failed: $@");
}
@@ -2919,10 +3213,10 @@ sub man3page_name {
my $self = shift;
my ($vol, $dirs, $file) = File::Spec->splitpath( shift );
my @dirs = File::Spec->splitdir( File::Spec->canonpath($dirs) );
-
+
# Remove known exts from the base name
$file =~ s/\.p(?:od|m|l)\z//i;
-
+
return join( $self->manpage_separator, @dirs, $file );
}
@@ -2942,7 +3236,7 @@ sub ACTION_diff {
my @flags = @{$self->{args}{ARGV}};
@flags = $self->split_like_shell($self->{args}{flags} || '') unless @flags;
-
+
my $installmap = $self->install_map;
delete $installmap->{read};
delete $installmap->{write};
@@ -2952,22 +3246,22 @@ sub ACTION_diff {
while (my $localdir = each %$installmap) {
my @localparts = File::Spec->splitdir($localdir);
my $files = $self->rscan_dir($localdir, sub {-f});
-
+
foreach my $file (@$files) {
my @parts = File::Spec->splitdir($file);
@parts = @parts[@localparts .. $#parts]; # Get rid of blib/lib or similar
-
+
my $installed = Module::Build::ModuleInfo->find_module_by_name(
join('::', @parts), \@myINC );
if (not $installed) {
print "Only in lib: $file\n";
next;
}
-
+
my $status = File::Compare::compare($installed, $file);
next if $status == 0; # Files are the same
die "Can't compare $installed and $file: $!" if $status == -1;
-
+
if ($file =~ $text_suffix) {
$self->do_system('diff', @flags, $installed, $file);
} else {
@@ -2985,7 +3279,7 @@ sub ACTION_install {
my ($self) = @_;
require ExtUtils::Install;
$self->depends_on('build');
- ExtUtils::Install::install($self->install_map, !$self->quiet, 0, $self->{args}{uninst}||0);
+ ExtUtils::Install::install($self->install_map, $self->verbose, 0, $self->{args}{uninst}||0);
}
sub ACTION_fakeinstall {
@@ -3005,19 +3299,74 @@ sub ACTION_fakeinstall {
sub ACTION_versioninstall {
my ($self) = @_;
-
+
die "You must have only.pm 0.25 or greater installed for this operation: $@\n"
unless eval { require only; 'only'->VERSION(0.25); 1 };
-
+
$self->depends_on('build');
-
+
my %onlyargs = map {exists($self->{args}{$_}) ? ($_ => $self->{args}{$_}) : ()}
qw(version versionlib);
only::install::install(%onlyargs);
}
+sub ACTION_installdeps {
+ my ($self) = @_;
+
+ # XXX include feature prerequisites as optional prereqs?
+
+ my $info = $self->_enum_prereqs;
+ if (! $info ) {
+ $self->log_info( "No prerequisites detected\n" );
+ return;
+ }
+
+ my $failures = $self->prereq_failures($info);
+ if ( ! $failures ) {
+ $self->log_info( "All prerequisites satisfied\n" );
+ return;
+ }
+
+ my @install;
+ while (my ($type, $prereqs) = each %$failures) {
+ if($type =~ m/^(?:\w+_)?requires$/) {
+ push(@install, keys %$prereqs);
+ next;
+ }
+ $self->log_info("Checking optional dependencies:\n");
+ while (my ($module, $status) = each %$prereqs) {
+ push(@install, $module) if($self->y_n("Install $module?", 'y'));
+ }
+ }
+
+ return unless @install;
+
+ my ($command, @opts) = $self->split_like_shell($self->cpan_client);
+
+ # relative command should be relative to our active Perl
+ # so we need to locate that command
+ if ( ! File::Spec->file_name_is_absolute( $command ) ) {
+ my @bindirs = File::Basename::dirname($self->perl);
+ push @bindirs, map {$self->config->{"install${_}bin"}} '','site','vendor';
+ for my $d ( @bindirs ) {
+ my $abs_cmd = $self->find_command(File::Spec->catfile( $d, $command ));
+ if ( defined $abs_cmd ) {
+ $command = $abs_cmd;
+ last;
+ }
+ }
+ }
+
+ if ( ! -x $command ) {
+ die "cpan_client '$command' is not executable\n";
+ }
+
+ $self->do_system($command, @opts, @install);
+}
+
sub ACTION_clean {
my ($self) = @_;
+ $self->log_info("Cleaning up build files\n");
foreach my $item (map glob($_), $self->cleanup) {
$self->delete_filetree($item);
}
@@ -3026,11 +3375,15 @@ sub ACTION_clean {
sub ACTION_realclean {
my ($self) = @_;
$self->depends_on('clean');
- $self->delete_filetree($self->config_dir, $self->build_script);
+ $self->log_info("Cleaning up configuration files\n");
+ $self->delete_filetree(
+ $self->config_dir, $self->mymetafile, $self->build_script
+ );
}
sub ACTION_ppd {
my ($self) = @_;
+
require Module::Build::PPMMaker;
my $ppd = Module::Build::PPMMaker->new();
my $file = $ppd->make_ppd(%{$self->{args}}, build => $self);
@@ -3104,7 +3457,7 @@ sub ACTION_pardist {
);
return();
}
-
+
$self->depends_on( 'build' );
return PAR::Dist::blib_to_par(
@@ -3115,11 +3468,11 @@ sub ACTION_pardist {
sub ACTION_dist {
my ($self) = @_;
-
+
$self->depends_on('distdir');
-
+
my $dist_dir = $self->dist_dir;
-
+
$self->make_tarball($dist_dir);
$self->delete_filetree($dist_dir);
}
@@ -3127,6 +3480,8 @@ sub ACTION_dist {
sub ACTION_distcheck {
my ($self) = @_;
+ $self->_check_manifest_skip;
+
require ExtUtils::Manifest;
local $^W; # ExtUtils::Manifest is not warnings clean.
my ($missing, $extra) = ExtUtils::Manifest::fullcheck();
@@ -3141,6 +3496,25 @@ sub ACTION_distcheck {
}
}
+sub _check_mymeta_skip {
+ my $self = shift;
+ my $maniskip = shift || 'MANIFEST.SKIP';
+
+ require ExtUtils::Manifest;
+ local $^W; # ExtUtils::Manifest is not warnings clean.
+
+ # older ExtUtils::Manifest had a private _maniskip
+ my $skip_factory = ExtUtils::Manifest->can('maniskip')
+ || ExtUtils::Manifest->can('_maniskip');
+
+ my $mymetafile = $self->mymetafile;
+ # we can't check it, just add it anyway to be safe
+ unless ( $skip_factory && $skip_factory->($maniskip)->($mymetafile) ) {
+ $self->log_warn("File '$maniskip' does not include '$mymetafile'. Adding it now.\n");
+ $self->_append_maniskip("^$mymetafile\$", $maniskip);
+ }
+}
+
sub _add_to_manifest {
my ($self, $manifest, $lines) = @_;
$lines = [$lines] unless ref $lines;
@@ -3153,7 +3527,7 @@ sub _add_to_manifest {
my $mode = (stat $manifest)[2];
chmod($mode | oct(222), $manifest) or die "Can't make $manifest writable: $!";
-
+
my $fh = IO::File->new("< $manifest") or die "Can't read $manifest: $!";
my $last_line = (<$fh>)[-1] || "\n";
my $has_newline = $last_line =~ /\n$/;
@@ -3165,7 +3539,7 @@ sub _add_to_manifest {
close $fh;
chmod($mode, $manifest);
- $self->log_info(map "Added to $manifest: $_\n", @$lines);
+ $self->log_verbose(map "Added to $manifest: $_\n", @$lines);
}
sub _sign_dir {
@@ -3175,16 +3549,16 @@ sub _sign_dir {
$self->log_warn("Couldn't load Module::Signature for 'distsign' action:\n $@\n");
return;
}
-
+
# Add SIGNATURE to the MANIFEST
{
my $manifest = File::Spec->catfile($dir, 'MANIFEST');
die "Signing a distribution requires a MANIFEST file" unless -e $manifest;
$self->_add_to_manifest($manifest, "SIGNATURE Added here by Module::Build");
}
-
+
# Would be nice if Module::Signature took a directory argument.
-
+
$self->_do_in_dir($dir, sub {local $Module::Signature::Quiet = 1; Module::Signature::sign()});
}
@@ -3210,7 +3584,7 @@ sub ACTION_distsign {
sub ACTION_skipcheck {
my ($self) = @_;
-
+
require ExtUtils::Manifest;
local $^W; # ExtUtils::Manifest is not warnings clean.
ExtUtils::Manifest::skipcheck();
@@ -3218,7 +3592,7 @@ sub ACTION_skipcheck {
sub ACTION_distclean {
my ($self) = @_;
-
+
$self->depends_on('realclean');
$self->depends_on('distcheck');
}
@@ -3235,6 +3609,11 @@ sub do_create_license {
my $self = shift;
$self->log_info("Creating LICENSE file\n");
+ if ( ! $self->_mb_feature('license_creation') ) {
+ $self->_warn_mb_feature_deps('license_creation');
+ die "Aborting.\n";
+ }
+
my $l = $self->license
or die "No license specified";
@@ -3243,7 +3622,7 @@ sub do_create_license {
my $class = "Software::License::$key";
eval "use $class; 1"
- or die "Can't load Software::License to create LICENSE file: $@";
+ or die "Can't load Software::License::$key to create LICENSE file: $@";
$self->delete_filetree('LICENSE');
@@ -3270,7 +3649,9 @@ EOF
return;
}
- if ( eval {require Pod::Readme; 1} ) {
+ # work around some odd Pod::Readme->new() failures in test reports by
+ # confirming that new() is available
+ if ( eval {require Pod::Readme; Pod::Readme->can('new') } ) {
$self->log_info("Creating README using Pod::Readme\n");
my $parser = Pod::Readme->new;
@@ -3326,29 +3707,48 @@ sub _main_docfile {
}
}
+sub do_create_bundle_inc {
+ my $self = shift;
+ my $dist_inc = File::Spec->catdir( $self->dist_dir, 'inc' );
+ require inc::latest;
+ inc::latest->write($dist_inc, @{$self->bundle_inc_preload});
+ inc::latest->bundle_module($_, $dist_inc) for @{$self->bundle_inc};
+ return 1;
+}
+
sub ACTION_distdir {
my ($self) = @_;
+ if ( @{$self->bundle_inc} && ! $self->_mb_feature('inc_bundling_support') ) {
+ $self->_warn_mb_feature_deps('inc_bundling_support');
+ die "Aborting.\n";
+ }
+
$self->depends_on('distmeta');
+ # Must not include MYMETA
+ $self->_check_mymeta_skip('MANIFEST.SKIP');
+
my $dist_files = $self->_read_manifest('MANIFEST')
- or die "Can't create distdir without a MANIFEST file - run 'manifest' action first";
+ or die "Can't create distdir without a MANIFEST file - run 'manifest' action first.\n";
delete $dist_files->{SIGNATURE}; # Don't copy, create a fresh one
die "No files found in MANIFEST - try running 'manifest' action?\n"
unless ($dist_files and keys %$dist_files);
my $metafile = $self->metafile;
$self->log_warn("*** Did you forget to add $metafile to the MANIFEST?\n")
unless exists $dist_files->{$metafile};
-
+
my $dist_dir = $self->dist_dir;
$self->delete_filetree($dist_dir);
$self->log_info("Creating $dist_dir\n");
$self->add_to_cleanup($dist_dir);
-
+
foreach my $file (keys %$dist_files) {
my $new = $self->copy_if_modified(from => $file, to_dir => $dist_dir, verbose => 0);
}
-
+
+ $self->do_create_bundle_inc if @{$self->bundle_inc};
+
$self->_sign_dir($dist_dir) if $self->{properties}{sign};
}
@@ -3388,8 +3788,7 @@ sub _eumanifest_has_include {
my $self = shift;
require ExtUtils::Manifest;
- return ExtUtils::Manifest->VERSION >= 1.50 ? 1 : 0;
- return 0;
+ return eval { ExtUtils::Manifest->VERSION(1.50); 1 };
}
@@ -3436,6 +3835,19 @@ sub _slurp {
}
+
+sub _append_maniskip {
+ my $self = shift;
+ my $skip = shift;
+ my $file = shift || 'MANIFEST.SKIP';
+ return unless defined $skip && length $skip;
+ my $fh = IO::File->new(">> $file")
+ or die "Can't open $file: $!";
+
+ print $fh "$skip\n";
+ $fh->close();
+}
+
sub _write_default_maniskip {
my $self = shift;
my $file = shift || 'MANIFEST.SKIP';
@@ -3446,6 +3858,8 @@ sub _write_default_maniskip {
: $self->_slurp( $self->_default_maniskip );
$content .= <<'EOF';
+# Avoid configuration metadata file
+^MYMETA\.$
# Avoid Module::Build generated and utility files.
\bBuild$
@@ -3466,14 +3880,27 @@ EOF
return;
}
-sub ACTION_manifest {
+sub _check_manifest_skip {
my ($self) = @_;
my $maniskip = 'MANIFEST.SKIP';
- unless ( -e 'MANIFEST' || -e $maniskip ) {
+
+ if ( ! -e $maniskip ) {
$self->log_warn("File '$maniskip' does not exist: Creating a default '$maniskip'\n");
$self->_write_default_maniskip($maniskip);
}
+ else {
+ # MYMETA must not be added to MANIFEST, so always confirm the skip
+ $self->_check_mymeta_skip( $maniskip );
+ }
+
+ return;
+}
+
+sub ACTION_manifest {
+ my ($self) = @_;
+
+ $self->_check_manifest_skip;
require ExtUtils::Manifest; # ExtUtils::Manifest is not warnings clean.
local ($^W, $ExtUtils::Manifest::Quiet) = (0,1);
@@ -3511,6 +3938,63 @@ sub _files_in {
return @files;
}
+sub share_dir {
+ my $self = shift;
+ my $p = $self->{properties};
+
+ $p->{share_dir} = shift if @_;
+
+ # Always coerce to proper hash form
+ if ( ! defined $p->{share_dir} ) {
+ # not set -- use default 'share' dir if exists
+ $p->{share_dir} = { dist => [ 'share' ] } if -d 'share';
+ }
+ elsif ( ! ref $p->{share_dir} ) {
+ # scalar -- treat as a single 'dist' directory
+ $p->{share_dir} = { dist => [ $p->{share_dir} ] };
+ }
+ elsif ( ref $p->{share_dir} eq 'ARRAY' ) {
+ # array -- treat as a list of 'dist' directories
+ $p->{share_dir} = { dist => $p->{share_dir} };
+ }
+ elsif ( ref $p->{share_dir} eq 'HASH' ) {
+ # hash -- check structure
+ my $share_dir = $p->{share_dir};
+ # check dist key
+ if ( defined $share_dir->{dist} ) {
+ if ( ! ref $share_dir->{dist} ) {
+ # scalar, so upgrade to arrayref
+ $share_dir->{dist} = [ $share_dir->{dist} ];
+ }
+ elsif ( ref $share_dir->{dist} ne 'ARRAY' ) {
+ die "'dist' key in 'share_dir' must be scalar or arrayref";
+ }
+ }
+ # check module key
+ if ( defined $share_dir->{module} ) {
+ my $mod_hash = $share_dir->{module};
+ if ( ref $mod_hash eq 'HASH' ) {
+ for my $k ( keys %$mod_hash ) {
+ if ( ! ref $mod_hash->{$k} ) {
+ $mod_hash->{$k} = [ $mod_hash->{$k} ];
+ }
+ elsif( ref $mod_hash->{$k} ne 'ARRAY' ) {
+ die "modules in 'module' key of 'share_dir' must be scalar or arrayref";
+ }
+ }
+ }
+ else {
+ die "'module' key in 'share_dir' must be hashref";
+ }
+ }
+ }
+ else {
+ die "'share_dir' must be hashref, arrayref or string";
+ }
+
+ return $p->{share_dir};
+}
+
sub script_files {
my $self = shift;
@@ -3529,13 +4013,13 @@ sub script_files {
}
my %pl_files = map {
- File::Spec->canonpath( File::Spec->case_tolerant ? uc $_ : $_ ) => 1
+ File::Spec->canonpath( File::Spec->case_tolerant ? uc $_ : $_ ) => 1
} keys %{ $self->PL_files || {} };
my @bin_files = $self->_files_in('bin');
my %bin_map = map {
- $_ => File::Spec->canonpath( File::Spec->case_tolerant ? uc $_ : $_ )
+ $_ => File::Spec->canonpath( File::Spec->case_tolerant ? uc $_ : $_ )
} @bin_files;
return $_ = { map {$_ => 1} grep !$pl_files{$bin_map{$_}}, @bin_files };
@@ -3546,6 +4030,7 @@ BEGIN { *scripts = \&script_files; }
my %licenses = (
perl => 'Perl_5',
apache => 'Apache_2_0',
+ apache_1_1 => 'Apache_1_1',
artistic => 'Artistic_1_0',
artistic_2 => 'Artistic_2_0',
lgpl => 'LGPL_2_1',
@@ -3568,6 +4053,7 @@ BEGIN { *scripts = \&script_files; }
my %license_urls = (
perl => 'http://dev.perl.org/licenses/',
apache => 'http://apache.org/licenses/LICENSE-2.0',
+ apache_1_1 => 'http://apache.org/licenses/LICENSE-1.1',
artistic => 'http://opensource.org/licenses/artistic-license.php',
artistic_2 => 'http://opensource.org/licenses/artistic-license-2.0.php',
lgpl => 'http://opensource.org/licenses/lgpl-license.php',
@@ -3615,10 +4101,10 @@ sub ACTION_distmeta {
sub do_create_metafile {
my $self = shift;
return if $self->{wrote_metadata};
-
+
my $p = $self->{properties};
my $metafile = $self->metafile;
-
+
unless ($p->{license}) {
$self->log_warn("No license specified, setting license = 'unknown'\n");
$p->{license} = 'unknown';
@@ -3639,7 +4125,7 @@ sub do_create_metafile {
push @INC, File::Spec->catdir($self->blib, 'lib');
}
- if ( $self->write_metafile( $self->metafile, $self->generate_metadata ) ) {
+ if ( $self->write_metafile( $self->metafile, $self->prepare_metadata( fatal => 1 ) ) ) {
$self->{wrote_metadata} = 1;
$self->_add_to_manifest('MANIFEST', $metafile);
}
@@ -3647,42 +4133,22 @@ sub do_create_metafile {
return 1;
}
-sub generate_metadata {
- my $self = shift;
- my $node = {};
-
- if ($self->_mb_feature('YAML_support')) {
- require YAML;
- require YAML::Node;
- # We use YAML::Node to get the order nice in the YAML file.
- $self->prepare_metadata( $node = YAML::Node->new({}) );
- } else {
- require Module::Build::YAML;
- my @order_keys;
- $self->prepare_metadata($node, \@order_keys);
- $node->{_order} = \@order_keys;
- }
- return $node;
-}
-
sub write_metafile {
my $self = shift;
my ($metafile, $node) = @_;
+ my $yaml;
if ($self->_mb_feature('YAML_support')) {
# XXX this is probably redundant, but stick with it
- require YAML;
- require YAML::Node;
- delete $node->{_order}; # XXX also probably redundant, but for safety
- # YAML API changed after version 0.30
- my $yaml_sub = $YAML::VERSION le '0.30' ? \&YAML::StoreFile : \&YAML::DumpFile;
- $yaml_sub->( $metafile, $node );
+ require YAML::Tiny;
+ $yaml = YAML::Tiny->new($node);
} else {
- # XXX probably redundant
require Module::Build::YAML;
- &Module::Build::YAML::DumpFile($metafile, $node);
+ $yaml = Module::Build::YAML->new($node);
}
- return 1;
+ my $result = $yaml->write($metafile)
+ or $self->log_warn( "Error writing '$metafile': " . $yaml->errstr . "\n");
+ return $result;
}
sub normalize_version {
@@ -3690,7 +4156,7 @@ sub normalize_version {
if ( $version =~ /[=<>!,]/ ) { # logic, not just version
# take as is without modification
}
- elsif ( ref $version eq 'version' ||
+ elsif ( ref $version eq 'version' ||
ref $version eq 'Module::Build::Version' ) { # version objects
$version = $version->is_qv ? $version->normal : $version->stringify;
}
@@ -3705,31 +4171,46 @@ sub normalize_version {
}
sub prepare_metadata {
- my ($self, $node, $keys) = @_;
+ my ($self, %args) = @_;
+ my $fatal = $args{fatal} || 0;
my $p = $self->{properties};
+ my $node = {};
# A little helper sub
my $add_node = sub {
my ($name, $val) = @_;
$node->{$name} = $val;
- push @$keys, $name if $keys;
};
foreach (qw(dist_name dist_version dist_author dist_abstract license)) {
(my $name = $_) =~ s/^dist_//;
$add_node->($name, $self->$_());
- die "ERROR: Missing required field '$_' for META.yml\n"
- unless defined($node->{$name}) && length($node->{$name});
+ unless ( defined($node->{$name}) && length($node->{$name}) ) {
+ my $err = "ERROR: Missing required field '$_' for metafile\n";
+ if ( $fatal ) {
+ die $err;
+ }
+ else {
+ $self->log_warn($err);
+ }
+ }
}
- $node->{version} = $self->normalize_version($node->{version});
+ $node->{version} = $self->normalize_version($node->{version});
if (defined( my $l = $self->license )) {
- die "Unknown license string '$l'"
- unless exists $self->valid_licenses->{ $l };
+ unless ( exists $self->valid_licenses->{ $l } ) {
+ my $err = "Unknown license string '$l'";
+ if ( $fatal ) {
+ die $err;
+ }
+ else {
+ $self->log_warn($err);
+ }
+ }
if (my $key = $self->valid_licenses->{ $l }) {
my $class = "Software::License::$key";
- if (eval "use $class; 1") {
+ if (eval "require Software::License; require $class; 1") {
# S::L requires a 'holder' key
$node->{resources}{license} = $class->new({holder=>"nobody"})->url;
}
@@ -3743,24 +4224,14 @@ sub prepare_metadata {
# copy prereq data structures so we can modify them before writing to META
my %prereq_types;
for my $type ( 'configure_requires', @{$self->prereq_action_types} ) {
- if (exists $p->{$type}) {
+ if (exists $p->{$type}) {
for my $mod ( keys %{ $p->{$type} } ) {
- $prereq_types{$type}{$mod} =
+ $prereq_types{$type}{$mod} =
$self->normalize_version($p->{$type}{$mod});
}
}
}
- # add current Module::Build to configure_requires if there
- # isn't one already specified (but not ourself, so we're not circular)
- if ( $self->dist_name ne 'Module-Build'
- && $self->auto_configure_requires
- && ! exists $prereq_types{'configure_requires'}{'Module::Build'}
- ) {
- (my $ver = $VERSION) =~ s/^(\d+\.\d\d).*$/$1/; # last major release only
- $prereq_types{configure_requires}{'Module::Build'} = $ver;
- }
-
for my $t ( keys %prereq_types ) {
$add_node->($t, $prereq_types{$t});
}
@@ -3771,7 +4242,7 @@ sub prepare_metadata {
my $pkgs = eval { $self->find_dist_packages };
if ($@) {
$self->log_warn("$@\nWARNING: Possible missing or corrupt 'MANIFEST' file.\n" .
- "Nothing to enter for 'provides' field in META.yml\n");
+ "Nothing to enter for 'provides' field in metafile.\n");
} else {
$node->{provides} = $pkgs if %$pkgs;
}
@@ -3782,7 +4253,7 @@ sub prepare_metadata {
$add_node->('generated_by', "Module::Build version $Module::Build::VERSION");
- $add_node->('meta-spec',
+ $add_node->('meta-spec',
{version => '1.4',
url => 'http://module-build.sourceforge.net/META-spec-v1.4.html',
});
@@ -3815,21 +4286,28 @@ sub find_dist_packages {
# private stock.
my $manifest = $self->_read_manifest('MANIFEST')
- or die "Can't find dist packages without a MANIFEST file - run 'manifest' action first";
+ or die "Can't find dist packages without a MANIFEST file\nRun 'Build manifest' to generate one\n";
# Localize
my %dist_files = map { $self->localize_file_path($_) => $_ }
keys %$manifest;
- my @pm_files = grep {exists $dist_files{$_}} keys %{ $self->find_pm_files };
+ my @pm_files = grep { $_ !~ m{^t} } # skip things in t/
+ grep {exists $dist_files{$_}}
+ keys %{ $self->find_pm_files };
+
+ return $self->find_packages_in_files(\@pm_files, \%dist_files);
+}
+
+sub find_packages_in_files {
+ my ($self, $file_list, $filename_map) = @_;
# First, we enumerate all packages & versions,
# separating into primary & alternative candidates
my( %prime, %alt );
- foreach my $file (@pm_files) {
- next if $dist_files{$file} =~ m{^t/}; # Skip things in t/
-
- my @path = split( /\//, $dist_files{$file} );
+ foreach my $file (@{$file_list}) {
+ my $mapped_filename = $filename_map->{$file};
+ my @path = split( /\//, $mapped_filename );
(my $prime_package = join( '::', @path[1..$#path] )) =~ s/\.pm$//;
my $pm_info = Module::Build::ModuleInfo->new_from_file( $file );
@@ -3841,18 +4319,18 @@ sub find_dist_packages {
my $version = $pm_info->version( $package );
if ( $package eq $prime_package ) {
- if ( exists( $prime{$package} ) ) {
- # M::B::ModuleInfo will handle this conflict
- die "Unexpected conflict in '$package'; multiple versions found.\n";
- } else {
- $prime{$package}{file} = $dist_files{$file};
+ if ( exists( $prime{$package} ) ) {
+ # M::B::ModuleInfo will handle this conflict
+ die "Unexpected conflict in '$package'; multiple versions found.\n";
+ } else {
+ $prime{$package}{file} = $mapped_filename;
$prime{$package}{version} = $version if defined( $version );
}
} else {
- push( @{$alt{$package}}, {
- file => $dist_files{$file},
- version => $version,
- } );
+ push( @{$alt{$package}}, {
+ file => $mapped_filename,
+ version => $version,
+ } );
}
}
}
@@ -3972,24 +4450,29 @@ sub _resolve_module_versions {
sub make_tarball {
my ($self, $dir, $file) = @_;
$file ||= $dir;
-
+
$self->log_info("Creating $file.tar.gz\n");
-
+
if ($self->{args}{tar}) {
my $tar_flags = $self->verbose ? 'cvf' : 'cf';
$self->do_system($self->split_like_shell($self->{args}{tar}), $tar_flags, "$file.tar", $dir);
$self->do_system($self->split_like_shell($self->{args}{gzip}), "$file.tar") if $self->{args}{gzip};
} else {
- eval { require Archive::Tar && Archive::Tar->VERSION(1.08); 1 }
- or die "You must install Archive::Tar to make a distribution tarball\n".
+ eval { require Archive::Tar && Archive::Tar->VERSION(1.09); 1 }
+ or die "You must install Archive::Tar 1.09+ to make a distribution tarball\n".
"or specify a binary tar program with the '--tar' option.\n".
"See the documentation for the 'dist' action.\n";
+ my $files = $self->rscan_dir($dir);
+
# Archive::Tar versions >= 1.09 use the following to enable a compatibility
# hack so that the resulting archive is compatible with older clients.
- $Archive::Tar::DO_NOT_USE_PREFIX = 0;
+ # If no file path is 100 chars or longer, we disable the prefix field
+ # for maximum compatibility. If there are any long file paths then we
+ # need the prefix field after all.
+ $Archive::Tar::DO_NOT_USE_PREFIX =
+ (grep { length($_) >= 100 } @$files) ? 0 : 1;
- my $files = $self->rscan_dir($dir);
my $tar = Archive::Tar->new;
$tar->add_files(@$files);
for my $f ($tar->get_files) {
@@ -4055,7 +4538,7 @@ sub original_prefix {
# or original_prefix('lib' => $value);
my ($self, $key, $value) = @_;
# update property before merging with defaults
- if ( @_ == 3 && defined $key) {
+ if ( @_ == 3 && defined $key) {
# $value can be undef; will mask default
$self->{properties}{original_prefix}{$key} = $value;
}
@@ -4263,7 +4746,7 @@ sub install_map {
}
}
}
-
+
$map{read} = ''; # To keep ExtUtils::Install quiet
return \%map;
@@ -4284,7 +4767,7 @@ sub rscan_dir {
!ref($pattern) || (ref $pattern eq 'Regexp') ? sub {push @result, $File::Find::name if /$pattern/} :
ref($pattern) eq 'CODE' ? sub {push @result, $File::Find::name if $pattern->()} :
die "Unknown pattern type";
-
+
File::Find::find({wanted => $subr, no_chdir => 1}, $dir);
return \@result;
}
@@ -4294,7 +4777,7 @@ sub delete_filetree {
my $deleted = 0;
foreach (@_) {
next unless -e $_;
- $self->log_info("Deleting $_\n");
+ $self->log_verbose("Deleting $_\n");
File::Path::rmtree($_, 0, 0);
die "Couldn't remove '$_': $!\n" if -e $_;
$deleted++;
@@ -4327,21 +4810,25 @@ sub cbuilder {
sub have_c_compiler {
my ($self) = @_;
-
+
my $p = $self->{properties};
- return $p->{have_compiler} if defined $p->{have_compiler};
-
+ return $p->{_have_c_compiler} if defined $p->{_have_c_compiler};
+
$self->log_verbose("Checking if compiler tools configured... ");
my $b = eval { $self->cbuilder };
- my $have = $b && $b->have_compiler;
+ my $have = $b && eval { $b->have_compiler };
$self->log_verbose($have ? "ok.\n" : "failed.\n");
- return $p->{have_compiler} = $have;
+ return $p->{_have_c_compiler} = $have;
}
sub compile_c {
my ($self, $file, %args) = @_;
- my $b = $self->cbuilder;
+ if ( ! $self->have_c_compiler ) {
+ die "Error: no compiler detected to compile '$file'. Aborting\n";
+ }
+
+ my $b = $self->cbuilder;
my $obj_file = $b->object_file($file);
$self->add_to_cleanup($obj_file);
return $obj_file if $self->up_to_date($file, $obj_file);
@@ -4381,11 +4868,11 @@ sub link_c {
sub compile_xs {
my ($self, $file, %args) = @_;
-
- $self->log_info("$file -> $args{outfile}\n");
+
+ $self->log_verbose("$file -> $args{outfile}\n");
if (eval {require ExtUtils::ParseXS; 1}) {
-
+
ExtUtils::ParseXS::process_file(
filename => $file,
prototypes => 0,
@@ -4393,26 +4880,26 @@ sub compile_xs {
);
} else {
# Ok, I give up. Just use backticks.
-
+
my $xsubpp = Module::Build::ModuleInfo->find_module_by_name('ExtUtils::xsubpp')
or die "Can't find ExtUtils::xsubpp in INC (@INC)";
-
+
my @typemaps;
push @typemaps, Module::Build::ModuleInfo->find_module_by_name(
'ExtUtils::typemap', \@INC
);
my $lib_typemap = Module::Build::ModuleInfo->find_module_by_name(
- 'typemap', [File::Basename::dirname($file)]
+ 'typemap', [File::Basename::dirname($file), File::Spec->rel2abs('.')]
);
push @typemaps, $lib_typemap if $lib_typemap;
@typemaps = map {+'-typemap', $_} @typemaps;
my $cf = $self->{config};
my $perl = $self->{properties}{perl};
-
+
my @command = ($perl, "-I".$cf->get('installarchlib'), "-I".$cf->get('installprivlib'), $xsubpp, '-noprototypes',
@typemaps, $file);
-
+
$self->log_info("@command\n");
my $fh = IO::File->new("> $args{outfile}") or die "Couldn't write $args{outfile}: $!";
print {$fh} $self->_backticks(@command);
@@ -4422,12 +4909,12 @@ sub compile_xs {
sub split_like_shell {
my ($self, $string) = @_;
-
+
return () unless defined($string);
return @$string if UNIVERSAL::isa($string, 'ARRAY');
$string =~ s/^\s+|\s+$//g;
return () unless length($string);
-
+
return Text::ParseWords::shellwords($string);
}
@@ -4553,12 +5040,12 @@ sub process_xs {
sub do_system {
my ($self, @cmd) = @_;
- $self->log_info("@cmd\n");
+ $self->log_verbose("@cmd\n");
# Some systems proliferate huge PERL5LIBs, try to ameliorate:
my %seen;
my $sep = $self->config('path_sep');
- local $ENV{PERL5LIB} =
+ local $ENV{PERL5LIB} =
( !exists($ENV{PERL5LIB}) ? '' :
length($ENV{PERL5LIB}) < 500
? $ENV{PERL5LIB}
@@ -4587,8 +5074,8 @@ sub copy_if_modified {
unless (defined $file and length $file) {
die "No 'from' parameter given to copy_if_modified";
}
-
- # makes no sense to replicate an absolute path, so assume flatten
+
+ # makes no sense to replicate an absolute path, so assume flatten
$args{flatten} = 1 if File::Spec->file_name_is_absolute( $file );
my $to_path;
@@ -4601,7 +5088,7 @@ sub copy_if_modified {
} else {
die "No 'to' or 'to_dir' parameter given to copy_if_modified";
}
-
+
return if $self->up_to_date($file, $to_path); # Already fresh
{
@@ -4611,9 +5098,9 @@ sub copy_if_modified {
# Create parent directories
File::Path::mkpath(File::Basename::dirname($to_path), 0, oct(777));
-
- $self->log_info("Copying $file -> $to_path\n") if $args{verbose};
-
+
+ $self->log_verbose("Copying $file -> $to_path\n");
+
if ($^O eq 'os2') {# copy will not overwrite; 0x1 = overwrite
chmod 0666, $to_path;
File::Copy::syscopy($file, $to_path, 0x1) or die "Can't copy('$file', '$to_path'): $!";
@@ -4644,7 +5131,7 @@ sub up_to_date {
}
$most_recent_source = -M _ if -M _ < $most_recent_source;
}
-
+
foreach my $derived (@$derived) {
return 0 if -M $derived > $most_recent_source;
}
@@ -4655,21 +5142,21 @@ sub dir_contains {
my ($self, $first, $second) = @_;
# File::Spec doesn't have an easy way to check whether one directory
# is inside another, unfortunately.
-
+
($first, $second) = map File::Spec->canonpath($_), ($first, $second);
my @first_dirs = File::Spec->splitdir($first);
my @second_dirs = File::Spec->splitdir($second);
return 0 if @second_dirs < @first_dirs;
-
+
my $is_same = ( File::Spec->case_tolerant
? sub {lc(shift()) eq lc(shift())}
: sub {shift() eq shift()} );
-
+
while (@first_dirs) {
return 0 unless $is_same->(shift @first_dirs, shift @second_dirs);
}
-
+
return 1;
}
diff --git a/cpan/Module-Build/lib/Module/Build/Bundling.pod b/cpan/Module-Build/lib/Module/Build/Bundling.pod
new file mode 100644
index 0000000000..0a60d8f70d
--- /dev/null
+++ b/cpan/Module-Build/lib/Module/Build/Bundling.pod
@@ -0,0 +1,154 @@
+=head1 NAME
+
+Module::Build::Bundling - How to bundle Module::Build with a distribution
+
+=head1 SYNOPSIS
+
+ # Build.PL
+ use lib '.';
+ use inc::latest 'Module::Build';
+
+ Module::Build->new(
+ module_name => 'Foo::Bar',
+ license => 'perl',
+ )->create_build_script;
+
+=head1 DESCRIPTION
+
+B<WARNING -- THIS IS AN EXPERIMENTAL FEATURE>
+
+In order to install a distribution using Module::Build, users must
+have Module::Build available on their systems. There are two ways
+to do this. The first way is to include Module::Build in the
+C<configure_requires> metadata field. This field is supported by
+recent versions L<CPAN> and L<CPANPLUS> and is a standard feature
+in the Perl core as of Perl 5.10.1. Module::Build now adds itself
+to C<configure_requires> by default.
+
+The second way supports older Perls that have not upgraded CPAN or
+CPANPLUS and involves bundling an entire copy of Module::Build
+into the distribution's C<inc/> directory. This is the same approach
+used by L<Module::Install>, a modern wrapper around ExtUtils::MakeMaker
+for Makefile.PL based distributions.
+
+The "trick" to making this work for Module::Build is making sure the
+highest version Module::Build is used, whether this is in C<inc/> or
+already installed on the user's system. This ensures that all necessary
+features are available as well as any new bug fixes. This is done using
+the new L<inc::latest> module.
+
+A "normal" Build.PL looks like this (with only the minimum required
+fields):
+
+ use Module::Build;
+
+ Module::Build->new(
+ module_name => 'Foo::Bar',
+ license => 'perl',
+ )->create_build_script;
+
+A "bundling" Build.PL replaces the initial "use" line with a nearly
+transparent replacement:
+
+ use lib '.';
+ use inc::latest 'Module::Build';
+
+ Module::Build->new(
+ module_name => 'Foo::Bar',
+ license => 'perl',
+ )->create_build_script;
+
+The inital C<lib> line ensures that the top-level distribution directory is
+added to C<@INC> so that C<inc::latest> loads from C<./inc/latest.pm>. You
+SHOULD NOT add 'inc' to C<@INC> (unless you have other special reasons for
+doing so) -- that's not how C<inc::latest> works.
+
+For I<authors>, when "Build dist" is run, Module::Build will be
+automatically bundled into C<inc> according to the rules for
+L<inc::latest>.
+
+For I<users>, inc::latest will load the latest Module::Build, whether
+installed or bundled in C<inc/>.
+
+=head1 BUNDLING OTHER CONFIGURATION DEPENDENCIES
+
+The same approach works for other configuration dependencies -- modules
+that I<must> be available for Build.PL to run. All other dependencies can
+be specified as usual in the Build.PL and CPAN or CPANPLUS will install
+them after Build.PL finishes.
+
+For example, to bundle the L<Devel::AssertOS::Unix> module (which ensures a
+"Unix-like" operating system), one could do this:
+
+ use inc::latest 'Devel::AssertOS::Unix';
+ use inc::latest 'Module::Build';
+
+ Module::Build->new(
+ module_name => 'Foo::Bar',
+ license => 'perl',
+ )->create_build_script;
+
+The C<inc::latest> module creates bundled directories based on the packlist
+file of an installed distribution. Even though C<inc::latest> takes module
+name arguments, it is better to think of it as bundling and making
+available entire I<distributions>. When a module is loaded through
+C<inc::latest>, it looks in all bundled distributions in C<inc/> for a
+newer module than can be found in the existing C<@INC> array.
+
+Thus, the module-name provided should usually be the "top-level" module
+name of a distribution, though this is not strictly required. For example,
+L<Module::Build> has a number of heuristics to map module names to
+packlists, allowing users to do things like this:
+
+ use inc::latest 'Devel::AssertOS::Unix';
+
+even though Devel::AssertOS::Unix is contained within the Devel-CheckOS
+distribution.
+
+At the current time, packlists are required. Thus, bundling dual-core
+modules, I<including Module::Build>, may require a 'forced install' over
+versions in the latest version of perl in order to create the necessary
+packlist for bundling. This limitation will hopefully be addressed in a
+future version of Module::Build.
+
+=head2 WARNING -- How to Manage Dependency Chains
+
+Before bundling a distribution you must ensure that all prerequisites are
+also bundled and load in the correct order. For Module::Build itself, this
+should not be necessary, but it is necessary for any other distribution.
+(A future release of Module::Build will hopefully address this deficiency.)
+
+For example, if you need C<Wibble>, but C<Wibble> depends on C<Wobble>,
+your Build.PL might look like this:
+
+ use inc::latest 'Wobble';
+ use inc::latest 'Wibble';
+ use inc::latest 'Module::Build';
+
+ Module::Build->new(
+ module_name => 'Foo::Bar',
+ license => 'perl',
+ )->create_build_script;
+
+Authors are strongly suggested to limit the bundling of additional
+dependencies if at all possible and to carefully test their distribution
+tarballs on older versions of Perl before uploading to CPAN.
+
+=head1 AUTHOR
+
+David Golden <dagolden@cpan.org>
+
+Development questions, bug reports, and patches should be sent to the
+Module-Build mailing list at <module-build@perl.org>.
+
+Bug reports are also welcome at
+<http://rt.cpan.org/NoAuth/Bugs.html?Dist=Module-Build>.
+
+=head1 SEE ALSO
+
+perl(1), L<inc::latest>, L<Module::Build>(3), L<Module::Build::API>(3),
+L<Module::Build::Cookbook>(3),
+
+=cut
+
+# vim: tw=75
diff --git a/cpan/Module-Build/lib/Module/Build/Compat.pm b/cpan/Module-Build/lib/Module/Build/Compat.pm
index dfe75d5e1a..ebe1b129cf 100644
--- a/cpan/Module-Build/lib/Module/Build/Compat.pm
+++ b/cpan/Module-Build/lib/Module/Build/Compat.pm
@@ -2,7 +2,7 @@ package Module::Build::Compat;
use strict;
use vars qw($VERSION);
-$VERSION = '0.35';
+$VERSION = '0.35_08';
use File::Basename ();
use File::Spec;
@@ -18,7 +18,7 @@ my %convert_installdirs = (
VENDOR => 'vendor',
);
-my %makefile_to_build =
+my %makefile_to_build =
(
TEST_VERBOSE => 'verbose',
VERBINST => 'verbose',
@@ -64,13 +64,50 @@ my %macro_to_build = %makefile_to_build;
# "LIB=foo make" is not the same as "perl Makefile.PL LIB=foo"
delete $macro_to_build{LIB};
+sub _simple_prereq {
+ return $_[0] =~ /^[0-9_]+\.?[0-9_]*$/; # crudly, a decimal literal
+}
+
+sub _merge_prereq {
+ my ($req, $breq) = @_;
+ $req ||= {};
+ $breq ||= {};
+
+ # validate formats
+ for my $p ( $req, $breq ) {
+ for my $k (keys %$p) {
+ die "Prereq '$p->{$k}' for '$k' is not supported by Module::Build::Compat\n"
+ unless _simple_prereq($p->{$k});
+ }
+ }
+ # merge
+ my $merge = { %$req };
+ for my $k ( keys %$breq ) {
+ my $v1 = $merge->{$k} || 0;
+ my $v2 = $breq->{$k};
+ $merge->{$k} = $v1 > $v2 ? $v1 : $v2;
+ }
+ return %$merge;
+}
+
sub create_makefile_pl {
my ($package, $type, $build, %args) = @_;
-
+
die "Don't know how to build Makefile.PL of type '$type'"
unless $type =~ /^(small|passthrough|traditional)$/;
+ if ($type eq 'passthrough') {
+ $build->log_warn(<<"HERE");
+
+IMPORTANT NOTE: The '$type' style of Makefile.PL is deprecated and
+may be removed in a future version of Module::Build in favor of the
+'configure_requires' property. See Module::Build::Compat
+documentation for details.
+
+HERE
+ }
+
my $fh;
if ($args{fh}) {
$fh = $args{fh};
@@ -83,7 +120,7 @@ sub create_makefile_pl {
print {$fh} "# Note: this file was auto-generated by ", __PACKAGE__, " version $VERSION\n";
- # Minimum perl version should be specified as "require 5.XXXXXX" in
+ # Minimum perl version should be specified as "require 5.XXXXXX" in
# Makefile.PL
my $requires = $build->requires;
if ( my $minimum_perl = $requires->{perl} ) {
@@ -123,41 +160,41 @@ EOF
} elsif ($type eq 'passthrough') {
printf {$fh} <<'EOF', $subclass_load, ref($build), ref($build);
-
+
unless (eval "use Module::Build::Compat 0.02; 1" ) {
print "This module requires Module::Build to install itself.\n";
-
+
require ExtUtils::MakeMaker;
my $yn = ExtUtils::MakeMaker::prompt
(' Install Module::Build now from CPAN?', 'y');
-
+
unless ($yn =~ /^y/i) {
die " *** Cannot install without Module::Build. Exiting ...\n";
}
-
+
require Cwd;
require File::Spec;
require CPAN;
-
+
# Save this 'cause CPAN will chdir all over the place.
my $cwd = Cwd::cwd();
-
+
CPAN::Shell->install('Module::Build::Compat');
CPAN::Shell->expand("Module", "Module::Build::Compat")->uptodate
or die "Couldn't install Module::Build, giving up.\n";
-
+
chdir $cwd or die "Cannot chdir() back to $cwd: $!";
}
eval "use Module::Build::Compat 0.02; 1" or die $@;
%s
Module::Build::Compat->run_build_pl(args => \@ARGV);
- my $build_script = 'Build';
+ my $build_script = 'Build';
$build_script .= '.com' if $^O eq 'VMS';
exit(0) unless(-e $build_script); # cpantesters convention
require %s;
Module::Build::Compat->write_makefile(build_class => '%s');
EOF
-
+
} elsif ($type eq 'traditional') {
my (%MM_Args, %prereq);
@@ -165,37 +202,37 @@ EOF
tie %MM_Args, 'Tie::IxHash'; # Don't care if it fails here
tie %prereq, 'Tie::IxHash'; # Don't care if it fails here
}
-
+
my %name = ($build->module_name
? (NAME => $build->module_name)
: (DISTNAME => $build->dist_name));
-
+
my %version = ($build->dist_version_from
? (VERSION_FROM => $build->dist_version_from)
: (VERSION => $build->dist_version)
);
%MM_Args = (%name, %version);
-
- %prereq = ( %{$build->requires}, %{$build->build_requires} );
+
+ %prereq = _merge_prereq( $build->requires, $build->build_requires );
%prereq = map {$_, $prereq{$_}} sort keys %prereq;
-
+
delete $prereq{perl};
$MM_Args{PREREQ_PM} = \%prereq;
-
+
$MM_Args{INSTALLDIRS} = $build->installdirs eq 'core' ? 'perl' : $build->installdirs;
-
+
$MM_Args{EXE_FILES} = [ sort keys %{$build->script_files} ] if $build->script_files;
-
+
$MM_Args{PL_FILES} = $build->PL_files || {};
if ($build->recursive_test_files) {
- $MM_Args{TESTS} = join q{ }, $package->_test_globs($build);
+ $MM_Args{test} = { TESTS => join q{ }, $package->_test_globs($build) };
}
local $Data::Dumper::Terse = 1;
my $args = Data::Dumper::Dumper(\%MM_Args);
$args =~ s/\{(.*)\}/($1)/s;
-
+
print $fh <<"EOF";
use ExtUtils::MakeMaker;
WriteMakefile
@@ -213,7 +250,7 @@ sub _test_globs {
sub subclass_dir {
my ($self, $build) = @_;
-
+
return (Module::Build::ModuleInfo->find_module_dir_by_name(ref $build)
|| File::Spec->catdir($build->config_dir, 'lib'));
}
@@ -228,7 +265,7 @@ sub makefile_to_build_args {
my @out;
foreach my $arg (@_) {
next if $arg eq '';
-
+
my ($key, $val) = ($arg =~ /^(\w+)=(.+)/ ? ($1, $2) :
die "Malformed argument '$arg'");
@@ -283,7 +320,7 @@ sub makefile_to_build_macros {
}
}
}
- push @out, (config => \%config) if %config;
+ push @out, (config => \%config) if %config;
return @out;
}
@@ -342,19 +379,19 @@ $action : force_do_it
$perl $Build $action
EOF
}
-
+
if ($self->_is_vms_mms) {
# Roll our own .EXPORT as MMS/MMK don't honor that directive.
- $maketext .= "\n.FIRST\n\t\@ $noop\n";
+ $maketext .= "\n.FIRST\n\t\@ $noop\n";
for my $macro (keys %macro_to_build) {
$maketext .= ".IFDEF $macro\n\tDEFINE $macro \"\$($macro)\"\n.ENDIF\n";
}
- $maketext .= "\n";
+ $maketext .= "\n";
}
else {
$maketext .= "\n.EXPORT : " . join(' ', keys %macro_to_build) . "\n\n";
}
-
+
return $maketext;
}
@@ -363,15 +400,13 @@ sub fake_prereqs {
my $fh = IO::File->new("< $file") or die "Can't read $file: $!";
my $prereqs = eval do {local $/; <$fh>};
close $fh;
-
+
+ my %merged = _merge_prereq( $prereqs->{requires}, $prereqs->{build_requires} );
my @prereq;
- foreach my $section (qw/build_requires requires/) {
- foreach (keys %{$prereqs->{$section}}) {
- next if $_ eq 'perl';
- push @prereq, "$_=>q[$prereqs->{$section}{$_}]";
- }
+ foreach (sort keys %merged) {
+ next if $_ eq 'perl';
+ push @prereq, "$_=>q[$merged{$_}]";
}
-
return unless @prereq;
return "# PREREQ_PM => { " . join(", ", @prereq) . " }\n\n";
}
@@ -414,7 +449,7 @@ Module::Build::Compat - Compatibility with ExtUtils::MakeMaker
my $build = Module::Build->new
( module_name => 'Foo::Bar',
license => 'perl',
- create_makefile_pl => 'passthrough' );
+ create_makefile_pl => 'traditional' );
...
@@ -448,6 +483,18 @@ The currently supported styles are:
=over 4
+=item traditional
+
+A F<Makefile.PL> will be created in the "traditional" style, i.e. it will
+use C<ExtUtils::MakeMaker> and won't rely on C<Module::Build> at all.
+In order to create the F<Makefile.PL>, we'll include the C<requires> and
+C<build_requires> dependencies as the C<PREREQ_PM> parameter.
+
+You don't want to use this style if during the C<perl Build.PL> stage
+you ask the user questions, or do some auto-sensing about the user's
+environment, or if you subclass C<Module::Build> to do some
+customization, because the vanilla F<Makefile.PL> won't do any of that.
+
=item small
A small F<Makefile.PL> will be created that passes all functionality
@@ -455,24 +502,22 @@ through to the F<Build.PL> script in the same directory. The user must
already have C<Module::Build> installed in order to use this, or else
they'll get a module-not-found error.
-=item passthrough
+=item passthrough (DEPRECATED)
This is just like the C<small> option above, but if C<Module::Build> is
not already installed on the user's system, the script will offer to
use C<CPAN.pm> to download it and install it before continuing with
the build.
-=item traditional
-
-A F<Makefile.PL> will be created in the "traditional" style, i.e. it will
-use C<ExtUtils::MakeMaker> and won't rely on C<Module::Build> at all.
-In order to create the F<Makefile.PL>, we'll include the C<requires> and
-C<build_requires> dependencies as the C<PREREQ_PM> parameter.
+This option has been deprecated and may be removed in a future version
+of Module::Build. Modern CPAN.pm and CPANPLUS will recognize the
+C<configure_requires> metadata property and install Module::Build before
+running Build.PL if Module::Build is listed and Module::Build now
+adds itself to configure_requires by default.
-You don't want to use this style if during the C<perl Build.PL> stage
-you ask the user questions, or do some auto-sensing about the user's
-environment, or if you subclass C<Module::Build> to do some
-customization, because the vanilla F<Makefile.PL> won't do any of that.
+Perl 5.10.1 includes C<configure_requires> support. In the future, when
+C<configure_requires> support is deemed sufficiently widespread, the
+C<passthrough> style will be removed.
=back
diff --git a/cpan/Module-Build/lib/Module/Build/Config.pm b/cpan/Module-Build/lib/Module/Build/Config.pm
index de8b44d092..b833e2b183 100644
--- a/cpan/Module-Build/lib/Module/Build/Config.pm
+++ b/cpan/Module-Build/lib/Module/Build/Config.pm
@@ -2,7 +2,7 @@ package Module::Build::Config;
use strict;
use vars qw($VERSION);
-$VERSION = '0.35';
+$VERSION = '0.35_08';
$VERSION = eval $VERSION;
use Config;
diff --git a/cpan/Module-Build/lib/Module/Build/Cookbook.pm b/cpan/Module-Build/lib/Module/Build/Cookbook.pm
index 82c8e01d67..42054d1744 100644
--- a/cpan/Module-Build/lib/Module/Build/Cookbook.pm
+++ b/cpan/Module-Build/lib/Module/Build/Cookbook.pm
@@ -1,7 +1,7 @@
package Module::Build::Cookbook;
use strict;
use vars qw($VERSION);
-$VERSION = '0.35';
+$VERSION = '0.35_08';
=head1 NAME
@@ -487,7 +487,7 @@ Next, add this to the top of your F<Build.PL>.
# Find out what version of Module::Build is installed or fail quietly.
# This should be cross-platform.
- my $Installed_MB =
+ my $Installed_MB =
`$^X -e "eval q{require Module::Build; print Module::Build->VERSION} or exit 1";
# some operating systems put a newline at the end of every print.
diff --git a/cpan/Module-Build/lib/Module/Build/Dumper.pm b/cpan/Module-Build/lib/Module/Build/Dumper.pm
index 1cd8cd0e16..6f8ff7a616 100644
--- a/cpan/Module-Build/lib/Module/Build/Dumper.pm
+++ b/cpan/Module-Build/lib/Module/Build/Dumper.pm
@@ -1,7 +1,7 @@
package Module::Build::Dumper;
use strict;
use vars qw($VERSION);
-$VERSION = '0.35';
+$VERSION = '0.35_08';
# This is just a split-out of a wrapper function to do Data::Dumper
# stuff "the right way". See:
diff --git a/cpan/Module-Build/lib/Module/Build/ModuleInfo.pm b/cpan/Module-Build/lib/Module/Build/ModuleInfo.pm
index 4de09b4c68..12ffa1d711 100644
--- a/cpan/Module-Build/lib/Module/Build/ModuleInfo.pm
+++ b/cpan/Module-Build/lib/Module/Build/ModuleInfo.pm
@@ -8,13 +8,14 @@ package Module::Build::ModuleInfo;
use strict;
use vars qw($VERSION);
-$VERSION = '0.35';
+$VERSION = '0.35_08';
$VERSION = eval $VERSION;
use File::Spec;
use IO::File;
use Module::Build::Version;
+my $V_NUM_REGEXP = qr{v?[0-9._]+}; # crudely, a v-string or decimal
my $PKG_REGEXP = qr{ # match a package declaration
^[\s\{;]* # intro chars on a line
@@ -22,6 +23,8 @@ my $PKG_REGEXP = qr{ # match a package declaration
\s+ # whitespace
([\w:]+) # a package name
\s* # optional whitespace
+ ($V_NUM_REGEXP)? # optional version number
+ \s* # optional whitesapce
; # semicolon line terminator
}x;
@@ -221,10 +224,10 @@ sub _parse_fh {
$self->_parse_version_expression( $line );
if ( $line =~ $PKG_REGEXP ) {
- $pkg = $1;
- push( @pkgs, $pkg ) unless grep( $pkg eq $_, @pkgs );
- $vers{$pkg} = undef unless exists( $vers{$pkg} );
- $need_vers = 1;
+ $pkg = $1;
+ push( @pkgs, $pkg ) unless grep( $pkg eq $_, @pkgs );
+ $vers{$pkg} = (defined $2 ? $2 : undef) unless exists( $vers{$pkg} );
+ $need_vers = defined $2 ? 0 : 1;
# VERSION defined with full package spec, i.e. $Module::VERSION
} elsif ( $vers_fullname && $vers_pkg ) {
@@ -232,7 +235,7 @@ sub _parse_fh {
$need_vers = 0 if $vers_pkg eq $pkg;
unless ( defined $vers{$vers_pkg} && length $vers{$vers_pkg} ) {
- $vers{$vers_pkg} =
+ $vers{$vers_pkg} =
$self->_evaluate_version_line( $vers_sig, $vers_fullname, $line );
} else {
# Warn unless the user is using the "$VERSION = eval
@@ -323,11 +326,22 @@ sub _evaluate_version_line {
(ref($vsub) eq 'CODE') or
die "failed to build version sub for $self->{filename}";
my $result = eval { $vsub->() };
+ die "Could not get version from $self->{filename} by executing:\n$eval\n\nThe fatal error was: $@\n"
+ if $@;
- die "Could not get version from $self->{filename} by executing:\n$eval\n\nThe fatal error was: $@\n" if $@;
+ # Activestate apparently creates custom versions like '1.23_45_01', which
+ # cause M::B::Version to think it's an invalid alpha. So check for that
+ # and strip them
+ my $num_dots = () = $result =~ m{\.}g;
+ my $num_unders = () = $result =~ m{_}g;
+ if ( substr($result,0,1) ne 'v' && $num_dots < 2 && $num_unders > 1 ) {
+ $result =~ s{_}{}g;
+ }
# Bless it into our own version class
- $result = Module::Build::Version->new($result);
+ eval { $result = Module::Build::Version->new($result) };
+ die "Version '$result' from $self->{filename} does not appear to be valid:\n$eval\n\nThe fatal error was: $@\n"
+ if $@;
return $result;
}
diff --git a/cpan/Module-Build/lib/Module/Build/Notes.pm b/cpan/Module-Build/lib/Module/Build/Notes.pm
index fe98419759..a0506c64dc 100644
--- a/cpan/Module-Build/lib/Module/Build/Notes.pm
+++ b/cpan/Module-Build/lib/Module/Build/Notes.pm
@@ -4,7 +4,7 @@ package Module::Build::Notes;
use strict;
use vars qw($VERSION);
-$VERSION = '0.35';
+$VERSION = '0.35_08';
$VERSION = eval $VERSION;
use Data::Dumper;
use IO::File;
@@ -33,10 +33,10 @@ sub restore {
sub access {
my $self = shift;
return $self->read() unless @_;
-
+
my $key = shift;
return $self->read($key) unless @_;
-
+
my $value = shift;
$self->write({ $key => $value });
return $self->read($key);
@@ -61,7 +61,7 @@ sub read {
return $self->{new}{$key} if exists $self->{new}{$key};
return $self->{disk}{$key};
}
-
+
# Return all data
my $out = (keys %{$self->{new}}
? {%{$self->{disk}}, %{$self->{new}}}
@@ -79,7 +79,7 @@ sub _same {
sub write {
my ($self, $href) = @_;
$href ||= {};
-
+
@{$self->{new}}{ keys %$href } = values %$href; # Merge
# Do some optimization to avoid unnecessary writes
@@ -88,17 +88,17 @@ sub write {
next if ref $self->{disk}{$key} or !exists $self->{disk}{$key};
delete $self->{new}{$key} if $self->_same($self->{new}{$key}, $self->{disk}{$key});
}
-
+
if (my $file = $self->{file}) {
my ($vol, $dir, $base) = File::Spec->splitpath($file);
$dir = File::Spec->catpath($vol, $dir, '');
return unless -e $dir && -d $dir; # The user needs to arrange for this
return if -e $file and !keys %{ $self->{new} }; # Nothing to do
-
- @{$self->{disk}}{ keys %{$self->{new}} } = values %{$self->{new}}; # Merge
+
+ @{$self->{disk}}{ keys %{$self->{new}} } = values %{$self->{new}}; # Merge
$self->_dump($file, $self->{disk});
-
+
$self->{new} = {};
}
return $self->read;
@@ -106,18 +106,66 @@ sub write {
sub _dump {
my ($self, $file, $data) = @_;
-
+
my $fh = IO::File->new("> $file") or die "Can't create '$file': $!";
print {$fh} Module::Build::Dumper->_data_dump($data);
}
+my $orig_template = do { local $/; <DATA> };
+close DATA;
+
sub write_config_data {
my ($self, %args) = @_;
+ my $template = $orig_template;
+ $template =~ s/NOTES_NAME/$args{config_module}/g;
+ $template =~ s/MODULE_NAME/$args{module}/g;
+ $template =~ s/=begin private\n//;
+ $template =~ s/=end private/=cut/;
+
+ # strip out private POD markers we use to keep pod from being
+ # recognized for *this* source file
+ $template =~ s{$_\n}{} for '=begin private', '=end private';
+
my $fh = IO::File->new("> $args{file}") or die "Can't create '$args{file}': $!";
+ print {$fh} $template;
+ print {$fh} "\n__DATA__\n";
+ print {$fh} Module::Build::Dumper->_data_dump([$args{config_data}, $args{feature}, $args{auto_features}]);
+
+}
+
+1;
+
+
+=head1 NAME
+
+Module::Build::Notes - Create persistent distribution configuration modules
+
+=head1 DESCRIPTION
+
+This module is used internally by Module::Build to create persistent
+configuration files that can be installed with a distribution. See
+L<Module::Build::ConfigData> for an example.
+
+=head1 AUTHOR
- printf $fh <<'EOF', $args{config_module};
-package %s;
+Ken Williams <kwilliams@cpan.org>
+
+=head1 COPYRIGHT
+
+Copyright (c) 2001-2006 Ken Williams. All rights reserved.
+
+This library is free software; you can redistribute it and/or
+modify it under the same terms as Perl itself.
+
+=head1 SEE ALSO
+
+perl(1), L<Module::Build>(3)
+
+=cut
+
+__DATA__
+package NOTES_NAME;
use strict;
my $arrayref = eval do {local $/; <DATA>}
or die "Couldn't load ConfigData data: $@";
@@ -129,14 +177,14 @@ sub config { $config->{$_[1]} }
sub set_config { $config->{$_[1]} = $_[2] }
sub set_feature { $features->{$_[1]} = 0+!!$_[2] } # Constrain to 1 or 0
-sub auto_feature_names { grep !exists $features->{$_}, keys %%$auto_features }
+sub auto_feature_names { grep !exists $features->{$_}, keys %$auto_features }
sub feature_names {
- my @features = (keys %%$features, auto_feature_names());
+ my @features = (keys %$features, auto_feature_names());
@features;
}
-sub config_names { keys %%$config }
+sub config_names { keys %$config }
sub write {
my $me = __FILE__;
@@ -170,20 +218,20 @@ sub write {
sub feature {
my ($package, $key) = @_;
return $features->{$key} if exists $features->{$key};
-
+
my $info = $auto_features->{$key} or return 0;
-
- # Under perl 5.005, each(%%$foo) isn't working correctly when $foo
+
+ # Under perl 5.005, each(%$foo) isn't working correctly when $foo
# was reanimated with Data::Dumper and eval(). Not sure why, but
# copying to a new hash seems to solve it.
- my %%info = %%$info;
-
+ my %info = %$info;
+
require Module::Build; # XXX should get rid of this
- while (my ($type, $prereqs) = each %%info) {
+ while (my ($type, $prereqs) = each %info) {
next if $type eq 'description' || $type eq 'recommends';
-
- my %%p = %%$prereqs; # Ditto here.
- while (my ($modname, $spec) = each %%p) {
+
+ my %p = %$prereqs; # Ditto here.
+ while (my ($modname, $spec) = each %p) {
my $status = Module::Build->check_installed_status($modname, $spec);
if ((!$status->{ok}) xor ($type =~ /conflicts$/)) { return 0; }
if ( ! eval "require $modname; 1" ) { return 0; }
@@ -192,36 +240,32 @@ sub feature {
return 1;
}
-EOF
-
- my ($module_name, $notes_name) = ($args{module}, $args{config_module});
- printf $fh <<"EOF", $notes_name, $module_name;
+=begin private
=head1 NAME
-$notes_name - Configuration for $module_name
-
+NOTES_NAME - Configuration for MODULE_NAME
=head1 SYNOPSIS
- use $notes_name;
- \$value = $notes_name->config('foo');
- \$value = $notes_name->feature('bar');
-
- \@names = $notes_name->config_names;
- \@names = $notes_name->feature_names;
-
- $notes_name->set_config(foo => \$new_value);
- $notes_name->set_feature(bar => \$new_value);
- $notes_name->write; # Save changes
+ use NOTES_NAME;
+ $value = NOTES_NAME->config('foo');
+ $value = NOTES_NAME->feature('bar');
+
+ @names = NOTES_NAME->config_names;
+ @names = NOTES_NAME->feature_names;
+
+ NOTES_NAME->set_config(foo => $new_value);
+ NOTES_NAME->set_feature(bar => $new_value);
+ NOTES_NAME->write; # Save changes
=head1 DESCRIPTION
-This module holds the configuration data for the C<$module_name>
+This module holds the configuration data for the C<MODULE_NAME>
module. It also provides a programmatic interface for getting or
setting that configuration data. Note that in order to actually make
-changes, you'll have to have write access to the C<$notes_name>
+changes, you'll have to have write access to the C<NOTES_NAME>
module, and you should attempt to understand the repercussions of your
actions.
@@ -230,17 +274,17 @@ actions.
=over 4
-=item config(\$name)
+=item config($name)
Given a string argument, returns the value of the configuration item
by that name, or C<undef> if no such item exists.
-=item feature(\$name)
+=item feature($name)
Given a string argument, returns the value of the feature by that
name, or C<undef> if no such feature exists.
-=item set_config(\$name, \$value)
+=item set_config($name, $value)
Sets the configuration item with the given name to the given value.
The value may be any Perl scalar that will serialize correctly using
@@ -248,7 +292,7 @@ C<Data::Dumper>. This includes references, objects (usually), and
complex data structures. It probably does not include transient
things like filehandles or sockets.
-=item set_feature(\$name, \$value)
+=item set_feature($name, $value)
Sets the feature with the given name to the given boolean value. The
value will be converted to 0 or 1 automatically.
@@ -256,12 +300,12 @@ value will be converted to 0 or 1 automatically.
=item config_names()
Returns a list of all the names of config items currently defined in
-C<$notes_name>, or in scalar context the number of items.
+C<NOTES_NAME>, or in scalar context the number of items.
=item feature_names()
Returns a list of all the names of features currently defined in
-C<$notes_name>, or in scalar context the number of features.
+C<NOTES_NAME>, or in scalar context the number of features.
=item auto_feature_names()
@@ -273,24 +317,16 @@ a fixed value.
=item write()
Commits any changes from C<set_config()> and C<set_feature()> to disk.
-Requires write access to the C<$notes_name> module.
+Requires write access to the C<NOTES_NAME> module.
=back
=head1 AUTHOR
-C<$notes_name> was automatically created using C<Module::Build>.
+C<NOTES_NAME> was automatically created using C<Module::Build>.
C<Module::Build> was written by Ken Williams, but he holds no
-authorship claim or copyright claim to the contents of C<$notes_name>.
-
-=cut
+authorship claim or copyright claim to the contents of C<NOTES_NAME>.
-__DATA__
-
-EOF
-
- print {$fh} Module::Build::Dumper->_data_dump([$args{config_data}, $args{feature}, $args{auto_features}]);
-}
+=end private
-1;
diff --git a/cpan/Module-Build/lib/Module/Build/PPMMaker.pm b/cpan/Module-Build/lib/Module/Build/PPMMaker.pm
index 35b5a75317..74a5a73b07 100644
--- a/cpan/Module-Build/lib/Module/Build/PPMMaker.pm
+++ b/cpan/Module-Build/lib/Module/Build/PPMMaker.pm
@@ -1,8 +1,9 @@
package Module::Build::PPMMaker;
use strict;
+use Config;
use vars qw($VERSION);
-$VERSION = '0.35';
+$VERSION = '0.35_08';
$VERSION = eval $VERSION;
# This code is mostly borrowed from ExtUtils::MM_Unix 6.10_03, with a
@@ -34,7 +35,6 @@ sub make_ppd {
my $method = "dist_$info";
$dist{$info} = $build->$method() or die "Can't determine distribution's $info\n";
}
- $dist{version} = $self->_ppd_version($dist{version});
$self->_simple_xml_escape($_) foreach $dist{abstract}, @{$dist{author}};
@@ -42,21 +42,17 @@ sub make_ppd {
# various licenses
my $ppd = <<"PPD";
<SOFTPKG NAME=\"$dist{name}\" VERSION=\"$dist{version}\">
- <TITLE>$dist{name}</TITLE>
<ABSTRACT>$dist{abstract}</ABSTRACT>
@{[ join "\n", map " <AUTHOR>$_</AUTHOR>", @{$dist{author}} ]}
<IMPLEMENTATION>
PPD
- # TODO: We could set <IMPLTYPE VALUE="PERL" /> or maybe
- # <IMPLTYPE VALUE="PERL/XS" /> ???
-
# We don't include recommended dependencies because PPD has no way
# to distinguish them from normal dependencies. We don't include
# build_requires dependencies because the PPM installer doesn't
# build or test before installing. And obviously we don't include
# conflicts either.
-
+
foreach my $type (qw(requires)) {
my $prereq = $build->$type();
while (my ($modname, $spec) = each %$prereq) {
@@ -73,27 +69,18 @@ PPD
}
}
- # Another hack - dependencies are on modules, but PPD expects
- # them to be on distributions (I think).
- $modname =~ s/::/-/g;
-
- $ppd .= sprintf(<<'EOF', $modname, $self->_ppd_version($min_version));
- <DEPENDENCY NAME="%s" VERSION="%s" />
-EOF
+ # PPM4 spec requires a '::' for top level modules
+ $modname .= '::' unless $modname =~ /::/;
+ $ppd .= qq! <REQUIRE NAME="$modname" VERSION="$min_version" />\n!;
}
}
# We only include these tags if this module involves XS, on the
- # assumption that pure Perl modules will work on any OS. PERLCORE,
- # unfortunately, seems to indicate that a module works with _only_
- # that version of Perl, and so is only appropriate when a module
- # uses XS.
+ # assumption that pure Perl modules will work on any OS.
if (keys %{$build->find_xs_files}) {
my $perl_version = $self->_ppd_version($build->perl_version);
- $ppd .= sprintf(<<'EOF', $perl_version, $^O, $self->_varchname($build->config) );
- <PERLCORE VERSION="%s" />
- <OS NAME="%s" />
+ $ppd .= sprintf(<<'EOF', $self->_varchname($build->config) );
<ARCHITECTURE NAME="%s" />
EOF
}
@@ -113,7 +100,9 @@ EOF
my $ppd_file = "$dist{name}.ppd";
my $fh = IO::File->new(">$ppd_file")
or die "Cannot write to $ppd_file: $!";
- $fh->binmode(":utf8") if $fh->can("binmode");
+
+ $fh->binmode(":utf8")
+ if $fh->can('binmode') && $] >= 5.008 && $Config{useperlio};
print $fh $ppd;
close $fh;
@@ -148,7 +137,7 @@ sub _varchname { # Copied from PPM.pm
'<' => '&lt;',
);
my $rx = join '|', keys %escapes;
-
+
sub _simple_xml_escape {
$_[1] =~ s/($rx)/$escapes{$1}/go;
}
diff --git a/cpan/Module-Build/lib/Module/Build/Platform/Amiga.pm b/cpan/Module-Build/lib/Module/Build/Platform/Amiga.pm
index 5ce8cf58a2..b31a9635ec 100644
--- a/cpan/Module-Build/lib/Module/Build/Platform/Amiga.pm
+++ b/cpan/Module-Build/lib/Module/Build/Platform/Amiga.pm
@@ -2,7 +2,7 @@ package Module::Build::Platform::Amiga;
use strict;
use vars qw($VERSION);
-$VERSION = '0.35';
+$VERSION = '0.35_08';
$VERSION = eval $VERSION;
use Module::Build::Base;
diff --git a/cpan/Module-Build/lib/Module/Build/Platform/Default.pm b/cpan/Module-Build/lib/Module/Build/Platform/Default.pm
index df29af5f68..b0e83a3d73 100644
--- a/cpan/Module-Build/lib/Module/Build/Platform/Default.pm
+++ b/cpan/Module-Build/lib/Module/Build/Platform/Default.pm
@@ -2,7 +2,7 @@ package Module::Build::Platform::Default;
use strict;
use vars qw($VERSION);
-$VERSION = '0.35';
+$VERSION = '0.35_08';
$VERSION = eval $VERSION;
use Module::Build::Base;
diff --git a/cpan/Module-Build/lib/Module/Build/Platform/EBCDIC.pm b/cpan/Module-Build/lib/Module/Build/Platform/EBCDIC.pm
index d68836c1a3..4365b12b31 100644
--- a/cpan/Module-Build/lib/Module/Build/Platform/EBCDIC.pm
+++ b/cpan/Module-Build/lib/Module/Build/Platform/EBCDIC.pm
@@ -2,7 +2,7 @@ package Module::Build::Platform::EBCDIC;
use strict;
use vars qw($VERSION);
-$VERSION = '0.35';
+$VERSION = '0.35_08';
$VERSION = eval $VERSION;
use Module::Build::Base;
diff --git a/cpan/Module-Build/lib/Module/Build/Platform/MPEiX.pm b/cpan/Module-Build/lib/Module/Build/Platform/MPEiX.pm
index a835c30d49..c7353783dd 100644
--- a/cpan/Module-Build/lib/Module/Build/Platform/MPEiX.pm
+++ b/cpan/Module-Build/lib/Module/Build/Platform/MPEiX.pm
@@ -2,7 +2,7 @@ package Module::Build::Platform::MPEiX;
use strict;
use vars qw($VERSION);
-$VERSION = '0.35';
+$VERSION = '0.35_08';
$VERSION = eval $VERSION;
use Module::Build::Base;
diff --git a/cpan/Module-Build/lib/Module/Build/Platform/MacOS.pm b/cpan/Module-Build/lib/Module/Build/Platform/MacOS.pm
index 9c9281adac..2c74942857 100644
--- a/cpan/Module-Build/lib/Module/Build/Platform/MacOS.pm
+++ b/cpan/Module-Build/lib/Module/Build/Platform/MacOS.pm
@@ -2,7 +2,7 @@ package Module::Build::Platform::MacOS;
use strict;
use vars qw($VERSION);
-$VERSION = '0.35';
+$VERSION = '0.35_08';
$VERSION = eval $VERSION;
use Module::Build::Base;
use vars qw(@ISA);
@@ -15,17 +15,17 @@ sub have_forkpipe { 0 }
sub new {
my $class = shift;
my $self = $class->SUPER::new(@_);
-
+
# $Config{sitelib} and $Config{sitearch} are, unfortunately, missing.
foreach ('sitelib', 'sitearch') {
$self->config($_ => $self->config("install$_"))
unless $self->config($_);
}
-
+
# For some reason $Config{startperl} is filled with a bunch of crap.
(my $sp = $self->config('startperl')) =~ s/.*Exit \{Status\}\s//;
$self->config(startperl => $sp);
-
+
return $self;
}
@@ -42,7 +42,7 @@ sub dispatch {
if( !@_ and !@ARGV ) {
require MacPerl;
-
+
# What comes first in the action list.
my @action_list = qw(build test install);
my %actions = map {+($_, 1)} $self->known_actions;
@@ -53,17 +53,17 @@ sub dispatch {
foreach (@action_list) {
$_ .= ' *' if $toolserver{$_};
}
-
+
my $cmd = MacPerl::Pick("What build command? ('*' requires ToolServer)", @action_list);
return unless defined $cmd;
$cmd =~ s/ \*$//;
$ARGV[0] = ($cmd);
-
+
my $args = MacPerl::Ask('Any extra arguments? (ie. verbose=1)', '');
return unless defined $args;
push @ARGV, $self->split_like_shell($args);
}
-
+
$self->SUPER::dispatch(@_);
}
@@ -82,10 +82,10 @@ sub ACTION_realclean {
sub ACTION_install {
my $self = shift;
-
+
return $self->SUPER::ACTION_install(@_)
if eval {ExtUtils::Install->VERSION('1.30'); 1};
-
+
local $^W = 0; # Avoid a 'redefine' warning
local *ExtUtils::Install::find = sub {
my ($code, @dirs) = @_;
@@ -94,7 +94,7 @@ sub ACTION_install {
return File::Find::find($code, @dirs);
};
-
+
return $self->SUPER::ACTION_install(@_);
}
diff --git a/cpan/Module-Build/lib/Module/Build/Platform/RiscOS.pm b/cpan/Module-Build/lib/Module/Build/Platform/RiscOS.pm
index c240750c46..9deb097963 100644
--- a/cpan/Module-Build/lib/Module/Build/Platform/RiscOS.pm
+++ b/cpan/Module-Build/lib/Module/Build/Platform/RiscOS.pm
@@ -2,7 +2,7 @@ package Module::Build::Platform::RiscOS;
use strict;
use vars qw($VERSION);
-$VERSION = '0.35';
+$VERSION = '0.35_08';
$VERSION = eval $VERSION;
use Module::Build::Base;
diff --git a/cpan/Module-Build/lib/Module/Build/Platform/Unix.pm b/cpan/Module-Build/lib/Module/Build/Platform/Unix.pm
index 879ca3ad4e..43f585fd4f 100644
--- a/cpan/Module-Build/lib/Module/Build/Platform/Unix.pm
+++ b/cpan/Module-Build/lib/Module/Build/Platform/Unix.pm
@@ -2,7 +2,7 @@ package Module::Build::Platform::Unix;
use strict;
use vars qw($VERSION);
-$VERSION = '0.35';
+$VERSION = '0.35_08';
$VERSION = eval $VERSION;
use Module::Build::Base;
diff --git a/cpan/Module-Build/lib/Module/Build/Platform/VMS.pm b/cpan/Module-Build/lib/Module/Build/Platform/VMS.pm
index 3305154b2d..13d350d8ff 100644
--- a/cpan/Module-Build/lib/Module/Build/Platform/VMS.pm
+++ b/cpan/Module-Build/lib/Module/Build/Platform/VMS.pm
@@ -2,7 +2,7 @@ package Module::Build::Platform::VMS;
use strict;
use vars qw($VERSION);
-$VERSION = '0.35';
+$VERSION = '0.35_08';
$VERSION = eval $VERSION;
use Module::Build::Base;
@@ -131,22 +131,22 @@ sub _quote_args {
# or if we get a single arg that is an array reference, quote the
# elements of it and return the reference.
my ($self, @args) = @_;
- my $got_arrayref = (scalar(@args) == 1
- && UNIVERSAL::isa($args[0], 'ARRAY'))
- ? 1
+ my $got_arrayref = (scalar(@args) == 1
+ && UNIVERSAL::isa($args[0], 'ARRAY'))
+ ? 1
: 0;
# Do not quote qualifiers that begin with '/'.
- map { if (!/^\//) {
+ map { if (!/^\//) {
$_ =~ s/\"/""/g; # escape C<"> by doubling
$_ = q(").$_.q(");
}
}
- ($got_arrayref ? @{$args[0]}
+ ($got_arrayref ? @{$args[0]}
: @args
);
- return $got_arrayref ? $args[0]
+ return $got_arrayref ? $args[0]
: join(' ', @args);
}
@@ -173,6 +173,62 @@ sub _backticks {
return `$cmd $args`;
}
+=item find_command
+
+Local an executable program
+
+=cut
+
+sub find_command {
+ my ($self, $command) = @_;
+
+ # a lot of VMS executables have a symbol defined
+ # check those first
+ if ( $^O eq 'VMS' ) {
+ require VMS::DCLsym;
+ my $syms = VMS::DCLsym->new;
+ return $command if scalar $syms->getsym( uc $command );
+ }
+
+ $self->SUPER::find_command($command);
+}
+
+# _maybe_command copied from ExtUtils::MM_VMS::maybe_command
+
+=item _maybe_command (override)
+
+Follows VMS naming conventions for executable files.
+If the name passed in doesn't exactly match an executable file,
+appends F<.Exe> (or equivalent) to check for executable image, and F<.Com>
+to check for DCL procedure. If this fails, checks directories in DCL$PATH
+and finally F<Sys$System:> for an executable file having the name specified,
+with or without the F<.Exe>-equivalent suffix.
+
+=cut
+
+sub _maybe_command {
+ my($self,$file) = @_;
+ return $file if -x $file && ! -d _;
+ my(@dirs) = ('');
+ my(@exts) = ('',$Config{'exe_ext'},'.exe','.com');
+
+ if ($file !~ m![/:>\]]!) {
+ for (my $i = 0; defined $ENV{"DCL\$PATH;$i"}; $i++) {
+ my $dir = $ENV{"DCL\$PATH;$i"};
+ $dir .= ':' unless $dir =~ m%[\]:]$%;
+ push(@dirs,$dir);
+ }
+ push(@dirs,'Sys$System:');
+ foreach my $dir (@dirs) {
+ my $sysfile = "$dir$file";
+ foreach my $ext (@exts) {
+ return $file if -x "$sysfile$ext" && ! -d _;
+ }
+ }
+ }
+ return;
+}
+
=item do_system
Override to ensure that we quote the arguments but not the command.
@@ -182,7 +238,7 @@ Override to ensure that we quote the arguments but not the command.
sub do_system {
# The command must not be quoted but the arguments to it must be.
my ($self, @cmd) = @_;
- $self->log_info("@cmd\n");
+ $self->log_verbose("@cmd\n");
my $cmd = shift @cmd;
my $args = $self->_quote_args(@cmd);
return !system("$cmd $args");
@@ -205,7 +261,7 @@ sub oneliner {
=item _infer_xs_spec
-Inherit the standard version but tweak the library file name to be
+Inherit the standard version but tweak the library file name to be
something Dynaloader can find.
=cut
@@ -250,7 +306,7 @@ sub rscan_dir {
=item dist_dir
-Inherit the standard version but replace embedded dots with underscores because
+Inherit the standard version but replace embedded dots with underscores because
a dot is the directory delimiter on VMS.
=cut
@@ -265,7 +321,7 @@ sub dist_dir {
=item man3page_name
-Inherit the standard version but chop the extra manpage delimiter off the front if
+Inherit the standard version but chop the extra manpage delimiter off the front if
there is one. The VMS version of splitdir('[.foo]') returns '', 'foo'.
=cut
@@ -367,7 +423,7 @@ sub _detildefy {
$newdirs = File::Spec::Unix->catdir(@hdirs, @backup, @dirs);
}
-
+
# Now put the two cases back together
$arg = File::Spec::Unix->catpath($hvol, $newdirs, $file);
@@ -446,7 +502,7 @@ sub _unix_rpt {
$unix_rpt = VMS::Feature::current("filename_unix_report");
} else {
my $env_unix_rpt = $ENV{'DECC$FILENAME_UNIX_REPORT'} || '';
- $unix_rpt = $env_unix_rpt =~ /^[ET1]/i;
+ $unix_rpt = $env_unix_rpt =~ /^[ET1]/i;
}
return $unix_rpt;
}
@@ -459,7 +515,7 @@ sub _efs {
$efs = VMS::Feature::current("efs_charset");
} else {
my $env_efs = $ENV{'DECC$EFS_CHARSET'} || '';
- $efs = $env_efs =~ /^[ET1]/i;
+ $efs = $env_efs =~ /^[ET1]/i;
}
return $efs;
}
diff --git a/cpan/Module-Build/lib/Module/Build/Platform/VOS.pm b/cpan/Module-Build/lib/Module/Build/Platform/VOS.pm
index be46a80416..2061b2cacb 100644
--- a/cpan/Module-Build/lib/Module/Build/Platform/VOS.pm
+++ b/cpan/Module-Build/lib/Module/Build/Platform/VOS.pm
@@ -2,7 +2,7 @@ package Module::Build::Platform::VOS;
use strict;
use vars qw($VERSION);
-$VERSION = '0.35';
+$VERSION = '0.35_08';
$VERSION = eval $VERSION;
use Module::Build::Base;
diff --git a/cpan/Module-Build/lib/Module/Build/Platform/Windows.pm b/cpan/Module-Build/lib/Module/Build/Platform/Windows.pm
index 6cf9da9cc3..fcaef5a409 100644
--- a/cpan/Module-Build/lib/Module/Build/Platform/Windows.pm
+++ b/cpan/Module-Build/lib/Module/Build/Platform/Windows.pm
@@ -2,7 +2,7 @@ package Module::Build::Platform::Windows;
use strict;
use vars qw($VERSION);
-$VERSION = '0.35';
+$VERSION = '0.35_08';
$VERSION = eval $VERSION;
use Config;
@@ -39,7 +39,7 @@ sub ACTION_realclean {
if ( lc $basename eq lc $self->build_script ) {
if ( $self->build_bat ) {
- $self->log_info("Deleting $basename.bat\n");
+ $self->log_verbose("Deleting $basename.bat\n");
my $full_progname = $0;
$full_progname =~ s/(?:\.bat)?$/.bat/i;
@@ -207,22 +207,22 @@ sub split_like_shell {
# into words. The algorithm below was bashed out by Randy and Ken
# (mostly Randy), and there are a lot of regression tests, so we
# should feel free to adjust if desired.
-
+
(my $self, local $_) = @_;
-
+
return @$_ if defined() && UNIVERSAL::isa($_, 'ARRAY');
-
+
my @argv;
return @argv unless defined() && length();
-
+
my $arg = '';
my( $i, $quote_mode ) = ( 0, 0 );
-
+
while ( $i < length() ) {
-
+
my $ch = substr( $_, $i , 1 );
my $next_ch = substr( $_, $i+1, 1 );
-
+
if ( $ch eq '\\' && $next_ch eq '"' ) {
$arg .= '"';
$i++;
@@ -249,10 +249,10 @@ sub split_like_shell {
} else {
$arg .= $ch;
}
-
+
$i++;
}
-
+
push( @argv, $arg ) if defined( $arg ) && length( $arg );
return @argv;
}
@@ -273,6 +273,27 @@ sub do_system {
return !$status;
}
+# Copied from ExtUtils::MM_Win32
+sub _maybe_command {
+ my($self,$file) = @_;
+ my @e = exists($ENV{'PATHEXT'})
+ ? split(/;/, $ENV{PATHEXT})
+ : qw(.com .exe .bat .cmd);
+ my $e = '';
+ for (@e) { $e .= "\Q$_\E|" }
+ chop $e;
+ # see if file ends in one of the known extensions
+ if ($file =~ /($e)$/i) {
+ return $file if -e $file;
+ }
+ else {
+ for (@e) {
+ return "$file$_" if -e "$file$_";
+ }
+ }
+ return;
+}
+
1;
diff --git a/cpan/Module-Build/lib/Module/Build/Platform/aix.pm b/cpan/Module-Build/lib/Module/Build/Platform/aix.pm
index 45feb3cdd4..7ba3c322b6 100644
--- a/cpan/Module-Build/lib/Module/Build/Platform/aix.pm
+++ b/cpan/Module-Build/lib/Module/Build/Platform/aix.pm
@@ -2,7 +2,7 @@ package Module::Build::Platform::aix;
use strict;
use vars qw($VERSION);
-$VERSION = '0.35';
+$VERSION = '0.35_08';
$VERSION = eval $VERSION;
use Module::Build::Platform::Unix;
diff --git a/cpan/Module-Build/lib/Module/Build/Platform/cygwin.pm b/cpan/Module-Build/lib/Module/Build/Platform/cygwin.pm
index 62a6461ce2..8b882ed293 100644
--- a/cpan/Module-Build/lib/Module/Build/Platform/cygwin.pm
+++ b/cpan/Module-Build/lib/Module/Build/Platform/cygwin.pm
@@ -2,7 +2,7 @@ package Module::Build::Platform::cygwin;
use strict;
use vars qw($VERSION);
-$VERSION = '0.35';
+$VERSION = '0.35_08';
$VERSION = eval $VERSION;
use Module::Build::Platform::Unix;
@@ -13,6 +13,22 @@ sub manpage_separator {
'.'
}
+# Copied from ExtUtils::MM_Cygwin::maybe_command()
+# If our path begins with F</cygdrive/> then we use C<ExtUtils::MM_Win32>
+# to determine if it may be a command. Otherwise we use the tests
+# from C<ExtUtils::MM_Unix>.
+
+sub _maybe_command {
+ my ($self, $file) = @_;
+
+ if ($file =~ m{^/cygdrive/}i) {
+ require Module::Build::Platform::Win32;
+ return Module::Build::Platform::Win32->_maybe_command($file);
+ }
+
+ return $self->SUPER::_maybe_command($file);
+}
+
1;
__END__
diff --git a/cpan/Module-Build/lib/Module/Build/Platform/darwin.pm b/cpan/Module-Build/lib/Module/Build/Platform/darwin.pm
index 39e9e36911..145933d478 100644
--- a/cpan/Module-Build/lib/Module/Build/Platform/darwin.pm
+++ b/cpan/Module-Build/lib/Module/Build/Platform/darwin.pm
@@ -2,7 +2,7 @@ package Module::Build::Platform::darwin;
use strict;
use vars qw($VERSION);
-$VERSION = '0.35';
+$VERSION = '0.35_08';
$VERSION = eval $VERSION;
use Module::Build::Platform::Unix;
diff --git a/cpan/Module-Build/lib/Module/Build/Platform/os2.pm b/cpan/Module-Build/lib/Module/Build/Platform/os2.pm
index ace01a3291..b6615c82c3 100644
--- a/cpan/Module-Build/lib/Module/Build/Platform/os2.pm
+++ b/cpan/Module-Build/lib/Module/Build/Platform/os2.pm
@@ -2,7 +2,7 @@ package Module::Build::Platform::os2;
use strict;
use vars qw($VERSION);
-$VERSION = '0.35';
+$VERSION = '0.35_08';
$VERSION = eval $VERSION;
use Module::Build::Platform::Unix;
@@ -13,6 +13,16 @@ sub manpage_separator { '.' }
sub have_forkpipe { 0 }
+# Copied from ExtUtils::MM_OS2::maybe_command
+sub _maybe_command {
+ my($self,$file) = @_;
+ $file =~ s,[/\\]+,/,g;
+ return $file if -x $file && ! -d _;
+ return "$file.exe" if -x "$file.exe" && ! -d _;
+ return "$file.cmd" if -x "$file.cmd" && ! -d _;
+ return;
+}
+
1;
__END__
diff --git a/cpan/Module-Build/lib/Module/Build/PodParser.pm b/cpan/Module-Build/lib/Module/Build/PodParser.pm
index b17b80b189..7a94e772ed 100644
--- a/cpan/Module-Build/lib/Module/Build/PodParser.pm
+++ b/cpan/Module-Build/lib/Module/Build/PodParser.pm
@@ -2,7 +2,7 @@ package Module::Build::PodParser;
use strict;
use vars qw($VERSION);
-$VERSION = '0.35';
+$VERSION = '0.35_08';
$VERSION = eval $VERSION;
use vars qw(@ISA);
@@ -33,31 +33,31 @@ sub new {
sub _myparse_from_filehandle {
my ($self, $fh) = @_;
-
+
local $_;
while (<$fh>) {
next unless /^=(?!cut)/ .. /^=cut/; # in POD
last if ($self->{abstract}) = /^ (?: [a-z:]+ \s+ - \s+ ) (.*\S) /ix;
}
-
+
my @author;
while (<$fh>) {
- next unless /^=head1\s+AUTHORS?/ ... /^=/;
+ next unless /^=head1\s+AUTHORS?/i ... /^=/;
next if /^=/;
push @author, $_ if /\@/;
}
return unless @author;
s/^\s+|\s+$//g foreach @author;
-
+
$self->{author} = \@author;
-
+
return;
}
sub get_abstract {
my $self = shift;
return $self->{abstract} if defined $self->{abstract};
-
+
$self->parse_from_filehandle($self->{fh});
return $self->{abstract};
@@ -66,7 +66,7 @@ sub get_abstract {
sub get_author {
my $self = shift;
return $self->{author} if defined $self->{author};
-
+
$self->parse_from_filehandle($self->{fh});
return $self->{author} || [];
@@ -92,10 +92,10 @@ sub textblock {
my ($self, $text) = @_;
$text =~ s/^\s+//;
$text =~ s/\s+$//;
- if ($self->{_head} eq 'NAME') {
+ if (uc $self->{_head} eq 'NAME') {
my ($name, $abstract) = split( /\s+-\s+/, $text, 2 );
$self->{abstract} = $abstract;
- } elsif ($self->{_head} =~ /^AUTHORS?$/) {
+ } elsif ($self->{_head} =~ /^AUTHORS?$/i) {
push @{$self->{author}}, $text if $text =~ /\@/;
}
}
diff --git a/cpan/Module-Build/lib/Module/Build/Version.pm b/cpan/Module-Build/lib/Module/Build/Version.pm
index 0664d432ab..4a1b961fbd 100644
--- a/cpan/Module-Build/lib/Module/Build/Version.pm
+++ b/cpan/Module-Build/lib/Module/Build/Version.pm
@@ -81,7 +81,7 @@ sub import {
map { $args{$_} = 1 } @_
}
else { # no parameters at all on use line
- %args =
+ args =
(
qv => 1,
'UNIVERSAL::VERSION' => 1,
@@ -89,9 +89,9 @@ sub import {
}
my $callpkg = caller();
-
+
if (exists($args{declare})) {
- *{$callpkg."::declare"} =
+ *{$callpkg."::declare"} =
sub {return $class->declare(shift) }
unless defined(&{$callpkg.'::declare'});
}
@@ -155,7 +155,7 @@ sub new
{
my ($class, $value) = @_;
my $self = bless ({}, ref ($class) || $class);
-
+
if ( ref($value) && eval('$value->isa("version")') ) {
# Can copy the elements directly
$self->{version} = [ @{$value->{version} } ];
@@ -193,7 +193,7 @@ sub new
$value = sprintf("%.9f",$value);
$value =~ s/(0+)$//; # trim trailing zeros
}
-
+
# This is not very efficient, but it is morally equivalent
# to the XS code (as that is the reference implementation).
# See vutil/vutil.c for details
@@ -215,7 +215,7 @@ sub new
}
$start = $last = $pos = $s;
-
+
# pre-scan the input string to check for decimals/underbars
while ( substr($value,$pos,1) =~ /[._\d,]/ ) {
if ( substr($value,$pos,1) eq '.' ) {
@@ -300,7 +300,7 @@ sub new
$orev = $rev;
$rev += substr($value,$s,1) * $mult;
$mult /= 10;
- if ( abs($orev) > abs($rev)
+ if ( abs($orev) > abs($rev)
|| abs($rev) > abs($VERSION_MAX) ) {
if ( warnings::enabled("overflow") ) {
require Carp;
@@ -320,7 +320,7 @@ sub new
$orev = $rev;
$rev += substr($value,$end,1) * $mult;
$mult *= 10;
- if ( abs($orev) > abs($rev)
+ if ( abs($orev) > abs($rev)
|| abs($rev) > abs($VERSION_MAX) ) {
if ( warnings::enabled("overflow") ) {
require Carp;
@@ -335,15 +335,15 @@ sub new
# Append revision
push @{$self->{version}}, $rev;
- if ( substr($value,$pos,1) eq '.'
+ if ( substr($value,$pos,1) eq '.'
&& substr($value,$pos+1,1) =~ /\d/ ) {
$s = ++$pos;
}
- elsif ( substr($value,$pos,1) eq '_'
+ elsif ( substr($value,$pos,1) eq '_'
&& substr($value,$pos+1,1) =~ /\d/ ) {
$s = ++$pos;
}
- elsif ( substr($value,$pos,1) eq ','
+ elsif ( substr($value,$pos,1) eq ','
&& substr($value,$pos+1,1) =~ /\d/ ) {
$s = ++$pos;
}
@@ -400,7 +400,7 @@ sub new
*parse = \&new;
-sub numify
+sub numify
{
my ($self) = @_;
unless (_verify($self)) {
@@ -441,7 +441,7 @@ sub numify
return $string;
}
-sub normal
+sub normal
{
my ($self) = @_;
unless (_verify($self)) {
@@ -484,9 +484,9 @@ sub stringify
require Carp;
Carp::croak("Invalid version object");
}
- return exists $self->{original}
- ? $self->{original}
- : exists $self->{qv}
+ return exists $self->{original}
+ ? $self->{original}
+ : exists $self->{qv}
? $self->normal
: $self->numify;
}
@@ -524,8 +524,8 @@ sub vcmp
}
# tiebreaker for alpha with identical terms
- if ( $retval == 0
- && $l == $r
+ if ( $retval == 0
+ && $l == $r
&& $left->{version}[$m] == $right->{version}[$m]
&& ( $lalpha || $ralpha ) ) {
@@ -557,7 +557,7 @@ sub vcmp
}
}
- return $retval;
+ return $retval;
}
sub vbool {
@@ -565,8 +565,8 @@ sub vbool {
return vcmp($self,$self->new("0"),1);
}
-sub vnoop {
- require Carp;
+sub vnoop {
+ require Carp;
Carp::croak("operation not supported with version object");
}
@@ -644,7 +644,7 @@ sub _VERSION {
if ( defined $req ) {
unless ( defined $version ) {
require Carp;
- my $msg = $] < 5.006
+ my $msg = $] < 5.006
? "$class version $req required--this is only version "
: "$class does not define \$$class\::VERSION"
."--version check failed";
@@ -662,14 +662,14 @@ sub _VERSION {
if ( $req > $version ) {
require Carp;
if ( $req->is_qv ) {
- Carp::croak(
+ Carp::croak(
sprintf ("%s version %s required--".
"this is only version %s", $class,
$req->normal, $version->normal)
);
}
else {
- Carp::croak(
+ Carp::croak(
sprintf ("%s version %s required--".
"this is only version %s", $class,
$req->stringify, $version->stringify)
diff --git a/cpan/Module-Build/lib/Module/Build/YAML.pm b/cpan/Module-Build/lib/Module/Build/YAML.pm
index 4a181ad1c9..2da91f2256 100644
--- a/cpan/Module-Build/lib/Module/Build/YAML.pm
+++ b/cpan/Module-Build/lib/Module/Build/YAML.pm
@@ -1,161 +1,600 @@
+# Adapted from YAML::Tiny 1.40
package Module::Build::YAML;
use strict;
-use vars qw($VERSION @EXPORT @EXPORT_OK);
-$VERSION = "0.50";
-@EXPORT = ();
-@EXPORT_OK = qw(Dump Load DumpFile LoadFile);
+use Carp 'croak';
+# UTF Support?
+sub HAVE_UTF8 () { $] >= 5.007003 }
+BEGIN {
+ if ( HAVE_UTF8 ) {
+ # The string eval helps hide this from Test::MinimumVersion
+ eval "require utf8;";
+ die "Failed to load UTF-8 support" if $@;
+ }
+
+ # Class structure
+ require 5.004;
+
+ $Module::Build::YAML::VERSION = '1.40';
+
+ # Error storage
+ $Module::Build::YAML::errstr = '';
+}
+
+# The character class of all characters we need to escape
+# NOTE: Inlined, since it's only used once
+# my $RE_ESCAPE = '[\\x00-\\x08\\x0b-\\x0d\\x0e-\\x1f\"\n]';
+
+# Printed form of the unprintable characters in the lowest range
+# of ASCII characters, listed by ASCII ordinal position.
+my @UNPRINTABLE = qw(
+ z x01 x02 x03 x04 x05 x06 a
+ x08 t n v f r x0e x0f
+ x10 x11 x12 x13 x14 x15 x16 x17
+ x18 x19 x1a e x1c x1d x1e x1f
+);
+
+# Printable characters for escapes
+my %UNESCAPES = (
+ z => "\x00", a => "\x07", t => "\x09",
+ n => "\x0a", v => "\x0b", f => "\x0c",
+ r => "\x0d", e => "\x1b", '\\' => '\\',
+);
+
+# Special magic boolean words
+my %QUOTE = map { $_ => 1 } qw{
+ null Null NULL
+ y Y yes Yes YES n N no No NO
+ true True TRUE false False FALSE
+ on On ON off Off OFF
+};
+
+#####################################################################
+# Implementation
+
+# Create an empty Module::Build::YAML object
sub new {
- my $this = shift;
- my $class = ref($this) || $this;
- my $self = {};
- bless $self, $class;
- return($self);
+ my $class = shift;
+ bless [ @_ ], $class;
}
-sub Dump {
- shift if ($_[0] eq __PACKAGE__ || ref($_[0]) eq __PACKAGE__);
- my $yaml = "";
- foreach my $item (@_) {
- $yaml .= "---\n";
- $yaml .= &_yaml_chunk("", $item);
- }
- return $yaml;
+# Create an object from a file
+sub read {
+ my $class = ref $_[0] ? ref shift : shift;
+
+ # Check the file
+ my $file = shift or return $class->_error( 'You did not specify a file name' );
+ return $class->_error( "File '$file' does not exist" ) unless -e $file;
+ return $class->_error( "'$file' is a directory, not a file" ) unless -f _;
+ return $class->_error( "Insufficient permissions to read '$file'" ) unless -r _;
+
+ # Slurp in the file
+ local $/ = undef;
+ local *CFG;
+ unless ( open(CFG, $file) ) {
+ return $class->_error("Failed to open file '$file': $!");
+ }
+ my $contents = <CFG>;
+ unless ( close(CFG) ) {
+ return $class->_error("Failed to close file '$file': $!");
+ }
+
+ $class->read_string( $contents );
}
-sub Load {
- shift if ($_[0] eq __PACKAGE__ || ref($_[0]) eq __PACKAGE__);
- die "not yet implemented";
+# Create an object from a string
+sub read_string {
+ my $class = ref $_[0] ? ref shift : shift;
+ my $self = bless [], $class;
+ my $string = $_[0];
+ unless ( defined $string ) {
+ return $self->_error("Did not provide a string to load");
+ }
+
+ # Byte order marks
+ # NOTE: Keeping this here to educate maintainers
+ # my %BOM = (
+ # "\357\273\277" => 'UTF-8',
+ # "\376\377" => 'UTF-16BE',
+ # "\377\376" => 'UTF-16LE',
+ # "\377\376\0\0" => 'UTF-32LE'
+ # "\0\0\376\377" => 'UTF-32BE',
+ # );
+ if ( $string =~ /^(?:\376\377|\377\376|\377\376\0\0|\0\0\376\377)/ ) {
+ return $self->_error("Stream has a non UTF-8 BOM");
+ } else {
+ # Strip UTF-8 bom if found, we'll just ignore it
+ $string =~ s/^\357\273\277//;
+ }
+
+ # Try to decode as utf8
+ utf8::decode($string) if HAVE_UTF8;
+
+ # Check for some special cases
+ return $self unless length $string;
+ unless ( $string =~ /[\012\015]+\z/ ) {
+ return $self->_error("Stream does not end with newline character");
+ }
+
+ # Split the file into lines
+ my @lines = grep { ! /^\s*(?:\#.*)?\z/ }
+ split /(?:\015{1,2}\012|\015|\012)/, $string;
+
+ # Strip the initial YAML header
+ @lines and $lines[0] =~ /^\%YAML[: ][\d\.]+.*\z/ and shift @lines;
+
+ # A nibbling parser
+ while ( @lines ) {
+ # Do we have a document header?
+ if ( $lines[0] =~ /^---\s*(?:(.+)\s*)?\z/ ) {
+ # Handle scalar documents
+ shift @lines;
+ if ( defined $1 and $1 !~ /^(?:\#.+|\%YAML[: ][\d\.]+)\z/ ) {
+ push @$self, $self->_read_scalar( "$1", [ undef ], \@lines );
+ next;
+ }
+ }
+
+ if ( ! @lines or $lines[0] =~ /^(?:---|\.\.\.)/ ) {
+ # A naked document
+ push @$self, undef;
+ while ( @lines and $lines[0] !~ /^---/ ) {
+ shift @lines;
+ }
+
+ } elsif ( $lines[0] =~ /^\s*\-/ ) {
+ # An array at the root
+ my $document = [ ];
+ push @$self, $document;
+ $self->_read_array( $document, [ 0 ], \@lines );
+
+ } elsif ( $lines[0] =~ /^(\s*)\S/ ) {
+ # A hash at the root
+ my $document = { };
+ push @$self, $document;
+ $self->_read_hash( $document, [ length($1) ], \@lines );
+
+ } else {
+ croak("Module::Build::YAML failed to classify the line '$lines[0]'");
+ }
+ }
+
+ $self;
}
-# This is basically copied out of YAML.pm and simplified a little.
-sub DumpFile {
- shift if ($_[0] eq __PACKAGE__ || ref($_[0]) eq __PACKAGE__);
- my $filename = shift;
- local $/ = "\n"; # reset special to "sane"
- my $mode = '>';
- if ($filename =~ /^\s*(>{1,2})\s*(.*)$/) {
- ($mode, $filename) = ($1, $2);
- }
- open my $OUT, "$mode $filename"
- or die "Can't open $filename for writing: $!";
- binmode($OUT, ':utf8') if $] >= 5.008;
- print $OUT Dump(@_);
- close $OUT;
-}
-
-# This is basically copied out of YAML.pm and simplified a little.
-sub LoadFile {
- shift if ($_[0] eq __PACKAGE__ || ref($_[0]) eq __PACKAGE__);
- my $filename = shift;
- open my $IN, $filename
- or die "Can't open $filename for reading: $!";
- binmode($IN, ':utf8') if $] >= 5.008;
- return Load(do { local $/; <$IN> });
- close $IN;
-}
-
-sub _yaml_chunk {
- my ($indent, $values) = @_;
- my $yaml_chunk = "";
- my $ref = ref($values);
- my ($value, @allkeys, %keyseen);
- if (!$ref) { # a scalar
- $yaml_chunk .= &_yaml_value($values) . "\n";
- }
- elsif ($ref eq "ARRAY") {
- foreach $value (@$values) {
- $yaml_chunk .= "$indent-";
- $ref = ref($value);
- if (!$ref) {
- $yaml_chunk .= " " . &_yaml_value($value) . "\n";
- }
- else {
- $yaml_chunk .= "\n";
- $yaml_chunk .= &_yaml_chunk("$indent ", $value);
- }
- }
- }
- else { # assume "HASH"
- if ($values->{_order} && ref($values->{_order}) eq "ARRAY") {
- @allkeys = @{$values->{_order}};
- $values = { %$values };
- delete $values->{_order};
- }
- push(@allkeys, sort keys %$values);
- foreach my $key (@allkeys) {
- next if (!defined $key || $key eq "" || $keyseen{$key});
- $keyseen{$key} = 1;
- $yaml_chunk .= "$indent$key:";
- $value = $values->{$key};
- $ref = ref($value);
- if (!$ref) {
- $yaml_chunk .= " " . &_yaml_value($value) . "\n";
- }
- else {
- $yaml_chunk .= "\n";
- $yaml_chunk .= &_yaml_chunk("$indent ", $value);
- }
- }
- }
- return($yaml_chunk);
-}
-
-sub _yaml_value {
- my ($value) = @_;
- # undefs become ~
- return '~' if not defined $value;
-
- # empty strings will become empty strings
- return '""' if $value eq '';
-
- # allow simple scalars (without embedded quote chars) to be unquoted
- # (includes $%_+=-\;:,./)
- return $value if $value !~ /["'`~\n!\@\#^\&\*\(\)\{\}\[\]\|<>\?]/;
-
- # quote and escape strings with special values
- return "'$value'"
- if $value !~ /['`~\n!\#^\&\*\(\)\{\}\[\]\|\?]/; # nothing but " or @ or < or > (email addresses)
-
- $value =~ s/\n/\\n/g; # handle embedded newlines
- $value =~ s/"/\\"/g; # handle embedded quotes
- return qq{"$value"};
+# Deparse a scalar string to the actual scalar
+sub _read_scalar {
+ my ($self, $string, $indent, $lines) = @_;
+
+ # Trim trailing whitespace
+ $string =~ s/\s*\z//;
+
+ # Explitic null/undef
+ return undef if $string eq '~';
+
+ # Quotes
+ if ( $string =~ /^\'(.*?)\'\z/ ) {
+ return '' unless defined $1;
+ $string = $1;
+ $string =~ s/\'\'/\'/g;
+ return $string;
+ }
+ if ( $string =~ /^\"((?:\\.|[^\"])*)\"\z/ ) {
+ # Reusing the variable is a little ugly,
+ # but avoids a new variable and a string copy.
+ $string = $1;
+ $string =~ s/\\"/"/g;
+ $string =~ s/\\([never\\fartz]|x([0-9a-fA-F]{2}))/(length($1)>1)?pack("H2",$2):$UNESCAPES{$1}/gex;
+ return $string;
+ }
+
+ # Special cases
+ if ( $string =~ /^[\'\"!&]/ ) {
+ croak("Module::Build::YAML does not support a feature in line '$lines->[0]'");
+ }
+ return {} if $string eq '{}';
+ return [] if $string eq '[]';
+
+ # Regular unquoted string
+ return $string unless $string =~ /^[>|]/;
+
+ # Error
+ croak("Module::Build::YAML failed to find multi-line scalar content") unless @$lines;
+
+ # Check the indent depth
+ $lines->[0] =~ /^(\s*)/;
+ $indent->[-1] = length("$1");
+ if ( defined $indent->[-2] and $indent->[-1] <= $indent->[-2] ) {
+ croak("Module::Build::YAML found bad indenting in line '$lines->[0]'");
+ }
+
+ # Pull the lines
+ my @multiline = ();
+ while ( @$lines ) {
+ $lines->[0] =~ /^(\s*)/;
+ last unless length($1) >= $indent->[-1];
+ push @multiline, substr(shift(@$lines), length($1));
+ }
+
+ my $j = (substr($string, 0, 1) eq '>') ? ' ' : "\n";
+ my $t = (substr($string, 1, 1) eq '-') ? '' : "\n";
+ return join( $j, @multiline ) . $t;
}
-1;
+# Parse an array
+sub _read_array {
+ my ($self, $array, $indent, $lines) = @_;
-__END__
+ while ( @$lines ) {
+ # Check for a new document
+ if ( $lines->[0] =~ /^(?:---|\.\.\.)/ ) {
+ while ( @$lines and $lines->[0] !~ /^---/ ) {
+ shift @$lines;
+ }
+ return 1;
+ }
+
+ # Check the indent level
+ $lines->[0] =~ /^(\s*)/;
+ if ( length($1) < $indent->[-1] ) {
+ return 1;
+ } elsif ( length($1) > $indent->[-1] ) {
+ croak("Module::Build::YAML found bad indenting in line '$lines->[0]'");
+ }
+
+ if ( $lines->[0] =~ /^(\s*\-\s+)[^\'\"]\S*\s*:(?:\s+|$)/ ) {
+ # Inline nested hash
+ my $indent2 = length("$1");
+ $lines->[0] =~ s/-/ /;
+ push @$array, { };
+ $self->_read_hash( $array->[-1], [ @$indent, $indent2 ], $lines );
+
+ } elsif ( $lines->[0] =~ /^\s*\-(\s*)(.+?)\s*\z/ ) {
+ # Array entry with a value
+ shift @$lines;
+ push @$array, $self->_read_scalar( "$2", [ @$indent, undef ], $lines );
-=head1 NAME
+ } elsif ( $lines->[0] =~ /^\s*\-\s*\z/ ) {
+ shift @$lines;
+ unless ( @$lines ) {
+ push @$array, undef;
+ return 1;
+ }
+ if ( $lines->[0] =~ /^(\s*)\-/ ) {
+ my $indent2 = length("$1");
+ if ( $indent->[-1] == $indent2 ) {
+ # Null array entry
+ push @$array, undef;
+ } else {
+ # Naked indenter
+ push @$array, [ ];
+ $self->_read_array( $array->[-1], [ @$indent, $indent2 ], $lines );
+ }
-Module::Build::YAML - Provides just enough YAML support so that Module::Build works even if YAML.pm is not installed
+ } elsif ( $lines->[0] =~ /^(\s*)\S/ ) {
+ push @$array, { };
+ $self->_read_hash( $array->[-1], [ @$indent, length("$1") ], $lines );
-=head1 SYNOPSIS
+ } else {
+ croak("Module::Build::YAML failed to classify line '$lines->[0]'");
+ }
- use Module::Build::YAML;
+ } elsif ( defined $indent->[-2] and $indent->[-1] == $indent->[-2] ) {
+ # This is probably a structure like the following...
+ # ---
+ # foo:
+ # - list
+ # bar: value
+ #
+ # ... so lets return and let the hash parser handle it
+ return 1;
- ...
+ } else {
+ croak("Module::Build::YAML failed to classify line '$lines->[0]'");
+ }
+ }
-=head1 DESCRIPTION
+ return 1;
+}
+
+# Parse an array
+sub _read_hash {
+ my ($self, $hash, $indent, $lines) = @_;
+
+ while ( @$lines ) {
+ # Check for a new document
+ if ( $lines->[0] =~ /^(?:---|\.\.\.)/ ) {
+ while ( @$lines and $lines->[0] !~ /^---/ ) {
+ shift @$lines;
+ }
+ return 1;
+ }
-Provides just enough YAML support so that Module::Build works even if YAML.pm is not installed.
+ # Check the indent level
+ $lines->[0] =~ /^(\s*)/;
+ if ( length($1) < $indent->[-1] ) {
+ return 1;
+ } elsif ( length($1) > $indent->[-1] ) {
+ croak("Module::Build::YAML found bad indenting in line '$lines->[0]'");
+ }
-Currently, this amounts to the ability to write META.yml files when C<perl Build distmeta>
-is executed via the Dump() and DumpFile() functions/methods.
+ # Get the key
+ unless ( $lines->[0] =~ s/^\s*([^\'\" ][^\n]*?)\s*:(\s+|$)// ) {
+ if ( $lines->[0] =~ /^\s*[?\'\"]/ ) {
+ croak("Module::Build::YAML does not support a feature in line '$lines->[0]'");
+ }
+ croak("Module::Build::YAML failed to classify line '$lines->[0]'");
+ }
+ my $key = $1;
-=head1 AUTHOR
+ # Do we have a value?
+ if ( length $lines->[0] ) {
+ # Yes
+ $hash->{$key} = $self->_read_scalar( shift(@$lines), [ @$indent, undef ], $lines );
+ } else {
+ # An indent
+ shift @$lines;
+ unless ( @$lines ) {
+ $hash->{$key} = undef;
+ return 1;
+ }
+ if ( $lines->[0] =~ /^(\s*)-/ ) {
+ $hash->{$key} = [];
+ $self->_read_array( $hash->{$key}, [ @$indent, length($1) ], $lines );
+ } elsif ( $lines->[0] =~ /^(\s*)./ ) {
+ my $indent2 = length("$1");
+ if ( $indent->[-1] >= $indent2 ) {
+ # Null hash entry
+ $hash->{$key} = undef;
+ } else {
+ $hash->{$key} = {};
+ $self->_read_hash( $hash->{$key}, [ @$indent, length($1) ], $lines );
+ }
+ }
+ }
+ }
-Stephen Adkins <spadkins@gmail.com>
+ return 1;
+}
+
+# Save an object to a file
+sub write {
+ my $self = shift;
+ my $file = shift or return $self->_error('No file name provided');
-=head1 COPYRIGHT
+ # Write it to the file
+ open( CFG, '>' . $file ) or return $self->_error(
+ "Failed to open file '$file' for writing: $!"
+ );
+ print CFG $self->write_string;
+ close CFG;
-Copyright (c) 2006. Stephen Adkins. All rights reserved.
+ return 1;
+}
-This program is free software; you can redistribute it and/or modify it
-under the same terms as Perl itself.
+# Save an object to a string
+sub write_string {
+ my $self = shift;
+ return '' unless @$self;
-See L<http://www.perl.com/perl/misc/Artistic.html>
+ # Iterate over the documents
+ my $indent = 0;
+ my @lines = ();
+ foreach my $cursor ( @$self ) {
+ push @lines, '---';
-=cut
+ # An empty document
+ if ( ! defined $cursor ) {
+ # Do nothing
+
+ # A scalar document
+ } elsif ( ! ref $cursor ) {
+ $lines[-1] .= ' ' . $self->_write_scalar( $cursor, $indent );
+
+ # A list at the root
+ } elsif ( ref $cursor eq 'ARRAY' ) {
+ unless ( @$cursor ) {
+ $lines[-1] .= ' []';
+ next;
+ }
+ push @lines, $self->_write_array( $cursor, $indent, {} );
+
+ # A hash at the root
+ } elsif ( ref $cursor eq 'HASH' ) {
+ unless ( %$cursor ) {
+ $lines[-1] .= ' {}';
+ next;
+ }
+ push @lines, $self->_write_hash( $cursor, $indent, {} );
+
+ } else {
+ croak("Cannot serialize " . ref($cursor));
+ }
+ }
+
+ join '', map { "$_\n" } @lines;
+}
+
+sub _write_scalar {
+ my $string = $_[1];
+ return '~' unless defined $string;
+ return "''" unless length $string;
+ if ( $string =~ /[\x00-\x08\x0b-\x0d\x0e-\x1f\"\'\n]/ ) {
+ $string =~ s/\\/\\\\/g;
+ $string =~ s/"/\\"/g;
+ $string =~ s/\n/\\n/g;
+ $string =~ s/([\x00-\x1f])/\\$UNPRINTABLE[ord($1)]/g;
+ return qq|"$string"|;
+ }
+ if ( $string =~ /(?:^\W|\s)/ or $QUOTE{$string} ) {
+ return "'$string'";
+ }
+ return $string;
+}
+
+sub _write_array {
+ my ($self, $array, $indent, $seen) = @_;
+ if ( $seen->{refaddr($array)}++ ) {
+ die "Module::Build::YAML does not support circular references";
+ }
+ my @lines = ();
+ foreach my $el ( @$array ) {
+ my $line = (' ' x $indent) . '-';
+ my $type = ref $el;
+ if ( ! $type ) {
+ $line .= ' ' . $self->_write_scalar( $el, $indent + 1 );
+ push @lines, $line;
+
+ } elsif ( $type eq 'ARRAY' ) {
+ if ( @$el ) {
+ push @lines, $line;
+ push @lines, $self->_write_array( $el, $indent + 1, $seen );
+ } else {
+ $line .= ' []';
+ push @lines, $line;
+ }
+
+ } elsif ( $type eq 'HASH' ) {
+ if ( keys %$el ) {
+ push @lines, $line;
+ push @lines, $self->_write_hash( $el, $indent + 1, $seen );
+ } else {
+ $line .= ' {}';
+ push @lines, $line;
+ }
+
+ } else {
+ die "Module::Build::YAML does not support $type references";
+ }
+ }
+
+ @lines;
+}
+
+sub _write_hash {
+ my ($self, $hash, $indent, $seen) = @_;
+ if ( $seen->{refaddr($hash)}++ ) {
+ die "Module::Build::YAML does not support circular references";
+ }
+ my @lines = ();
+ foreach my $name ( sort keys %$hash ) {
+ my $el = $hash->{$name};
+ my $line = (' ' x $indent) . "$name:";
+ my $type = ref $el;
+ if ( ! $type ) {
+ $line .= ' ' . $self->_write_scalar( $el, $indent + 1 );
+ push @lines, $line;
+
+ } elsif ( $type eq 'ARRAY' ) {
+ if ( @$el ) {
+ push @lines, $line;
+ push @lines, $self->_write_array( $el, $indent + 1, $seen );
+ } else {
+ $line .= ' []';
+ push @lines, $line;
+ }
+
+ } elsif ( $type eq 'HASH' ) {
+ if ( keys %$el ) {
+ push @lines, $line;
+ push @lines, $self->_write_hash( $el, $indent + 1, $seen );
+ } else {
+ $line .= ' {}';
+ push @lines, $line;
+ }
+
+ } else {
+ die "Module::Build::YAML does not support $type references";
+ }
+ }
+
+ @lines;
+}
+
+# Set error
+sub _error {
+ $Module::Build::YAML::errstr = $_[1];
+ undef;
+}
+
+# Retrieve error
+sub errstr {
+ $Module::Build::YAML::errstr;
+}
+
+#####################################################################
+# YAML Compatibility
+
+sub Dump {
+ Module::Build::YAML->new(@_)->write_string;
+}
+
+sub Load {
+ my $self = Module::Build::YAML->read_string(@_);
+ unless ( $self ) {
+ croak("Failed to load YAML document from string");
+ }
+ if ( wantarray ) {
+ return @$self;
+ } else {
+ # To match YAML.pm, return the last document
+ return $self->[-1];
+ }
+}
+
+BEGIN {
+ *freeze = *Dump;
+ *thaw = *Load;
+}
+
+sub DumpFile {
+ my $file = shift;
+ Module::Build::YAML->new(@_)->write($file);
+}
+
+sub LoadFile {
+ my $self = Module::Build::YAML->read($_[0]);
+ unless ( $self ) {
+ croak("Failed to load YAML document from '" . ($_[0] || '') . "'");
+ }
+ if ( wantarray ) {
+ return @$self;
+ } else {
+ # Return only the last document to match YAML.pm,
+ return $self->[-1];
+ }
+}
+
+#####################################################################
+# Use Scalar::Util if possible, otherwise emulate it
+
+BEGIN {
+ eval {
+ require Scalar::Util;
+ };
+ if ( $@ ) {
+ # Failed to load Scalar::Util
+ eval <<'END_PERL';
+sub refaddr {
+ my $pkg = ref($_[0]) or return undef;
+ if (!!UNIVERSAL::can($_[0], 'can')) {
+ bless $_[0], 'Scalar::Util::Fake';
+ } else {
+ $pkg = undef;
+ }
+ "$_[0]" =~ /0x(\w+)/;
+ my $i = do { local $^W; hex $1 };
+ bless $_[0], $pkg if defined $pkg;
+ $i;
+}
+END_PERL
+ } else {
+ Scalar::Util->import('refaddr');
+ }
+}
+
+1;
+
+__END__
diff --git a/cpan/Module-Build/lib/inc/latest.pm b/cpan/Module-Build/lib/inc/latest.pm
new file mode 100644
index 0000000000..9d4a38006b
--- /dev/null
+++ b/cpan/Module-Build/lib/inc/latest.pm
@@ -0,0 +1,250 @@
+package inc::latest;
+use strict;
+use vars qw($VERSION);
+$VERSION = '0.35_08';
+$VERSION = eval $VERSION;
+
+use Carp;
+use File::Basename ();
+use File::Spec ();
+use File::Path ();
+use IO::File ();
+use File::Copy ();
+
+# track and return modules loaded by inc::latest
+my @loaded_modules;
+sub loaded_modules {@loaded_modules}
+
+# must ultimately "goto" the import routine of the module to be loaded
+# so that the calling package is correct when $mod->import() runs.
+sub import {
+ my ($package, $mod, @args) = @_;
+ return unless(defined $mod);
+
+ my $inc_path = './inc/latest.pm';
+ my $private_path = './inc/latest/private.pm';
+ if(-e $inc_path) {
+ # delete our methods
+ delete $inc::latest::{$_} for(keys %inc::latest::);
+ # load the bundled module
+ require $inc_path;
+ require $private_path;
+ my $import = inc::latest->can('import');
+ goto $import;
+ }
+
+ # author mode - just record and load the modules
+ push(@loaded_modules, $mod);
+ require inc::latest::private;
+ goto \&inc::latest::private::_load_module;
+}
+
+sub write {
+ my $package = shift;
+ my ($where, @preload) = @_;
+
+ warn "should really be writing in inc/" unless $where =~ /inc$/;
+
+ # write inc/latest.pm
+ File::Path::mkpath( $where );
+ my $fh = IO::File->new( File::Spec->catfile($where,'latest.pm'), "w" );
+ print {$fh} "# This stub created by inc::latest $VERSION\n";
+ print {$fh} <<'HERE';
+package inc::latest;
+use strict;
+use vars '@ISA';
+require inc::latest::private;
+@ISA = qw/inc::latest::private/;
+HERE
+ if (@preload) {
+ print {$fh} "\npackage inc::latest::preload;\n";
+ for my $mod (@preload) {
+ print {$fh} "inc::latest->import('$mod');\n";
+ }
+ }
+ print {$fh} "\n1;\n";
+ close $fh;
+
+ # write inc/latest/private;
+ require inc::latest::private;
+ File::Path::mkpath( File::Spec->catdir( $where, 'latest' ) );
+ my $from = $INC{'inc/latest/private.pm'};
+ my $to = File::Spec->catfile($where,'latest','private.pm');
+ File::Copy::copy( $from, $to ) or die "Couldn't copy '$from' to '$to': $!";
+
+ return 1;
+}
+
+sub bundle_module {
+ my ($package, $module, $where) = @_;
+
+ # create inc/inc_$foo
+ (my $dist = $module) =~ s{::}{-}g;
+ my $inc_lib = File::Spec->catdir($where,"inc_$dist");
+ File::Path::mkpath $inc_lib;
+
+ # get list of files to copy
+ require ExtUtils::Installed;
+ # workaround buggy EU::Installed check of @INC
+ my $inst = ExtUtils::Installed->new(extra_libs => [@INC]);
+ my $packlist = $inst->packlist( $module ) or die "Couldn't find packlist";
+ my @files = grep { /\.pm$/ } keys %$packlist;
+
+
+ # figure out prefix
+ my $mod_path = quotemeta $package->_mod2path( $module );
+ my ($prefix) = grep { /$mod_path$/ } @files;
+ $prefix =~ s{$mod_path$}{};
+
+ # copy files
+ for my $from ( @files ) {
+ next unless $from =~ /\.pm$/;
+ (my $mod_path = $from) =~ s{^\Q$prefix\E}{};
+ my $to = File::Spec->catfile( $inc_lib, $mod_path );
+ File::Path::mkpath(File::Basename::dirname($to));
+ File::Copy::copy( $from, $to ) or die "Couldn't copy '$from' to '$to': $!";
+ }
+ return 1;
+}
+
+# Translate a module name into a directory/file.pm to search for in @INC
+sub _mod2path {
+ my ($self, $mod) = @_;
+ my @parts = split /::/, $mod;
+ $parts[-1] .= '.pm';
+ return $parts[0] if @parts == 1;
+ return File::Spec->catfile(@parts);
+}
+
+1;
+
+
+=head1 NAME
+
+inc::latest - use modules bundled in inc/ if they are newer than installed ones
+
+=head1 SYNOPSIS
+
+ # in Build.PL
+ use inc::latest 'Module::Build';
+
+=head1 DESCRIPTION
+
+The C<inc::latest> module helps bootstrap configure-time dependencies for CPAN
+distributions. These dependencies get bundled into the C<inc> directory within
+a distribution and are used by Build.PL (or Makefile.PL).
+
+Arguments to C<inc::latest> are module names that are checked against both the
+current C<@INC> array and against specially-named directories in C<inc>. If
+the bundled verison is newer than the installed one (or the module isn't
+installed, then, the bundled directory is added to the start of <@INC> and the
+module is loaded from there.
+
+There are actually two variations of C<inc::latest> -- one for authors and one
+for the C<inc> directory. For distribution authors, the C<inc::latest>
+installed in the system will record modules loaded via C<inc::latest> and can
+be used to create the bundled files in C<inc>, including writing the second
+variation as C<inc/latest.pm>.
+
+This second C<inc::latest> is the one that is loaded in a distribution being
+installed (e.g. from Build.PL). This bundled C<inc::latest> is the one
+that determines which module to load.
+
+=head2 Special notes on bundling
+
+The C<inc::latest> module creates bundled directories based on the packlist
+file of an installed distribution. Even though C<inc::latest> takes module
+name arguments, it is better to think of it as bundling and making available
+entire I<distributions>. When a module is loaded through C<inc::latest>,
+it looks in all bundled distributions in C<inc/> for a newer module than
+can be found in the existing C<@INC> array.
+
+Thus, the module-name provided should usually be the "top-level" module name of
+a distribution, though this is not strictly required. For example,
+L<Module::Build> has a number of heuristics to map module names to packlists,
+allowing users to do things like this:
+
+ use inc::latest 'Devel::AssertOS::Unix';
+
+even though Devel::AssertOS::Unix is contained within the Devel-CheckOS
+distribution.
+
+At the current time, packlists are required. Thus, bundling dual-core modules
+may require a 'forced install' over versions in the latest version of perl
+in order to create the necessary packlist for bundling.
+
+=head1 USAGE
+
+When calling C<use>, the bundled C<inc::latest> takes a single module name and
+optional arguments to pass to that module's own import method.
+
+ use 'inc::latest' 'Foo::Bar' qw/foo bar baz/;
+
+=head2 Author-mode
+
+You are in author-mode inc::latest if any of the Author-mode methods are
+available. For example:
+
+ if ( inc::latest->can('write') ) {
+ inc::latest->write('inc');
+ }
+
+=over 4
+
+=item loaded_modules()
+
+ my @list = inc::latest->loaded_modules;
+
+This takes no arguments and always returns a list of module names requested for
+loading via "use inc::latest 'MODULE'", regardless of wether the load was
+successful or not.
+
+=item write()
+
+ inc::latest->write( 'inc' );
+
+This writes the bundled version of inc::latest to the directory name given as an
+argument. It almost all cases, it should be 'C<inc>'.
+
+=item bundle_module()
+
+ for my $mod ( inc::latest->loaded_modules ) {
+ inc::latest->bundle_module($mod, $dir);
+ }
+
+If $mod corresponds to a packlist, then this function creates a specially-named
+directory in $dir and copies all .pm files from the modlist to the new
+directory (which almost always should just be 'inc'). For example, if Foo::Bar
+is the name of the module, and $dir is 'inc', then the directory would be
+'inc/inc_Foo-Bar' and contain files like this:
+
+ inc/inc_Foo-Bar/Foo/Bar.pm
+
+Currently, $mod B<must> have a packlist. If this is not the case (e.g. for a
+dual-core module), then the bundling will fail. You may be able to create a
+packlist by forced installing the module on top of the version that came with
+core Perl.
+
+=back
+
+=head2 As bundled in inc/
+
+All methods are private. Only the C<import> method is public.
+
+=head1 AUTHOR
+
+Eric Wilhelm <ewilhelm@cpan.org>, David Golden <dagolden@cpan.org>
+
+=head1 COPYRIGHT
+
+Copyright (c) 2009 by Eric Wilhelm and David Golden
+
+This library is free software; you can redistribute it and/or
+modify it under the same terms as Perl itself.
+
+=head1 SEE ALSO
+
+L<Module::Build>
+
+=cut
+
diff --git a/cpan/Module-Build/lib/inc/latest/private.pm b/cpan/Module-Build/lib/inc/latest/private.pm
new file mode 100644
index 0000000000..285514bc38
--- /dev/null
+++ b/cpan/Module-Build/lib/inc/latest/private.pm
@@ -0,0 +1,101 @@
+package inc::latest::private;
+use strict;
+use vars qw($VERSION);
+$VERSION = '0.35_08';
+$VERSION = eval $VERSION;
+
+use File::Spec;
+use IO::File;
+
+# must ultimately "goto" the import routine of the module to be loaded
+# so that the calling package is correct when $mod->import() runs.
+sub import {
+ my ($package, $mod, @args) = @_;
+ my $file = $package->_mod2path($mod);
+
+ if ($INC{$file}) {
+ # Already loaded, but let _load_module handle import args
+ goto \&_load_module;
+ }
+
+ # A bundled copy must be present
+ my ($bundled, $bundled_dir) = $package->_search_bundled($file)
+ or die "No bundled copy of $mod found";
+
+ my $from_inc = $package->_search_INC($file);
+ unless ($from_inc) {
+ # Only bundled is available
+ unshift(@INC, $bundled_dir);
+ goto \&_load_module;
+ }
+
+ if (_version($from_inc) >= _version($bundled)) {
+ # Ignore the bundled copy
+ goto \&_load_module;
+ }
+
+ # Load the bundled copy
+ unshift(@INC, $bundled_dir);
+ goto \&_load_module;
+}
+
+sub _version {
+ require ExtUtils::MakeMaker;
+ return ExtUtils::MM->parse_version(shift);
+}
+
+# use "goto" for import to preserve caller
+sub _load_module {
+ my $package = shift; # remaining @_ is ready for goto
+ my ($mod, @args) = @_;
+ eval "require $mod; 1" or die $@;
+ if ( my $import = $mod->can('import') ) {
+ goto $import;
+ }
+ return 1;
+}
+
+sub _search_bundled {
+ my ($self, $file) = @_;
+
+ my $mypath = 'inc';
+
+ local *DH; # Maintain 5.005 compatibility
+ opendir DH, $mypath or die "Can't open directory $mypath: $!";
+
+ while (defined(my $e = readdir DH)) {
+ next unless $e =~ /^inc_/;
+ my $try = File::Spec->catfile($mypath, $e, $file);
+
+ return($try, File::Spec->catdir($mypath, $e)) if -e $try;
+ }
+ return;
+}
+
+# Look for the given path in @INC.
+sub _search_INC {
+ # TODO: doesn't handle coderefs or arrayrefs or objects in @INC, but
+ # it probably should
+ my ($self, $file) = @_;
+
+ foreach my $dir (@INC) {
+ next if ref $dir;
+ my $try = File::Spec->catfile($dir, $file);
+ return $try if -e $try;
+ }
+
+ return;
+}
+
+# Translate a module name into a directory/file.pm to search for in @INC
+sub _mod2path {
+ my ($self, $mod) = @_;
+ my @parts = split /::/, $mod;
+ $parts[-1] .= '.pm';
+ return $parts[0] if @parts == 1;
+ return File::Spec->catfile(@parts);
+}
+
+1;
+
+
diff --git a/cpan/Module-Build/t/PL_files.t b/cpan/Module-Build/t/PL_files.t
index a22171458c..68614c80e4 100644
--- a/cpan/Module-Build/t/PL_files.t
+++ b/cpan/Module-Build/t/PL_files.t
@@ -4,7 +4,7 @@ use strict;
use lib 't/lib';
use MBTest tests => 8;
use DistGen;
-use Module::Build;
+blib_load('Module::Build');
my $dist;
diff --git a/cpan/Module-Build/t/README.pod b/cpan/Module-Build/t/README.pod
new file mode 100644
index 0000000000..b2d0579d3e
--- /dev/null
+++ b/cpan/Module-Build/t/README.pod
@@ -0,0 +1,94 @@
+=head1 A GUIDE TO WRITING TESTS FOR MODULE::BUILD
+
+This document provides tips on writing new tests for Module::Build. Please
+note that many existing tests were written prior to these guidelines and
+have many different styles. Please don't copy/paste old tests by rote without
+considering better ways to test. See C<sample.t> for a starter test file.
+
+=head1 TEST FILE PREAMBLE
+
+Every Module::Build test should begin with the same preamble to ensure that the
+test library is set properly and that the correct version of Module::Build is
+being tested.
+
+ use strict;
+ use lib 't/lib';
+ use MBTest tests => 2; # or 'no_plan'
+
+ blib_load('Module::Build');
+
+The C<MBTest> module is in C<t/lib/> and subclasses Test::More. When loaded
+it cleans up several environment variables that could cause problems,
+tweaks C<@INC> and exports several helper functions. See that module for
+details.
+
+=head1 CREATING A TEST DISTRIBUTION
+
+The C<DistGen> module in C<t/lib/> should be used to create sample
+distributions for testing. It provides numerous helpful methods to
+create a skeleton distribution, add files, change files, and so on.
+Run C<perldoc> on C<t/lib/DistGen.pm> to see the documentation.
+
+ # CREATE A TEST DISTRIBUTION
+
+ use DistGen;
+
+ # create dist object in a temp directory
+ my $dist = DistGen->new;
+
+ # enter the test distribution directory before further testing
+ $dist->chdir_in;
+
+ # generate the skeleton files
+ $dist->regen;
+
+
+=head1 GETTING A MODULE::BUILD OBJECT
+
+From inside the test distribution, you can get the Module::Build object
+configured in Build.PL using the C<new_from_context> method on the
+dist object. This is just like Module::Build's C<new_from_context> except
+it passes C<< quiet => 1 >> to avoid sending output to the terminal.
+Use the Module::Build object to test the programmatic API.
+
+ my $mb = $dist->new_from_context( quiet => 1 );
+ isa_ok( $mb, "Module::Build" );
+ is( $mb->dist_name, "Simple", "dist_name is 'Simple'" );
+
+=head1 TESTING THE COMMAND LINE API
+
+The command line API is tested by running subprocesses, not via a Module::Build
+object. The C<DistGen> object has helper methods for running C<Build.PL> and
+C<Build> and passing arguments on the command line.
+
+ $dist->run_build_pl( '--quiet' );
+ $dist->run_build( 'test' );
+
+=head1 TYPICAL TESTING CYCLE
+
+The typical testing cycle is to generate or modify a test distribution, either
+through the C<DistGen> object or directly in the filesystem, then regenerate
+the distribution and test it (or run command line tests and observe the
+result.)
+
+ # Modify the distribution
+
+ $dist->change_build_pl(
+ {
+ module_name => $dist->name,
+ license => 'artistic',
+ }
+ );
+ $dist->regen;
+
+ # Get a new build object and test it
+
+ $mb = $dist->new_from_context;
+ is( $mb->license, "artistic", "saw 'artistic' license" );
+
+
+=head1 COPYRIGHT
+
+This documentation is Copyright (C) 2009 by David Golden. You can redistribute
+it and/or modify it under the same terms as Perl 5.10.0.
+
diff --git a/cpan/Module-Build/t/actions/installdeps.t b/cpan/Module-Build/t/actions/installdeps.t
new file mode 100644
index 0000000000..95e221d0ad
--- /dev/null
+++ b/cpan/Module-Build/t/actions/installdeps.t
@@ -0,0 +1,48 @@
+use strict;
+use lib 't/lib';
+use MBTest;
+use DistGen;
+
+plan tests => 7;
+
+# Ensure any Module::Build modules are loaded from correct directory
+blib_load('Module::Build');
+
+# create dist object in a temp directory
+# enter the directory and generate the skeleton files
+my $dist = DistGen->new->chdir_in;
+
+$dist->change_build_pl(
+ module_name => $dist->name,
+ requires => {
+ 'File::Spec' => 9999,
+ },
+ build_requires => {
+ 'Getopt::Long' => 9998,
+ },
+ cpan_client => $^X . ' -le print($_)for($^X,@ARGV)',
+)->regen;
+
+# get a Module::Build object and test with it
+my $mb;
+stdout_stderr_of( sub { $mb = $dist->new_from_context('verbose' => 1) } );
+isa_ok( $mb, "Module::Build" );
+like( $mb->cpan_client, qr/^\Q$^X\E/, "cpan_client is mocked with perl" );
+
+my $out = stdout_of( sub {
+ $dist->run_build('installdeps')
+});
+ok( length($out), "ran mocked Build installdeps");
+my $expected = quotemeta(Module::Build->find_command($^X));
+like( $out, qr/$expected/i, "relative cpan_client resolved relative to \$^X" );
+like( $out, qr/File::Spec/, "saw File::Spec prereq" );
+like( $out, qr/Getopt::Long/, "saw Getopt::Long prereq" );
+
+$out = stdout_stderr_of( sub {
+ $dist->run_build('installdeps', '--cpan_client', 'ADLKASJDFLASDJ')
+});
+like( $out, qr/cpan_client .* is not executable/,
+ "Build installdeps with bad cpan_client dies"
+);
+
+# vim:ts=2:sw=2:et:sta:sts=2
diff --git a/cpan/Module-Build/t/add_property.t b/cpan/Module-Build/t/add_property.t
index 6032b0929d..e0b25ae00f 100644
--- a/cpan/Module-Build/t/add_property.t
+++ b/cpan/Module-Build/t/add_property.t
@@ -2,12 +2,11 @@
use strict;
use lib 't/lib';
-use MBTest tests => 29;
+use MBTest tests => 27;
#use MBTest 'no_plan';
use DistGen;
-BEGIN { use_ok 'Module::Build' or die; }
-ensure_blib 'Module::Build';
+blib_load 'Module::Build';
my $tmp = MBTest->tmpdir;
my $dist = DistGen->new( dir => $tmp );
diff --git a/cpan/Module-Build/t/basic.t b/cpan/Module-Build/t/basic.t
index f46be0a4c9..74c50b6178 100644
--- a/cpan/Module-Build/t/basic.t
+++ b/cpan/Module-Build/t/basic.t
@@ -2,10 +2,9 @@
use strict;
use lib 't/lib';
-use MBTest tests => 60;
+use MBTest tests => 58;
-use_ok 'Module::Build';
-ensure_blib('Module::Build');
+blib_load('Module::Build');
my $tmp = MBTest->tmpdir;
@@ -28,7 +27,7 @@ $dist->chdir_in;
$mb = Module::Build->new( dist_name => $dist->name, dist_version => 7 );
ok $mb;
- ok ! $mb->module_name; # Make sure it's defined
+ ok $mb->module_name; # Set via heuristics
is $mb->dist_name, $dist->name;
}
@@ -163,10 +162,7 @@ $dist->chdir_in;
is $args{foo}, 1;
# revert test distribution to pristine state because we modified a file
- $dist->remove;
- $dist = DistGen->new( dir => $tmp );
- $dist->regen;
- $dist->chdir_in;
+ $dist->regen( clean => 1 );
}
# Test author stuff
@@ -236,5 +232,3 @@ $dist->chdir_in;
is_deeply $mb->include_dirs, ['/foo'], 'Should have single include dir';
}
-# cleanup
-$dist->remove;
diff --git a/cpan/Module-Build/t/bundle_inc.t b/cpan/Module-Build/t/bundle_inc.t
new file mode 100644
index 0000000000..edb1aa94cd
--- /dev/null
+++ b/cpan/Module-Build/t/bundle_inc.t
@@ -0,0 +1,194 @@
+# sample.t -- a sample test file for Module::Build
+
+use strict;
+use lib 't/lib';
+use MBTest; # or 'no_plan'
+use DistGen;
+use Config;
+use IO::File;
+use File::Spec;
+use ExtUtils::Packlist;
+use File::Path;
+
+# Ensure any Module::Build modules are loaded from correct directory
+blib_load('Module::Build');
+blib_load('Module::Build::ConfigData');
+
+if ( Module::Build::ConfigData->feature('inc_bundling_support') ) {
+ plan tests => 18;
+} else {
+ plan skip_all => 'inc_bundling_support feature is not enabled';
+}
+
+# need to do a temp install of M::B being tested to ensure a packlist
+# is available for bundling
+
+my $current_mb = Module::Build->resume();
+my $temp_install = MBTest->tmpdir();
+my $arch = $Config{archname};
+my $lib_path = File::Spec->catdir($temp_install,qw/lib perl5/);
+my $arch_path = File::Spec->catdir( $lib_path, $arch );
+mkpath ( $arch_path );
+ok( -d $arch_path, "created temporary M::B pseudo-install directory");
+
+unshift @INC, $lib_path, $arch_path;
+local $ENV{PERL5LIB} = join( $Config{path_sep},
+ $lib_path, $arch_path, ($ENV{PERL5LIB} ? $ENV{PERL5LIB} : () )
+);
+
+stdout_of( sub { $current_mb->dispatch('install', install_base => $temp_install) } );
+
+# create dist object in a temp directory
+# enter the directory and generate the skeleton files
+my $dist = DistGen->new( inc => 1 )->chdir_in->regen;
+
+# get a Module::Build object and test with it
+my $mb = $dist->new_from_context(); # quiet by default
+isa_ok( $mb, "Module::Build" );
+is( $mb->dist_name, "Simple", "dist_name is 'Simple'" );
+is_deeply( $mb->bundle_inc, [ 'Module::Build' ],
+ "Module::Build is flagged for bundling"
+);
+
+# see what gets bundled
+stdout_stderr_of( sub { $mb->dispatch('distdir') } );
+
+my $dist_inc = File::Spec->catdir($mb->dist_dir, 'inc');
+ok( -e File::Spec->catfile( $dist_inc, 'latest.pm' ),
+ "./inc/latest.pm created"
+);
+
+ok( -d File::Spec->catdir( $dist_inc, 'inc_Module-Build' ),
+ "dist_dir/inc/inc_Module_Build created"
+);
+
+my $mb_file =
+ File::Spec->catfile( $dist_inc, qw/inc_Module-Build Module Build.pm/ );
+
+ok( -e $mb_file,
+ "dist_dir/inc/inc_Module_Build/Module/Build.pm created"
+);
+
+ok( -e File::Spec->catfile( $dist_inc, qw/inc_Module-Build Module Build Base.pm/ ),
+ "dist_dir/inc/inc_Module_Build/Module/Build/Base.pm created"
+);
+
+# Force bundled M::B to a higher version so it gets loaded
+
+my $fh = IO::File->new($mb_file, "+<") or die "Could not open $mb_file: $!";
+my $mb_code = do { local $/; <$fh> };
+$mb_code =~ s{\$VERSION\s+=\s+\S+}{\$VERSION = 9999;};
+$fh->seek(0,0);
+print {$fh} $mb_code;
+$fh->close;
+
+# test the bundling in dist_dir
+chdir $mb->dist_dir;
+
+stdout_of( sub { Module::Build->run_perl_script('Build.PL',[],[]) } );
+
+my $meta = IO::File->new('MYMETA.yml');
+ok( $meta, "found MYMETA.yml" );
+ok( scalar( grep { /generated_by:.*9999/ } <$meta> ),
+ "dist_dir Build.PL loaded bundled Module::Build"
+);
+
+#--------------------------------------------------------------------------#
+# test identification of dependencies
+#--------------------------------------------------------------------------#
+
+$dist->chdir_in;
+
+$dist->add_file( 'mylib/Foo.pm', << 'HERE' );
+package Foo;
+our $VERSION = 1;
+1;
+HERE
+
+$dist->add_file( 'mylib/Bar.pm', << 'HERE' );
+package Bar;
+use Foo;
+our $VERSION = 42;
+1;
+HERE
+
+$dist->change_file( 'Build.PL', << "HERE" );
+use inc::latest 'Module::Build';
+use inc::latest 'Foo';
+
+Module::Build->new(
+ module_name => '$dist->{name}',
+ license => 'perl',
+)->create_build_script;
+HERE
+
+$dist->regen( clean => 1 );
+
+make_packlist($_,'mylib') for qw/Foo Bar/;
+
+# get a Module::Build object and test with it
+my $abs_mylib = File::Spec->rel2abs('mylib');
+
+
+unshift @INC, $abs_mylib;
+$mb = $dist->new_from_context(); # quiet by default
+isa_ok( $mb, "Module::Build" );
+is_deeply( [sort @{$mb->bundle_inc}], [ 'Foo', 'Module::Build' ],
+ "Module::Build and Foo are flagged for bundling"
+);
+
+my $output = stdout_stderr_of( sub { $mb->dispatch('distdir') } );
+
+ok( -e File::Spec->catfile( $dist_inc, 'latest.pm' ),
+ "./inc/latest.pm created"
+);
+
+ok( -d File::Spec->catdir( $dist_inc, 'inc_Foo' ),
+ "dist_dir/inc/inc_Foo created"
+);
+
+$dist->change_file( 'Build.PL', << "HERE" );
+use inc::latest 'Module::Build';
+use inc::latest 'Bar';
+
+Module::Build->new(
+ module_name => '$dist->{name}',
+ license => 'perl',
+)->create_build_script;
+HERE
+
+$dist->regen( clean => 1 );
+make_packlist($_,'mylib') for qw/Foo Bar/;
+
+$mb = $dist->new_from_context(); # quiet by default
+isa_ok( $mb, "Module::Build" );
+is_deeply( [sort @{$mb->bundle_inc}], [ 'Bar', 'Module::Build' ],
+ "Module::Build and Bar are flagged for bundling"
+);
+
+$output = stdout_stderr_of( sub { $mb->dispatch('distdir') } );
+
+ok( -e File::Spec->catfile( $dist_inc, 'latest.pm' ),
+ "./inc/latest.pm created"
+);
+
+ok( -d File::Spec->catdir( $dist_inc, 'inc_Bar' ),
+ "dist_dir/inc/inc_Bar created"
+);
+
+
+
+sub make_packlist {
+ my ($mod, $lib) = @_;
+ my $arch = $Config{archname};
+ (my $mod_path = $mod) =~ s{::}{/}g;
+ my $mod_file = File::Spec->catfile( $lib, "$mod_path\.pm" );
+ my $abs = File::Spec->rel2abs($mod_file);
+ my $packlist_path = File::Spec->catdir($lib, $arch, 'auto', $mod_path);
+ mkpath $packlist_path;
+ my $packlist = ExtUtils::Packlist->new;
+ $packlist->{$abs}++;
+ $packlist->write( File::Spec->catfile( $packlist_path, '.packlist' ));
+}
+
+# vim:ts=2:sw=2:et:sta:sts=2
diff --git a/cpan/Module-Build/t/compat.t b/cpan/Module-Build/t/compat.t
index 88e5953408..f84b79b744 100644
--- a/cpan/Module-Build/t/compat.t
+++ b/cpan/Module-Build/t/compat.t
@@ -25,8 +25,8 @@ if ( $Config{make} && $^O ne 'VMS' ? find_in_path($Config{make}) : 1 ) {
my $is_vms_mms = ($^O eq 'VMS') && ($Config{make} =~ /MM[SK]/i);
-use_ok 'Module::Build';
-ensure_blib('Module::Build');
+blib_load('Module::Build');
+blib_load('Module::Build::Version');
#########################
@@ -43,8 +43,8 @@ $dist->chdir_in;
#########################
-use Module::Build;
-use Module::Build::Compat;
+blib_load('Module::Build');
+blib_load('Module::Build::Compat');
use Carp; $SIG{__WARN__} = \&Carp::cluck;
@@ -72,10 +72,11 @@ $dist->change_build_pl({
license => 'perl',
requires => {
'perl' => $],
- 'File::Spec' => 0,
+ 'File::Spec' => 0.2,
},
- build_requires => {
- 'Test::More' => 0,
+ build_requires => {
+ 'Test::More' => 0,
+ 'File::Spec' => 0,
},
PL_files => { 'foo.PL' => 'foo' },
});
@@ -90,8 +91,11 @@ $dist->regen;
test_makefile_types(
requires => {
'perl' => $],
- 'File::Spec' => 0,
+ 'File::Spec' => 0.2,
+ },
+ build_requires => {
'Test::More' => 0,
+ 'File::Spec' => 0,
},
PL_files => {
'foo.PL' => 'foo',
@@ -108,7 +112,7 @@ $dist->regen;
# Create M::B instance but don't pollute STDOUT
my $mb;
-stdout_of( sub {
+stdout_stderr_of( sub {
$mb = Module::Build->new_from_context;
});
ok $mb, "Module::Build->new_from_context";
@@ -131,7 +135,7 @@ ok $mb, "Module::Build->new_from_context";
# Makefile.PL - make sure it fails in the right way here.
local @Foo::Builder::ISA = qw(Module::Build);
my $foo_builder;
- stdout_of( sub {
+ stdout_stderr_of( sub {
$foo_builder = Foo::Builder->new_from_context;
});
foreach my $style ('passthrough', 'small') {
@@ -148,13 +152,13 @@ ok $mb, "Module::Build->new_from_context";
# Now make sure it can actually work.
my $bar_builder;
- stdout_of( sub {
+ stdout_stderr_of( sub {
$bar_builder = Module::Build->subclass( class => 'Bar::Builder' )->new_from_context;
});
foreach my $style ('passthrough', 'small') {
create_makefile_pl($style, $bar_builder);
my $result;
- stdout_of( sub {
+ stdout_stderr_of( sub {
$result = $mb->run_perl_script('Makefile.PL');
});
ok $result, "Makefile.PL ran without error";
@@ -167,7 +171,7 @@ ok $mb, "Module::Build->new_from_context";
my $libdir = File::Spec->catdir( $tmp, 'libdir' );
my $result;
- stdout_of( sub {
+ stdout_stderr_of( sub {
$result = $mb->run_perl_script('Makefile.PL', [],
[
"LIB=$libdir",
@@ -188,7 +192,7 @@ ok $mb, "Module::Build->new_from_context";
# Make sure those switches actually had an effect
my ($ran_ok, $output);
- $output = stdout_of( sub { $ran_ok = $new_build->do_system(@make, 'test') } );
+ $output = stdout_stderr_of( sub { $ran_ok = $new_build->do_system(@make, 'test') } );
ok $ran_ok, "make test ran without error";
$output =~ s/^/# /gm; # Don't confuse our own test output
like $output, qr/(?:# ok \d+\s+)+/, 'Should be verbose';
@@ -201,7 +205,7 @@ ok $mb, "Module::Build->new_from_context";
$make_macro = '/macro=("' . $make_macro . '")';
}
- $output = stdout_of( sub {
+ $output = stdout_stderr_of( sub {
local $ENV{HARNESS_TIMER}; # RT#39635 - timer messes with output
$ran_ok = $mb->do_system(@make, 'test', $make_macro)
} );
@@ -258,7 +262,7 @@ ok $mb, "Module::Build->new_from_context";
}
}
- stdout_of( sub { $mb->do_system(@make, 'realclean'); } );
+ stdout_stderr_of( sub { $mb->do_system(@make, 'realclean'); } );
ok ! -e $makefile, "$makefile shouldn't exist";
1 while unlink 'Makefile.PL';
@@ -274,14 +278,14 @@ ok $mb, "Module::Build->new_from_context";
create_makefile_pl('passthrough', $mb);
- stdout_of( sub {
+ stdout_stderr_of( sub {
$mb->run_perl_script('Makefile.PL', [], ['INSTALL_BASE=~/foo']);
});
my $b2 = Module::Build->current;
ok $b2->install_base, "install_base set";
unlike $b2->install_base, qr/^~/, "Tildes should be expanded";
- stdout_of( sub { $mb->do_system(@make, 'realclean'); } );
+ stdout_stderr_of( sub { $mb->do_system(@make, 'realclean'); } );
ok ! -e $makefile, "$makefile shouldn't exist";
1 while unlink 'Makefile.PL';
@@ -293,34 +297,53 @@ ok $mb, "Module::Build->new_from_context";
$dist->regen;
my $mb;
- stdout_of( sub {
+ stdout_stderr_of( sub {
$mb = Module::Build->new_from_context( recursive_test_files => 1 );
});
create_makefile_pl('traditional', $mb);
my $args = extract_writemakefile_args() || {};
- is $args->{TESTS},
- join( q{ },
- File::Spec->catfile(qw(t *.t)),
- File::Spec->catfile(qw(t deep *.t))
- ),
- 'Makefile.PL has correct TESTS line for recursive test files';
-}
-# cleanup
-$dist->remove;
+ if ( exists $args->{test}->{TESTS} ) {
+ is $args->{test}->{TESTS},
+ join( q{ },
+ File::Spec->catfile(qw(t *.t)),
+ File::Spec->catfile(qw(t deep *.t))
+ ),
+ 'Makefile.PL has correct TESTS line for recursive test files';
+ } else {
+ ok( ! exists $args->{TESTS}, 'Not using incorrect recursive tests key' );
+ }
+
+}
#########################################################
+sub _merge_prereqs {
+ my ($first, $second) = @_;
+ my $new = { %$first };
+ for my $k (keys %$second) {
+ if ( exists $new->{$k} ) {
+ my ($v1,$v2) = ($new->{$k},$second->{$k});
+ $new->{$k} = ($v1 > $v2 ? $v1 : $v2);
+ }
+ else {
+ $new->{$k} = $second->{$k};
+ }
+ }
+ return $new;
+}
+
sub test_makefile_types {
my %opts = @_;
$opts{requires} ||= {};
+ $opts{build_requires} ||= {};
$opts{PL_files} ||= {};
foreach my $type (@makefile_types) {
# Create M::B instance
my $mb;
- stdout_of( sub {
+ stdout_stderr_of( sub {
$mb = Module::Build->new_from_context;
});
ok $mb, "Module::Build->new_from_context";
@@ -330,12 +353,12 @@ sub test_makefile_types {
test_makefile_pl_requires_perl( $opts{requires}{perl} );
test_makefile_creation($mb);
- test_makefile_prereq_pm( $opts{requires} );
+ test_makefile_prereq_pm( _merge_prereqs($opts{requires}, $opts{build_requires}) );
test_makefile_pl_files( $opts{PL_files} ) if $type eq 'traditional';
my ($output,$success);
# Capture output to keep our STDOUT clean
- $output = stdout_of( sub {
+ $output = stdout_stderr_of( sub {
$success = $mb->do_system(@make);
});
ok $success, "make ran without error";
@@ -345,13 +368,13 @@ sub test_makefile_types {
}
# Can't let 'test' STDOUT go to our STDOUT, or it'll confuse Test::Harness.
- $output = stdout_of( sub {
+ $output = stdout_stderr_of( sub {
$success = $mb->do_system(@make, 'test');
});
ok $success, "make test ran without error";
like uc $output, qr{DONE\.|SUCCESS}, "make test output indicated success";
- $output = stdout_of( sub {
+ $output = stdout_stderr_of( sub {
$success = $mb->do_system(@make, 'realclean');
});
ok $success, "make realclean ran without error";
@@ -372,7 +395,7 @@ sub test_makefile_creation {
my ($output, $result);
# capture output to avoid polluting our test output
- $output = stdout_of( sub {
+ $output = stdout_stderr_of( sub {
$result = $build->run_perl_script('Makefile.PL', $preargs, $postargs);
});
my $label = "Makefile.PL ran without error";
@@ -472,7 +495,8 @@ sub extract_writemakefile_args {
}
sub create_makefile_pl {
- Module::Build::Compat->create_makefile_pl(@_);
+ my @args = @_;
+ stdout_stderr_of( sub { Module::Build::Compat->create_makefile_pl(@args) } );
my $ok = ok -e 'Makefile.PL', "$_[0] Makefile.PL created";
# Some really conservative make's, like HP/UX, assume files with the same
diff --git a/cpan/Module-Build/t/compat/exit.t b/cpan/Module-Build/t/compat/exit.t
index 78269a97a3..3672c938c3 100644..100755
--- a/cpan/Module-Build/t/compat/exit.t
+++ b/cpan/Module-Build/t/compat/exit.t
@@ -3,10 +3,9 @@
use strict;
use lib 't/lib';
-use MBTest tests => 5;
+use MBTest tests => 3;
-use_ok 'Module::Build';
-ensure_blib('Module::Build');
+blib_load('Module::Build');
#########################
@@ -24,11 +23,13 @@ $dist->chdir_in;
my $mb; stdout_of(sub{ $mb = Module::Build->new_from_context});
-use Module::Build::Compat;
+blib_load('Module::Build::Compat');
$dist->regen;
-Module::Build::Compat->create_makefile_pl('passthrough', $mb);
+stdout_stderr_of(
+ sub{ Module::Build::Compat->create_makefile_pl('passthrough', $mb); }
+);
# as silly as all of this exit(0) business is, that is what the cpan
# testers have instructed everybody to do so...
diff --git a/cpan/Module-Build/t/debug.t b/cpan/Module-Build/t/debug.t
index c9b4fa581c..e0b8f60817 100644
--- a/cpan/Module-Build/t/debug.t
+++ b/cpan/Module-Build/t/debug.t
@@ -2,18 +2,15 @@
use strict;
use lib 't/lib';
-use MBTest tests => 3;
+use MBTest tests => 1;
-require_ok('Module::Build');
-ensure_blib('Module::Build');
+blib_load('Module::Build');
my $tmp = MBTest->tmpdir;
use DistGen;
my $dist = DistGen->new( dir => $tmp );
$dist->regen;
-END{ $dist->remove }
-
$dist->chdir_in;
#########################
@@ -28,6 +25,3 @@ $dist->chdir_in;
);
}
-#########################
-
-# cleanup
diff --git a/cpan/Module-Build/t/destinations.t b/cpan/Module-Build/t/destinations.t
index 4af99d0031..07247a32ba 100644
--- a/cpan/Module-Build/t/destinations.t
+++ b/cpan/Module-Build/t/destinations.t
@@ -2,10 +2,9 @@
use strict;
use lib 't/lib';
-use MBTest tests => 115;
+use MBTest tests => 113;
-use_ok 'Module::Build';
-ensure_blib('Module::Build');
+blib_load('Module::Build');
my $tmp = MBTest->tmpdir;
@@ -248,7 +247,8 @@ $mb->prefix(undef);
}
# Poke at the innards of MB to change the default install locations.
- my $old = $mb->install_sets->{site} = \%test_config;
+ my $old = $mb->install_sets->{site};
+ $mb->install_sets->{site} = \%test_config;
$mb->config(siteprefixexp => catdir(File::Spec->rootdir,
'wierd', 'prefix'));
@@ -321,5 +321,3 @@ sub test_install_destinations {
}
}
-
-$dist->remove;
diff --git a/cpan/Module-Build/t/ext.t b/cpan/Module-Build/t/ext.t
index 8045761c2a..6101bccd16 100644
--- a/cpan/Module-Build/t/ext.t
+++ b/cpan/Module-Build/t/ext.t
@@ -4,8 +4,6 @@ use strict;
use lib 't/lib';
use MBTest;
-use Module::Build;
-
my @unix_splits =
(
{ q{one t'wo th'ree f"o\"ur " "five" } => [ 'one', 'two three', 'fo"ur ', 'five' ] },
@@ -58,9 +56,11 @@ my @win_splits =
{ 'a " b " c' => [ 'a', ' b ', 'c' ] },
);
-plan tests => 10 + 4*@unix_splits + 4*@win_splits;
+plan tests => 9 + 4*@unix_splits + 4*@win_splits;
-ensure_blib('Module::Build');
+blib_load('Module::Build');
+blib_load('Module::Build::Platform::Unix');
+blib_load('Module::Build::Platform::Windows');
#########################
@@ -74,7 +74,6 @@ foreach my $platform ('', '::Platform::Unix', '::Platform::Windows') {
# I think 3.24 isn't actually the majik version, my 3.23 seems to pass...
my $low_TPW_version = Text::ParseWords->VERSION < 3.24;
-use Module::Build::Platform::Unix;
foreach my $test (@unix_splits) {
# Text::ParseWords bug:
local $TODO = $low_TPW_version && ((keys %$test)[0] =~ m{\\\n});
@@ -82,7 +81,6 @@ foreach my $test (@unix_splits) {
do_split_tests('Module::Build::Platform::Unix', $test);
}
-use Module::Build::Platform::Windows;
foreach my $test (@win_splits) {
do_split_tests('Module::Build::Platform::Windows', $test);
}
diff --git a/cpan/Module-Build/t/extend.t b/cpan/Module-Build/t/extend.t
index db99eec70b..36ff4b6946 100644
--- a/cpan/Module-Build/t/extend.t
+++ b/cpan/Module-Build/t/extend.t
@@ -2,10 +2,9 @@
use strict;
use lib 't/lib';
-use MBTest tests => 66;
+use MBTest tests => 64;
-use_ok 'Module::Build';
-ensure_blib('Module::Build');
+blib_load('Module::Build');
my $tmp = MBTest->tmpdir;
@@ -79,7 +78,7 @@ print "Hello, World!\n";
$mb->add_build_element('foo');
$mb->add_build_element('foo');
- is_deeply $mb->build_elements, [qw(PL support pm xs pod script foo)],
+ is_deeply $mb->build_elements, [qw(PL support pm xs share_dir pod script foo)],
'The foo element should be in build_elements only once';
$mb->dispatch('build');
@@ -187,21 +186,20 @@ print "Hello, World!\n";
meta_add => {foo => 'bar'},
conflicts => {'Foo::Barxx' => 0},
);
- my %data;
- $mb->prepare_metadata( \%data );
- is $data{foo}, 'bar';
+ my $data = $mb->prepare_metadata;
+ is $data->{foo}, 'bar';
$mb->meta_merge(foo => 'baz');
- $mb->prepare_metadata( \%data );
- is $data{foo}, 'baz';
+ $data = $mb->prepare_metadata;
+ is $data->{foo}, 'baz';
$mb->meta_merge(conflicts => {'Foo::Fooxx' => 0});
- $mb->prepare_metadata( \%data );
- is_deeply $data{conflicts}, {'Foo::Barxx' => 0, 'Foo::Fooxx' => 0};
+ $data = $mb->prepare_metadata;
+ is_deeply $data->{conflicts}, {'Foo::Barxx' => 0, 'Foo::Fooxx' => 0};
$mb->meta_add(conflicts => {'Foo::Bazxx' => 0});
- $mb->prepare_metadata( \%data );
- is_deeply $data{conflicts}, {'Foo::Bazxx' => 0, 'Foo::Fooxx' => 0};
+ $data = $mb->prepare_metadata;
+ is_deeply $data->{conflicts}, {'Foo::Bazxx' => 0, 'Foo::Fooxx' => 0};
}
{
@@ -275,5 +273,3 @@ print "Hello, World!\n";
}
-# cleanup
-$dist->remove;
diff --git a/cpan/Module-Build/t/files.t b/cpan/Module-Build/t/files.t
index 87b192eaba..cf822fb091 100644
--- a/cpan/Module-Build/t/files.t
+++ b/cpan/Module-Build/t/files.t
@@ -2,10 +2,9 @@
use strict;
use lib 't/lib';
-use MBTest tests => 6;
+use MBTest tests => 4;
-use_ok 'Module::Build';
-ensure_blib('Module::Build');
+blib_load('Module::Build');
use IO::File;
my $tmp = MBTest->tmpdir;
@@ -46,5 +45,3 @@ my $mb = Module::Build->new_from_context;
ok( Module::Build->dir_contains($first, $second) );
}
-# cleanup
-$dist->remove;
diff --git a/cpan/Module-Build/t/help.t b/cpan/Module-Build/t/help.t
index 8408315f07..2bf34c8d50 100644
--- a/cpan/Module-Build/t/help.t
+++ b/cpan/Module-Build/t/help.t
@@ -2,38 +2,23 @@
use strict;
use lib 't/lib';
-use MBTest tests => 25;
+use MBTest tests => 23;
-use_ok 'Module::Build';
-ensure_blib('Module::Build');
-
-use Cwd ();
-use File::Path ();
-
-my $cwd = Cwd::cwd();
-my $tmp = MBTest->tmpdir;
+blib_load('Module::Build');
use DistGen;
-my $dist = DistGen->new(dir => $tmp);
-
-
+my $dist = DistGen->new;
$dist->regen;
+$dist->chdir_in;
my $restart = sub {
- $dist->clean();
- DistGen::chdir_all( $cwd );
- File::Path::rmtree( $tmp );
# we're redefining the same package as we go, so...
delete($::{'MyModuleBuilder::'});
delete($INC{'MyModuleBuilder.pm'});
- $dist->regen;
- chdir($dist->dirname) or
- die "Can't chdir to '@{[$dist->dirname]}': $!";
+ $dist->regen( clean => 1 );
};
-chdir($dist->dirname) or die "Can't chdir to '@{[$dist->dirname]}': $!";
-
########################################################################
{ # check the =item style
my $mb = Module::Build->subclass(
@@ -274,7 +259,5 @@ is($mb->get_action_docs('batz'), undef, 'nothing after uplevel');
# cleanup
$dist->clean();
-DistGen::chdir_all($cwd);
-File::Path::rmtree( $tmp );
# vim:ts=2:sw=2:et:sta
diff --git a/cpan/Module-Build/t/install.t b/cpan/Module-Build/t/install.t
index 2cadaa39da..66cdd5c94a 100644
--- a/cpan/Module-Build/t/install.t
+++ b/cpan/Module-Build/t/install.t
@@ -2,10 +2,9 @@
use strict;
use lib 't/lib';
-use MBTest tests => 36;
+use MBTest tests => 34;
-use_ok 'Module::Build';
-ensure_blib('Module::Build');
+blib_load('Module::Build');
use Config;
use Cwd ();
@@ -225,10 +224,7 @@ Simple Man <simple@example.com>
is keys %$pms, 0;
# revert to pristine state
- $dist->remove;
- $dist = DistGen->new( dir => $tmp );
- $dist->regen;
- $dist->chdir_in;
+ $dist->regen( clean => 1 );
}
sub strip_volume {
@@ -243,6 +239,3 @@ sub file_exists {
ok -e $file or diag("Expected $file to exist, but it doesn't");
}
-
-# cleanup
-$dist->remove;
diff --git a/cpan/Module-Build/t/install_extra_target.t b/cpan/Module-Build/t/install_extra_target.t
index c717ce5eee..21d0c272ae 100644
--- a/cpan/Module-Build/t/install_extra_target.t
+++ b/cpan/Module-Build/t/install_extra_target.t
@@ -3,10 +3,9 @@
use strict;
use lib 't/lib';
-use MBTest tests => 8;
+use MBTest tests => 6;
-require_ok 'Module::Build';
-ensure_blib('Module::Build');
+blib_load('Module::Build');
use File::Spec::Functions qw( catdir );
@@ -46,11 +45,11 @@ sub process_etc_files
}
#Copy share files to blib
-sub process_share_files
+sub process_shared_files
{
my $self = shift;
- $self->copy_files("share");
+ $self->copy_files("shared");
}
1;
@@ -62,23 +61,23 @@ my $build = $subclass->new(
);
$build->add_build_element('etc');
-$build->add_build_element('share');
+$build->add_build_element('shared');
my $distdir = lc $build->dist_name();
foreach my $id ('core', 'site', 'vendor') {
#Where to install these build types when using prefix symantics
- $build->prefix_relpaths($id, 'share' => "share/$distdir");
+ $build->prefix_relpaths($id, 'shared' => "shared/$distdir");
$build->prefix_relpaths($id, 'etc' => "etc/$distdir");
#Where to install these build types when using default symantics
my $set = $build->install_sets($id);
- $set->{'share'} = '/usr/'.($id eq 'site' ? 'local/':'')."share/$distdir";
+ $set->{'shared'} = '/usr/'.($id eq 'site' ? 'local/':'')."shared/$distdir";
$set->{'etc'} = ($id eq 'site' ? '/usr/local/etc/':'/etc/').$distdir;
}
#Where to install these types when using install_base symantics
-$build->install_base_relpaths('share' => "share/$distdir");
+$build->install_base_relpaths('shared' => "shared/$distdir");
$build->install_base_relpaths('etc' => "etc/$distdir");
$build->create_build_script();
@@ -97,12 +96,12 @@ stardate = 1234344
===EOF===
-$dist->add_file("share/data", <<'===EOF===');
+$dist->add_file("shared/data", <<'===EOF===');
7 * 9 = 42?
===EOF===
-$dist->add_file("share/html/index.html", <<'===EOF===');
+$dist->add_file("shared/html/index.html", <<'===EOF===');
<HTML>
<BODY>
<H1>Hello World!</H1>
@@ -122,16 +121,15 @@ $output .= stdout_of sub { $dist->run_build };
my $error;
$error++ unless ok(-e "blib/etc/config", "Built etc/config");
-$error++ unless ok(-e "blib/share/data", "Built share/data");
-$error++ unless ok(-e "blib/share/html/index.html", "Built share/html");
+$error++ unless ok(-e "blib/shared/data", "Built shared/data");
+$error++ unless ok(-e "blib/shared/html/index.html", "Built shared/html");
diag "OUTPUT:\n$output" if $error;
$output = stdout_of sub { $dist->run_build('install') };
$error = 0;
$error++ unless ok(-e "$installdest/etc/simple/config", "installed etc/config");
-$error++ unless ok(-e "$installdest/share/simple/data", "installed share/data");
-$error++ unless ok(-e "$installdest/share/simple/html/index.html", "installed share/html");
+$error++ unless ok(-e "$installdest/shared/simple/data", "installed shared/data");
+$error++ unless ok(-e "$installdest/shared/simple/html/index.html", "installed shared/html");
diag "OUTPUT:\n$output" if $error;
-$dist->remove();
diff --git a/cpan/Module-Build/t/lib/DistGen.pm b/cpan/Module-Build/t/lib/DistGen.pm
index 86ee794f3b..d1fb260d60 100644
--- a/cpan/Module-Build/t/lib/DistGen.pm
+++ b/cpan/Module-Build/t/lib/DistGen.pm
@@ -7,9 +7,9 @@ use vars qw( $VERSION $VERBOSE @EXPORT_OK);
$VERSION = '0.01';
$VERBOSE = 0;
-
use Carp;
+use MBTest ();
use Cwd ();
use File::Basename ();
use File::Find ();
@@ -38,7 +38,7 @@ BEGIN {
$vms_efs_case = VMS::Feature::current("efs_case_preserve");
} else {
my $env_unix_rpt = $ENV{'DECC$FILENAME_UNIX_REPORT'} || '';
- $unix_rpt = $env_unix_rpt =~ /^[ET1]/i;
+ $unix_rpt = $env_unix_rpt =~ /^[ET1]/i;
my $efs_case = $ENV{'DECC$EFS_CASE_PRESERVE'} || '';
$vms_efs_case = $efs_case =~ /^[ET1]/i;
}
@@ -64,44 +64,76 @@ sub undent {
}
sub chdir_all ($) {
- # OS/2 has "current directory per disk", undeletable;
+ # OS/2 has "current directory per disk", undeletable;
# doing chdir() to another disk won't change cur-dir of initial disk...
chdir('/') if $^O eq 'os2';
chdir shift;
}
+
########################################################################
+END { chdir_all(MBTest->original_cwd); }
+
sub new {
- my $package = shift;
+ my $self = bless {}, shift;
+ $self->reset(@_);
+}
+
+sub reset {
+ my $self = shift;
my %options = @_;
$options{name} ||= 'Simple';
- $options{dir} ||= Cwd::cwd();
+ $options{dir} = File::Spec->rel2abs(
+ defined $options{dir} ? $options{dir} : MBTest->tmpdir
+ );
my %data = (
no_manifest => 0,
xs => 0,
+ inc => 0,
%options,
);
- my $self = bless( \%data, $package );
-
- # So we can clean up later even if the caller chdir()s
- $self->{dir} = File::Spec->rel2abs($self->{dir});
+ %$self = %data;
tie %{$self->{filedata}}, 'Tie::CPHash';
tie %{$self->{pending}{change}}, 'Tie::CPHash';
+ # start with a fresh, empty directory
if ( -d $self->dirname ) {
warn "Warning: Removing existing directory '@{[$self->dirname]}'\n";
- $self->remove;
+ File::Path::rmtree( $self->dirname );
}
+ File::Path::mkpath( $self->dirname );
$self->_gen_default_filedata();
return $self;
}
+sub remove {
+ my $self = shift;
+ $self->chdir_original if($self->did_chdir);
+ File::Path::rmtree( $self->dirname );
+ return $self;
+}
+
+sub revert {
+ my ($self, $file) = @_;
+ if ( defined $file ) {
+ delete $self->{filedata}{$file};
+ delete $self->{pending}{$_}{$file} for qw/change remove/;
+ }
+ else {
+ delete $self->{filedata}{$_} for keys %{ $self->{filedata} };
+ for my $pend ( qw/change remove/ ) {
+ delete $self->{pending}{$pend}{$_} for keys %{ $self->{pending}{$pend} };
+ }
+ }
+ $self->_gen_default_filedata;
+}
+
sub _gen_default_filedata {
my $self = shift;
@@ -112,17 +144,32 @@ sub _gen_default_filedata {
$self->add_file($member, $data) unless($self->{filedata}{$member});
};
- $self->$add_unless('Build.PL', undent(<<" ---"));
- use strict;
- use Module::Build;
+ if ( ! $self->{inc} ) {
+ $self->$add_unless('Build.PL', undent(<<" ---"));
+ use strict;
+ use Module::Build;
- my \$builder = Module::Build->new(
- module_name => '$self->{name}',
- license => 'perl',
- );
+ my \$builder = Module::Build->new(
+ module_name => '$self->{name}',
+ license => 'perl',
+ );
- \$builder->create_build_script();
- ---
+ \$builder->create_build_script();
+ ---
+ }
+ else {
+ $self->$add_unless('Build.PL', undent(<<" ---"));
+ use strict;
+ use inc::latest 'Module::Build';
+
+ my \$builder = Module::Build->new(
+ module_name => '$self->{name}',
+ license => 'perl',
+ );
+
+ \$builder->create_build_script();
+ ---
+ }
my $module_filename =
join( '/', ('lib', split(/::/, $self->{name})) ) . '.pm';
@@ -229,7 +276,7 @@ sub _gen_default_filedata {
# 5.6 is missing const char * in its typemap
$self->$add_unless('typemap', undent(<<" ---"));
- const char * T_PV
+ const char *\tT_PV
---
$self->$add_unless('t/basic.t', undent(<<" ---"));
@@ -249,7 +296,6 @@ sub _gen_manifest {
my $manifest = shift;
my $fh = IO::File->new( ">$manifest" ) or do {
- $self->remove();
die "Can't write '$manifest'\n";
};
@@ -312,7 +358,6 @@ sub regen {
my $dirname = File::Basename::dirname( $fullname );
unless ( -d $dirname ) {
File::Path::mkpath( $dirname ) or do {
- $self->remove();
die "Can't create '$dirname'\n";
};
}
@@ -322,7 +367,6 @@ sub regen {
}
my $fh = IO::File->new(">$fullname") or do {
- $self->remove();
die "Can't write '$fullname'\n";
};
print $fh $self->{filedata}{$file};
@@ -339,6 +383,7 @@ sub regen {
}
$self->_gen_manifest( $manifest );
}
+ return $self;
}
sub clean {
@@ -396,20 +441,7 @@ sub clean {
}, ($^O eq 'VMS' ? './' : File::Spec->curdir) );
chdir_all( $here );
-}
-
-sub remove {
- my $self = shift;
- croak("invalid usage -- remove()") if(@_);
- $self->chdir_original if($self->did_chdir);
- File::Path::rmtree( $self->dirname );
- # might as well check
- croak("\nthis test should have used chdir_in()") unless(Cwd::getcwd);
-}
-
-sub revert {
- my $self = shift;
- die "Unimplemented.\n";
+ return $self;
}
sub add_file {
@@ -425,10 +457,13 @@ sub remove_file {
}
delete( $self->{filedata}{$file} );
$self->{pending}{remove}{$file} = 1;
+ return $self;
}
sub change_build_pl {
- my ($self, $opts) = @_;
+ my ($self, @opts) = @_;
+
+ my $opts = ref $opts[0] eq 'HASH' ? $opts[0] : { @opts };
local $Data::Dumper::Terse = 1;
(my $args = Dumper($opts)) =~ s/^\s*\{|\}\s*$//g;
@@ -437,16 +472,17 @@ sub change_build_pl {
use strict;
use Module::Build;
my \$b = Module::Build->new(
- # Some CPANPLUS::Dist::Build versions need to allow mismatches
+ # Some CPANPLUS::Dist::Build versions need to allow mismatches
# On logic: thanks to Module::Install, CPAN.pm must set both keys, but
# CPANPLUS sets only the one
- allow_mb_mismatch => (
+ allow_mb_mismatch => (
\$ENV{PERL5_CPANPLUS_IS_RUNNING} && ! \$ENV{PERL5_CPAN_IS_RUNNING} ? 1 : 0
),
$args
);
\$b->create_build_script();
---
+ return $self;
}
sub change_file {
@@ -455,6 +491,7 @@ sub change_file {
my $data = shift;
$self->{filedata}{$file} = $data;
$self->{pending}{change}{$file} = 1;
+ return $self;
}
sub get_file {
@@ -466,40 +503,43 @@ sub get_file {
sub chdir_in {
my $self = shift;
-
- $self->{original_dir} ||= Cwd::cwd; # only once
+ $self->{original_dir} ||= Cwd::cwd; # only once!
my $dir = $self->dirname;
chdir($dir) or die "Can't chdir to '$dir': $!";
+ return $self;
}
########################################################################
-sub did_chdir {
- my $self = shift;
+sub did_chdir { exists shift()->{original_dir} }
- return exists($self->{original_dir});
-}
########################################################################
sub chdir_original {
my $self = shift;
- croak("never called chdir_in()") unless($self->{original_dir});
- my $dir = $self->{original_dir};
+ my $dir = delete $self->{original_dir};
chdir_all($dir) or die "Can't chdir to '$dir': $!";
+ return $self;
}
########################################################################
+sub new_from_context {
+ my ($self, @args) = @_;
+ require Module::Build;
+ return Module::Build->new_from_context( quiet => 1, @args );
+}
+
sub run_build_pl {
my ($self, @args) = @_;
require Module::Build;
- Module::Build->run_perl_script('Build.PL', [], [@args])
+ return Module::Build->run_perl_script('Build.PL', [], [@args])
}
sub run_build {
my ($self, @args) = @_;
require Module::Build;
my $build_script = $^O eq 'VMS' ? 'Build.com' : 'Build';
- Module::Build->run_perl_script($build_script, [], [@args])
+ return Module::Build->run_perl_script($build_script, [], [@args])
}
1;
@@ -516,8 +556,7 @@ DistGen - Creates simple distributions for testing.
use DistGen;
# create distribution and prepare to test
- my $dist = DistGen->new(name => 'Foo::Bar', dir => $tmp);
- $dist->regen;
+ my $dist = DistGen->new(name => 'Foo::Bar');
$dist->chdir_in;
# change distribution files
@@ -526,42 +565,48 @@ DistGen - Creates simple distributions for testing.
$dist->remove_file('t/some_test.t');
$dist->regen;
- # clean up extraneous files
+ # undo changes and clean up extraneous files
+ $dist->revert;
$dist->clean;
# exercise the command-line interface
$dist->run_build_pl();
$dist->run_build('test');
- # finish testing and clean up
- $dist->chdir_original;
- $dist->remove;
+ # start over as a new distribution
+ $dist->reset( name => 'Foo::Bar', xs => 1 );
+ $dist->chdir_in;
=head1 USAGE
A DistGen object manages a set of files in a distribution directory.
-The constructor and some methods only define the target state of the
-distribution. They do B<not> make any changes to the filesystem:
+The C<new()> constructor initializes the object and creates an empty
+directory for the distribution. It does not create files or chdir into
+the directory. The C<reset()> method re-initializes the object in a
+new directory with new parameters. It also does not create files or change
+the current directory.
+
+Some methods only define the target state of the distribution. They do B<not>
+make any changes to the filesystem:
- new
add_file
change_file
change_build_pl
remove_file
+ revert
Other methods then change the filesystem to match the target state of
-the distribution (or to remove it entirely):
+the distribution:
- regen
clean
+ regen
remove
Other methods are provided for a convenience during testing. The
-most important are ones that manage the current directory:
+most important is the one to enter the distribution directory:
chdir_in
- chdir_original
Additional methods portably encapsulate running Build.PL and Build:
@@ -570,16 +615,19 @@ Additional methods portably encapsulate running Build.PL and Build:
=head1 API
-=head2 Constructor
+=head2 Constructors
=head3 new()
-Create a new object. Does not write its contents (see L</regen()>.)
+Create a new object and an empty directory to hold the distribution's files.
+If no C<dir> option is provided, it defaults to MBTest->tmpdir, which sets
+a different temp directory for Perl core testing and CPAN testing.
+
+The C<new> method does not write any files -- see L</regen()> below.
- my $tmp = MBTest->tmpdir;
my $dist = DistGen->new(
name => 'Foo::Bar',
- dir => $tmp,
+ dir => MBTest->tmpdir,
xs => 1,
no_manifest => 0,
);
@@ -596,9 +644,14 @@ dist name.
=item dir
-The (parent) directory in which to create the distribution directory.
-The default is File::Spec->curdir. The distribution will be created
-under this according to the "dist" form of C<name> (e.g. "Foo-Bar".)
+The (parent) directory in which to create the distribution directory. The
+distribution will be created under this according to the "dist" form of C<name>
+(e.g. "Foo-Bar".) Defaults to a temporary directory.
+
+ $dist = DistGen->new( dir => '/tmp/MB-test' );
+ $dist->regen;
+
+ # distribution files have been created in /tmp/MB-test/Simple
=item xs
@@ -622,6 +675,13 @@ the following files are also added:
typemap
lib/Simple.xs # based on name parameter
+=head3 reset()
+
+The C<reset> method re-initializes the object as if it were generated
+from a fresh call to C<new>. It takes the same optional parameters as C<new>.
+
+ $dist->reset( name => 'Foo::Bar', xs => 0 );
+
=head2 Adding and editing files
Note that C<$filename> should always be specified with unix-style paths,
@@ -669,6 +729,14 @@ Removes C<$filename> from the distribution.
$dist->remove_file( $filename );
+=head3 revert()
+
+Returns the object to its initial state, or given a $filename it returns that
+file to its initial state if it is one of the built-in files.
+
+ $dist->revert;
+ $dist->revert($filename);
+
=head2 Changing the distribution directory
These methods immediately affect the filesystem.
@@ -680,8 +748,10 @@ flagged for removal with remove_file().
$dist->regen(clean => 1);
-If the optional C<clean> argument is given, it also removes any
-extraneous files that do not belong to the distribution.
+If the optional C<clean> argument is given, it also calls C<clean>. These
+can also be chained like this, instead:
+
+ $dist->clean->regen;
=head3 clean()
@@ -689,22 +759,19 @@ Removes any files that are not part of the distribution.
$dist->clean;
-=begin TODO
-
-=head3 revert()
-
-[Unimplemented] Returns the object to its initial state, or given a
-$filename it returns that file to it's initial state if it is one of
-the built-in files.
+=head3 remove()
- $dist->revert;
- $dist->revert($filename);
+Changes back to the original directory and removes the distribution
+directory (but not the temporary directory set during C<new()>).
-=end TODO
+ $dist = DistGen->new->chdir->regen;
+ # ... do some testing ...
-=head3 remove()
+ $dist->remove->chdir_in->regen;
+ # ... do more testing ...
-Removes the entire distribution directory.
+This is like a more aggressive form of C<clean>. Generally, calling C<clean>
+and C<regen> should be sufficient.
=head2 Changing directories
diff --git a/cpan/Module-Build/t/lib/MBTest.pm b/cpan/Module-Build/t/lib/MBTest.pm
index dc2410b399..8a5acd257a 100644
--- a/cpan/Module-Build/t/lib/MBTest.pm
+++ b/cpan/Module-Build/t/lib/MBTest.pm
@@ -13,6 +13,7 @@ BEGIN {
my @delete_env_keys = qw(
DEVEL_COVER_OPTIONS
MODULEBUILDRC
+ PERL_MB_OPT
HARNESS_TIMER
HARNESS_OPTIONS
HARNESS_VERBOSE
@@ -49,7 +50,15 @@ BEGIN {
# In case the test wants to use our other bundled
# modules, make sure they can be loaded.
- push @INC, File::Spec->catdir('t', 'bundled');
+ my $t_lib = File::Spec->catdir('t', 'bundled');
+ push @INC, $t_lib; # Let user's installed version override
+
+ if ($ENV{PERL_CORE}) {
+ # We change directories, so expand @INC and $^X to absolute paths
+ # Also add .
+ @INC = (map(File::Spec->rel2abs($_), @INC), ".");
+ $^X = File::Spec->rel2abs($^X);
+ }
}
use Exporter;
@@ -74,7 +83,7 @@ my @extra_exports = qw(
find_in_path
check_compiler
have_module
- ensure_blib
+ blib_load
);
push @EXPORT, @extra_exports;
__PACKAGE__->export(scalar caller, @extra_exports);
@@ -85,7 +94,9 @@ __PACKAGE__->export(scalar caller, @extra_exports);
# always return to the current directory
{
- my $cwd = Cwd::cwd;
+ my $cwd = File::Spec->rel2abs(Cwd::cwd);
+
+ sub original_cwd { return $cwd }
END {
# Go back to where you came from!
@@ -103,13 +114,11 @@ __PACKAGE__->export(scalar caller, @extra_exports);
}
########################################################################
-# Setup a temp directory
-sub tmpdir {
- my ($self, $usr_tmp) = @_;
- return File::Temp::tempdir( 'MB-XXXXXXXX',
- CLEANUP => 1, DIR => $ENV{PERL_CORE} ? Cwd::cwd :
- $usr_tmp ? $usr_tmp : File::Spec->tmpdir
- );
+# Setup a temp directory
+sub tmpdir {
+ my ($self, @args) = @_;
+ my $dir = $ENV{PERL_CORE} ? MBTest->original_cwd : File::Spec->tmpdir;
+ return File::Temp::tempdir('MB-XXXXXXXX', CLEANUP => 1, DIR => $dir, @args);
}
sub save_handle {
@@ -137,7 +146,7 @@ sub stdout_stderr_of {
$stdout = stdout_of ( sub {
$stderr = stderr_of( $subr )
});
- return ($stdout, $stderr);
+ return wantarray ? ($stdout, $stderr) : $stdout . $stderr;
}
sub slurp {
@@ -160,13 +169,20 @@ sub exe_exts {
sub find_in_path {
my $thing = shift;
-
- my @path = split $Config{path_sep}, $ENV{PATH};
+
my @exe_ext = exe_exts();
- foreach (@path) {
- my $fullpath = File::Spec->catfile($_, $thing);
+ if ( File::Spec->file_name_is_absolute( $thing ) ) {
foreach my $ext ( '', @exe_ext ) {
- return "$fullpath$ext" if -e "$fullpath$ext";
+ return "$thing$ext" if -e "$thing$ext";
+ }
+ }
+ else {
+ my @path = split $Config{path_sep}, $ENV{PATH};
+ foreach (@path) {
+ my $fullpath = File::Spec->catfile($_, $thing);
+ foreach my $ext ( '', @exe_ext ) {
+ return "$fullpath$ext" if -e "$fullpath$ext";
+ }
}
}
return;
@@ -178,6 +194,7 @@ sub check_compiler {
local $SIG{__WARN__} = sub {};
+ blib_load('Module::Build');
my $mb = Module::Build->current;
$mb->verbose( 0 );
@@ -202,21 +219,23 @@ sub check_compiler {
sub have_module {
my $module = shift;
- return eval "use $module; 1";
+ return eval "require $module; 1";
}
-sub ensure_blib {
- # Make sure the given module was loaded from blib/, not the larger system
+sub blib_load {
+ # Load the given module and ensure it came from blib/, not the larger system
my $mod = shift;
+ have_module($mod) or die "Error loading $mod\: $@\n";
+
(my $path = $mod) =~ s{::}{/}g;
-
- local $Test::Builder::Level = $Test::Builder::Level + 1;
- SKIP: {
- skip "no blib in core", 1 if $ENV{PERL_CORE};
- like $INC{"$path.pm"}, qr/\bblib\b/, "Make sure $mod was loaded from blib/"
- or diag "PERL5LIB: " . ($ENV{PERL5LIB} || '') . "\n" .
- "PERL5OPT: " . ($ENV{PERL5OPT} || '') . "\n" .
- "\@INC contains:\n " . join("\n ", @INC) . "\n";
+ $path .= ".pm";
+ my ($pkg, $file, $line) = caller;
+ unless($ENV{PERL_CORE}) {
+ unless($INC{$path} =~ m/\bblib\b/) {
+ (my $load_from = $INC{$path}) =~ s{$path$}{};
+ die "$mod loaded from '$load_from'\nIt should have been loaded from blib. \@INC contains:\n ",
+ join("\n ", @INC) . "\nFatal error occured in blib_load() at $file, line $line.\n";
+ }
}
}
diff --git a/cpan/Module-Build/t/manifypods.t b/cpan/Module-Build/t/manifypods.t
index 31c9e8ea83..5947646d13 100644
--- a/cpan/Module-Build/t/manifypods.t
+++ b/cpan/Module-Build/t/manifypods.t
@@ -3,15 +3,14 @@
use strict;
use lib 't/lib';
use MBTest;
-use Module::Build;
-use Module::Build::ConfigData;
+blib_load('Module::Build');
+blib_load('Module::Build::ConfigData');
if ( Module::Build::ConfigData->feature('manpage_support') ) {
- plan tests => 22;
+ plan tests => 21;
} else {
plan skip_all => 'manpage_support feature is not enabled';
}
-ensure_blib('Module::Build');
#########################
@@ -139,11 +138,7 @@ $mb->dispatch('realclean');
# revert to a pristine state
-$dist->remove;
-$dist = DistGen->new( dir => $tmp );
-$dist->regen;
-$dist->chdir_in;
-
+$dist->regen( clean => 1 );
my $mb2 = Module::Build->new(
module_name => $dist->name,
@@ -163,6 +158,3 @@ foreach ('testcover', 'disttest') {
unlike $docs, qr/\n=/, $docs;
}
-
-# cleanup
-$dist->remove;
diff --git a/cpan/Module-Build/t/mbyaml.t b/cpan/Module-Build/t/mbyaml.t
deleted file mode 100644
index d2cb0d547f..0000000000
--- a/cpan/Module-Build/t/mbyaml.t
+++ /dev/null
@@ -1,262 +0,0 @@
-#!/usr/local/bin/perl -w
-
-use strict;
-use lib 't/lib';
-use MBTest 'no_plan';
-
-use_ok 'Module::Build::YAML';
-ensure_blib('Module::Build::YAML');
-
-my ($dir);
-$dir = ".";
-$dir = "t" if (-d "t");
-
-{
- my ($expected, $got, $var);
- ##########################################################
- # Test a typical-looking Module::Build structure (alphabetized)
- ##########################################################
- $var = {
- 'resources' => {
- 'license' => 'http://opensource.org/licenses/artistic-license.php'
- },
- 'meta-spec' => {
- 'version' => '1.2',
- 'url' => 'http://module-build.sourceforge.net/META-spec-v1.2.html'
- },
- 'generated_by' => 'Module::Build version 0.2709',
- 'version' => '0.13',
- 'name' => 'js-app',
- 'dynamic_config' => '1',
- 'author' => [
- '"Stephen Adkins" <spadkins@gmail.com>'
- ],
- 'license' => 'lgpl',
- 'build_requires' => {
- 'App::Build' => '0',
- 'File::Spec' => '0',
- 'Module::Build' => '0'
- },
- 'provides' => {
- 'JavaScript::App' => {
- 'version' => '0',
- 'file' => 'lib/JavaScript/App.pm'
- }
- },
- 'requires' => {
- 'App::Options' => '0'
- },
- 'abstract' => 'A framework for building dynamic widgets or full applications in Javascript'
- };
- $expected = <<'EOF';
----
-abstract: A framework for building dynamic widgets or full applications in Javascript
-author:
- - '"Stephen Adkins" <spadkins@gmail.com>'
-build_requires:
- App::Build: 0
- File::Spec: 0
- Module::Build: 0
-dynamic_config: 1
-generated_by: Module::Build version 0.2709
-license: lgpl
-meta-spec:
- url: http://module-build.sourceforge.net/META-spec-v1.2.html
- version: 1.2
-name: js-app
-provides:
- JavaScript::App:
- file: lib/JavaScript/App.pm
- version: 0
-requires:
- App::Options: 0
-resources:
- license: http://opensource.org/licenses/artistic-license.php
-version: 0.13
-EOF
- $got = &Module::Build::YAML::Dump($var);
- is($got, $expected, "Dump(): single deep hash");
-
- ##########################################################
- # Test a typical-looking Module::Build structure (ordered)
- ##########################################################
- $expected = <<'EOF';
----
-name: js-app
-version: 0.13
-author:
- - '"Stephen Adkins" <spadkins@gmail.com>'
-abstract: A framework for building dynamic widgets or full applications in Javascript
-license: lgpl
-resources:
- license: http://opensource.org/licenses/artistic-license.php
-requires:
- App::Options: 0
-build_requires:
- App::Build: 0
- File::Spec: 0
- Module::Build: 0
-dynamic_config: 1
-provides:
- JavaScript::App:
- file: lib/JavaScript/App.pm
- version: 0
-generated_by: Module::Build version 0.2709
-meta-spec:
- url: http://module-build.sourceforge.net/META-spec-v1.2.html
- version: 1.2
-EOF
- $var->{_order} = [qw(name version author abstract license resources requires build_requires dynamic_config provides)];
- $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 = <<'EOF';
----
-e
----
-2.71828
----
-- pi
-- is
-- 3.1416
----
-6: ~
-fun: under_sun
-more: ~
-EOF
- $got = &Module::Build::YAML::Dump(@$var);
- is($got, $expected, "Dump(): multiple, various");
-
- ##########################################################
- # Test that a single array ref turns into one document
- ##########################################################
- $expected = <<'EOF';
----
-- e
-- 2.71828
--
- - pi
- - is
- - 3.1416
--
- 6: ~
- fun: under_sun
- more: ~
-EOF
- $got = &Module::Build::YAML::Dump($var);
- is($got, $expected, "Dump(): single array of various");
-
- ##########################################################
- # Test Object-Oriented Flavor of the API
- ##########################################################
- my $y = Module::Build::YAML->new();
- $got = $y->Dump($var);
- is($got, $expected, "Dump(): single array of various (OO)");
-
- ##########################################################
- # Test Quoting Conditions (newlines, quotes, tildas, undefs)
- ##########################################################
- $var = {
- 'foo01' => '`~!@#$%^&*()_+-={}|[]\\;\':",./?<>
-<nl>',
- 'foo02' => '~!@#$%^&*()_+-={}|[]\\;:,./<>?',
- 'foo03' => undef,
- 'foo04' => '~',
- };
- $expected = <<'EOF';
----
-foo01: "`~!@#$%^&*()_+-={}|[]\;':\",./?<>\n<nl>"
-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/cpan/Module-Build/t/metadata.t b/cpan/Module-Build/t/metadata.t
index 6f53c1d225..2850bea24c 100644
--- a/cpan/Module-Build/t/metadata.t
+++ b/cpan/Module-Build/t/metadata.t
@@ -2,15 +2,13 @@
use strict;
use lib 't/lib';
-use MBTest tests => 53;
+use MBTest tests => 51;
-use_ok 'Module::Build';
-ensure_blib('Module::Build');
+blib_load('Module::Build');
+blib_load('Module::Build::ConfigData');
my $tmp = MBTest->tmpdir;
-use Module::Build::ConfigData;
-
my %metadata =
(
module_name => 'Simple',
@@ -56,7 +54,6 @@ my $simple2_file = 'lib/Simple2.pm';
$dist->chdir_in;
-use Module::Build;
my $mb = Module::Build->new_from_context;
##################################################
@@ -68,7 +65,7 @@ my $mb = Module::Build->new_from_context;
my $mb_config_req = {
'Module::Build' => int($Module::Build::VERSION * 100)/100
};
- my $node = $mb->prepare_metadata( {} );
+ my $node = $mb->prepare_metadata( );
# exists() doesn't seem to work here
is $node->{name}, $metadata{module_name};
@@ -89,7 +86,7 @@ my $mb = Module::Build->new_from_context;
{
my $mb_prereq = { 'Module::Build' => 0 };
$mb->configure_requires( $mb_prereq );
- my $node = $mb->prepare_metadata( {} );
+ my $node = $mb->prepare_metadata( );
# exists() doesn't seem to work here
@@ -366,7 +363,7 @@ package Simple;
$VERSION = '2.34';
---
$dist->regen( clean => 1 );
-$mb = new_build();
+stderr_of( sub { $mb = new_build(); } );
$err = stderr_of( sub { $provides = $mb->find_dist_packages } );
is_deeply($provides,
{'Simple' => { file => $simple_file,
@@ -470,7 +467,7 @@ package Foo;
$VERSION = '2.34';
---
$dist->regen( clean => 1 );
-$mb = new_build();
+stderr_of( sub { $mb = new_build(); } );
$err = stderr_of( sub { $provides = $mb->find_dist_packages } );
# XXX Should 'Foo' exist ??? Can't predict values for file & version
ok( exists( $provides->{Foo} ) );
@@ -604,6 +601,3 @@ $dist->regen( clean => 1 );
$mb = new_build();
is_deeply($mb->find_dist_packages, {});
-############################################################
-# cleanup
-$dist->remove;
diff --git a/cpan/Module-Build/t/metadata2.t b/cpan/Module-Build/t/metadata2.t
index a5af034dc0..954b6589a0 100644
--- a/cpan/Module-Build/t/metadata2.t
+++ b/cpan/Module-Build/t/metadata2.t
@@ -2,14 +2,11 @@
use strict;
use lib 't/lib';
-use MBTest tests => 20;
+use MBTest tests => 18;
-use_ok 'Module::Build';
-ensure_blib('Module::Build');
+blib_load('Module::Build');
+blib_load('Module::Build::ConfigData');
-my $tmp = MBTest->tmpdir;
-
-use Module::Build::ConfigData;
use DistGen;
@@ -19,14 +16,12 @@ SKIP: {
skip( 'YAML_support feature is not enabled', 4 )
unless Module::Build::ConfigData->feature('YAML_support');
- my $dist = DistGen->new( dir => $tmp, no_manifest => 1 );
- $dist->regen;
-
- $dist->chdir_in;
+ my $dist = DistGen->new( no_manifest => 1 )->chdir_in->regen;
ok ! -e 'MANIFEST';
- my $mb = Module::Build->new_from_context;
+ my $mb;
+ stderr_of( sub { $mb = Module::Build->new_from_context } );
my $out;
$out = eval { stderr_of(sub{$mb->dispatch('distmeta')}) };
@@ -36,7 +31,6 @@ SKIP: {
ok -e 'META.yml';
- $dist->remove;
}
@@ -62,7 +56,7 @@ Simple Simon <simon@simple.sim>
=cut
---
-my $dist = DistGen->new( dir => $tmp );
+my $dist = DistGen->new->chdir_in;
$dist->change_build_pl
({
@@ -71,10 +65,6 @@ $dist->change_build_pl
license => 'perl',
create_readme => 1,
});
-$dist->regen;
-
-$dist->chdir_in;
-
# .pm File with pod
#
@@ -139,7 +129,3 @@ is( $mb->dist_author->[0], 'Simple Simon <simon@simple.sim>',
is( $mb->dist_abstract, "A simple module",
"Extracting abstract from .pod over .pm");
-
-############################################################
-# cleanup
-$dist->remove;
diff --git a/cpan/Module-Build/t/moduleinfo.t b/cpan/Module-Build/t/moduleinfo.t
index ca7eb048e5..e28726d493 100644
--- a/cpan/Module-Build/t/moduleinfo.t
+++ b/cpan/Module-Build/t/moduleinfo.t
@@ -4,99 +4,58 @@
use strict;
use lib 't/lib';
-use MBTest tests => 82;
-
-use_ok 'Module::Build::ModuleInfo';
-ensure_blib('Module::Build::ModuleInfo');
-
-my $tmp = MBTest->tmpdir;
-
-use DistGen;
-my $dist = DistGen->new( dir => $tmp );
-$dist->regen;
-
-$dist->chdir_in;
-
-#########################
-
-# class method C<find_module_by_name>
-my $module = Module::Build::ModuleInfo->find_module_by_name(
- 'Module::Build::ModuleInfo' );
-ok( -e $module, 'find_module_by_name() succeeds' );
-
-
-# fail on invalid module name
-my $pm_info = Module::Build::ModuleInfo->new_from_module(
- 'Foo::Bar', inc => [] );
-ok( !defined( $pm_info ), 'fail if can\'t find module by module name' );
-
-
-# fail on invalid filename
-my $file = File::Spec->catfile( 'Foo', 'Bar.pm' );
-$pm_info = Module::Build::ModuleInfo->new_from_file( $file, inc => [] );
-ok( !defined( $pm_info ), 'fail if can\'t find module by file name' );
-
-
-# construct from module filename
-$file = File::Spec->catfile( 'lib', split( /::/, $dist->name ) ) . '.pm';
-$pm_info = Module::Build::ModuleInfo->new_from_file( $file );
-ok( defined( $pm_info ), 'new_from_file() succeeds' );
-
-# construct from module name, using custom include path
-$pm_info = Module::Build::ModuleInfo->new_from_module(
- $dist->name, inc => [ 'lib', @INC ] );
-ok( defined( $pm_info ), 'new_from_module() succeeds' );
-
+use MBTest;
# parse various module $VERSION lines
+# these will be reversed later to create %modules
my @modules = (
- <<'---', # declared & defined on same line with 'our'
+ '1.23' => <<'---', # declared & defined on same line with 'our'
package Simple;
our $VERSION = '1.23';
---
- <<'---', # declared & defined on separate lines with 'our'
+ '1.23' => <<'---', # declared & defined on separate lines with 'our'
package Simple;
our $VERSION;
$VERSION = '1.23';
---
- <<'---', # use vars
+ '1.23' => <<'---', # use vars
package Simple;
use vars qw( $VERSION );
$VERSION = '1.23';
---
- <<'---', # choose the right default package based on package/file name
+ '1.23' => <<'---', # choose the right default package based on package/file name
package Simple::_private;
$VERSION = '0';
package Simple;
$VERSION = '1.23'; # this should be chosen for version
---
- <<'---', # just read the first $VERSION line
+ '1.23' => <<'---', # just read the first $VERSION line
package Simple;
$VERSION = '1.23'; # we should see this line
$VERSION = eval $VERSION; # and ignore this one
---
- <<'---', # just read the first $VERSION line in reopened package (1)
+ '1.23' => <<'---', # just read the first $VERSION line in reopened package (1)
package Simple;
$VERSION = '1.23';
package Error::Simple;
$VERSION = '2.34';
package Simple;
---
- <<'---', # just read the first $VERSION line in reopened package (2)
+ '1.23' => <<'---', # just read the first $VERSION line in reopened package (2)
package Simple;
package Error::Simple;
$VERSION = '2.34';
package Simple;
$VERSION = '1.23';
---
- <<'---', # mentions another module's $VERSION
+ '1.23' => <<'---', # mentions another module's $VERSION
package Simple;
$VERSION = '1.23';
if ( $Other::VERSION ) {
# whatever
}
---
- <<'---', # mentions another module's $VERSION in a different package
+ '1.23' => <<'---', # mentions another module's $VERSION in a different package
package Simple;
$VERSION = '1.23';
package Simple2;
@@ -104,21 +63,21 @@ if ( $Simple::VERSION ) {
# whatever
}
---
- <<'---', # $VERSION checked only in assignments, not regexp ops
+ '1.23' => <<'---', # $VERSION checked only in assignments, not regexp ops
package Simple;
$VERSION = '1.23';
if ( $VERSION =~ /1\.23/ ) {
# whatever
}
---
- <<'---', # $VERSION checked only in assignments, not relational ops
+ '1.23' => <<'---', # $VERSION checked only in assignments, not relational ops
package Simple;
$VERSION = '1.23';
if ( $VERSION == 3.45 ) {
# whatever
}
---
- <<'---', # $VERSION checked only in assignments, not relational ops
+ '1.23' => <<'---', # $VERSION checked only in assignments, not relational ops
package Simple;
$VERSION = '1.23';
package Simple2;
@@ -126,36 +85,36 @@ if ( $Simple::VERSION == 3.45 ) {
# whatever
}
---
- <<'---', # Fully qualified $VERSION declared in package
+ '1.23' => <<'---', # Fully qualified $VERSION declared in package
package Simple;
$Simple::VERSION = 1.23;
---
- <<'---', # Differentiate fully qualified $VERSION in a package
+ '1.23' => <<'---', # Differentiate fully qualified $VERSION in a package
package Simple;
$Simple2::VERSION = '999';
$Simple::VERSION = 1.23;
---
- <<'---', # Differentiate fully qualified $VERSION and unqualified
+ '1.23' => <<'---', # Differentiate fully qualified $VERSION and unqualified
package Simple;
$Simple2::VERSION = '999';
$VERSION = 1.23;
---
- <<'---', # $VERSION declared as package variable from within 'main' package
+ '1.23' => <<'---', # $VERSION declared as package variable from within 'main' package
$Simple::VERSION = '1.23';
{
package Simple;
$x = $y, $cats = $dogs;
}
---
- <<'---', # $VERSION wrapped in parens - space inside
+ '1.23' => <<'---', # $VERSION wrapped in parens - space inside
package Simple;
( $VERSION ) = '1.23';
---
- <<'---', # $VERSION wrapped in parens - no space inside
+ '1.23' => <<'---', # $VERSION wrapped in parens - no space inside
package Simple;
($VERSION) = '1.23';
---
- <<'---', # $VERSION follows a spurious 'package' in a quoted construct
+ '1.23' => <<'---', # $VERSION follows a spurious 'package' in a quoted construct
package Simple;
__PACKAGE__->mk_accessors(qw(
program socket proc
@@ -163,25 +122,87 @@ __PACKAGE__->mk_accessors(qw(
our $VERSION = "1.23";
---
- <<'---', # $VERSION using version.pm
+ '1.23' => <<'---', # $VERSION using version.pm
package Simple;
use version; our $VERSION = version->new('1.23');
---
- <<'---', # $VERSION using version.pm and qv()
+ '1.23' => <<'---', # $VERSION using version.pm and qv()
package Simple;
use version; our $VERSION = qv('1.230');
---
- <<'---', # Two version assignments, should ignore second one
+ '1.23' => <<'---', # Two version assignments, should ignore second one
$Simple::VERSION = '1.230';
$Simple::VERSION = eval $Simple::VERSION;
---
+ '1.23' => <<'---', # declared & defined on same line with 'our'
+package Simple;
+our $VERSION = '1.23_00_00';
+---
+ '1.23' => <<'---', # package NAME VERSION
+ package Simple 1.23;
+---
+ '1.23_01' => <<'---', # package NAME VERSION
+ package Simple 1.23_01;
+---
+ 'v1.2.3' => <<'---', # package NAME VERSION
+ package Simple v1.2.3;
+---
+ 'v1.2_3' => <<'---', # package NAME VERSION
+ package Simple v1.2_3;
+---
);
+my %modules = reverse @modules;
+
+plan tests => 36 + 2 * keys( %modules );
-my( $i, $n ) = ( 1, scalar( @modules ) );
-foreach my $module ( @modules ) {
+blib_load('Module::Build::ModuleInfo');
+
+my $tmp = MBTest->tmpdir;
+
+use DistGen;
+my $dist = DistGen->new( dir => $tmp );
+$dist->regen;
+
+$dist->chdir_in;
+
+#########################
+
+# class method C<find_module_by_name>
+my $module = Module::Build::ModuleInfo->find_module_by_name(
+ 'Module::Build::ModuleInfo' );
+ok( -e $module, 'find_module_by_name() succeeds' );
+
+
+# fail on invalid module name
+my $pm_info = Module::Build::ModuleInfo->new_from_module(
+ 'Foo::Bar', inc => [] );
+ok( !defined( $pm_info ), 'fail if can\'t find module by module name' );
+
+
+# fail on invalid filename
+my $file = File::Spec->catfile( 'Foo', 'Bar.pm' );
+$pm_info = Module::Build::ModuleInfo->new_from_file( $file, inc => [] );
+ok( !defined( $pm_info ), 'fail if can\'t find module by file name' );
+
+
+# construct from module filename
+$file = File::Spec->catfile( 'lib', split( /::/, $dist->name ) ) . '.pm';
+$pm_info = Module::Build::ModuleInfo->new_from_file( $file );
+ok( defined( $pm_info ), 'new_from_file() succeeds' );
+
+# construct from module name, using custom include path
+$pm_info = Module::Build::ModuleInfo->new_from_module(
+ $dist->name, inc => [ 'lib', @INC ] );
+ok( defined( $pm_info ), 'new_from_module() succeeds' );
+
+
+foreach my $module ( sort keys %modules ) {
+ my $expected = $modules{$module};
SKIP: {
skip( "No our() support until perl 5.6", 2 )
- if $] < 5.006 && $module =~ /\bour\b/;
+ if $] < 5.006 && $module =~ /\bour\b/;
+ skip( "No package NAME VERSION support until perl 5.11.1", 2 )
+ if $] < 5.011001 && $module =~ /package\s+[\w\:\']+\s+v?[0-9._]+/;
$dist->change_file( 'lib/Simple.pm', $module );
$dist->regen;
@@ -191,19 +212,17 @@ foreach my $module ( @modules ) {
my $pm_info = Module::Build::ModuleInfo->new_from_file( $file );
# Test::Builder will prematurely numify objects, so use this form
- ok( $pm_info->version eq '1.23',
- "correct module version ($i of $n)" );
- is( $warnings, '', 'no warnings from parsing' );
- $i++;
+ my $errs;
+ ok( $pm_info->version eq $expected,
+ "correct module version (expected '$expected')" )
+ or $errs++;
+ is( $warnings, '', 'no warnings from parsing' ) or $errs++;
+ diag "Got: '@{[$pm_info->version]}'\nModule contents:\n$module" if $errs;
}
}
# revert to pristine state
-$dist->remove;
-$dist = DistGen->new( dir => $tmp );
-$dist->regen;
-$dist->chdir_in;
-
+$dist->regen( clean => 1 );
# Find each package only once
$dist->change_file( 'lib/Simple.pm', <<'---' );
@@ -249,19 +268,15 @@ $pm_info = Module::Build::ModuleInfo->new_from_file( $file );
is( $pm_info->version, '1.23_01', 'alpha version reported');
# NOTE the following test has be done this way because Test::Builder is
-# too smart for our own good and tries to see if the version object is a
+# too smart for our own good and tries to see if the version object is a
# dual-var, which breaks with alpha versions:
# Argument "1.23_0100" isn't numeric in addition (+) at
-# /usr/lib/perl5/5.8.7/Test/Builder.pm line 505.
+# /usr/lib/perl5/5.8.7/Test/Builder.pm line 505.
ok( $pm_info->version > 1.23, 'alpha version greater than non');
# revert to pristine state
-$dist->remove;
-$dist = DistGen->new( dir => $tmp );
-$dist->regen;
-$dist->chdir_in;
-
+$dist->regen( clean => 1 );
# parse $VERSION lines scripts for package main
my @scripts = (
@@ -313,7 +328,7 @@ $::VERSION = 0.01;
---
);
-( $i, $n ) = ( 1, scalar( @scripts ) );
+my ( $i, $n ) = ( 1, scalar( @scripts ) );
foreach my $script ( @scripts ) {
$dist->change_file( 'bin/simple.plx', $script );
$dist->regen;
@@ -402,7 +417,7 @@ __DATA__
is( $pm_info->name, 'Simple', 'found default package' );
is( $pm_info->version, '0.01', 'version for default package' );
my @packages = $pm_info->packages_inside;
- is_deeply(\@packages, ['Simple']);
+ is_deeply(\@packages, ['Simple'], 'packages inside');
}
{
@@ -419,10 +434,7 @@ $VERSION = version->new('0.61.' . (qw$Revision: 129 $)[1]);
is( $pm_info->name, 'Simple', 'found default package' );
is( $pm_info->version, '0.60.128', 'version for default package' );
my @packages = $pm_info->packages_inside;
- is_deeply([sort @packages], ['Simple', 'Simple::Simon']);
+ is_deeply([sort @packages], ['Simple', 'Simple::Simon'], 'packages inside');
is( $pm_info->version('Simple::Simon'), '0.61.129', 'version for embedded package' );
}
-
-# cleanup
-$dist->remove;
diff --git a/cpan/Module-Build/t/mymeta.t b/cpan/Module-Build/t/mymeta.t
new file mode 100644
index 0000000000..c60a5b2420
--- /dev/null
+++ b/cpan/Module-Build/t/mymeta.t
@@ -0,0 +1,30 @@
+#!/usr/bin/perl -w
+
+use strict;
+use lib 't/lib';
+use MBTest tests => 3;
+
+blib_load('Module::Build');
+
+my $tmp = MBTest->tmpdir;
+
+use DistGen;
+my $dist = DistGen->new( dir => $tmp );
+$dist->regen;
+$dist->chdir_in;
+
+#########################
+
+# Test MYMETA generation
+{
+ ok( ! -e "MYMETA.yml", "MYMETA.yml doesn't exist before Build.PL runs" );
+ my $output;
+ $output = stdout_of sub { $dist->run_build_pl };
+ like($output, qr/Creating new 'MYMETA.yml' with configuration results/,
+ "Saw MYMETA.yml creation message"
+ );
+ ok( -e "MYMETA.yml", "MYMETA.yml exists" );
+}
+
+#########################
+
diff --git a/cpan/Module-Build/t/new_from_context.t b/cpan/Module-Build/t/new_from_context.t
index ee34f07367..f45a1760eb 100644
--- a/cpan/Module-Build/t/new_from_context.t
+++ b/cpan/Module-Build/t/new_from_context.t
@@ -2,10 +2,9 @@
use strict;
use lib 't/lib';
-use MBTest tests => 4;
+use MBTest tests => 2;
-use_ok 'Module::Build';
-ensure_blib('Module::Build');
+blib_load('Module::Build');
use IO::File;
my $tmp = MBTest->tmpdir;
@@ -25,7 +24,4 @@ my $mb = eval { Module::Build->new_from_context};
ok(! $@, 'dodged the bullet') or die;
ok($mb);
-# cleanup
-$dist->remove;
-
# vim:ts=2:sw=2:et:sta
diff --git a/cpan/Module-Build/t/notes.t b/cpan/Module-Build/t/notes.t
index 29f1fc38b1..4568e7c36a 100644
--- a/cpan/Module-Build/t/notes.t
+++ b/cpan/Module-Build/t/notes.t
@@ -2,10 +2,9 @@
use strict;
use lib 't/lib';
-use MBTest tests => 13;
+use MBTest tests => 11;
-use_ok 'Module::Build';
-ensure_blib('Module::Build');
+blib_load('Module::Build');
my $tmp = MBTest->tmpdir;
@@ -65,6 +64,3 @@ $mb = Module::Build->resume;
ok $mb;
is $mb->notes('foo'), 'bar';
-
-# cleanup
-$dist->remove;
diff --git a/cpan/Module-Build/t/parents.t b/cpan/Module-Build/t/parents.t
index 666fb05601..825f79a787 100644
--- a/cpan/Module-Build/t/parents.t
+++ b/cpan/Module-Build/t/parents.t
@@ -2,10 +2,9 @@
use strict;
use lib 't/lib';
-use MBTest tests => 28;
+use MBTest tests => 26;
-use_ok 'Module::Build';
-ensure_blib('Module::Build');
+blib_load('Module::Build');
#########################
diff --git a/cpan/Module-Build/t/perl_mb_opt.t b/cpan/Module-Build/t/perl_mb_opt.t
new file mode 100644
index 0000000000..70089ee6be
--- /dev/null
+++ b/cpan/Module-Build/t/perl_mb_opt.t
@@ -0,0 +1,62 @@
+# sample.t -- a sample test file for Module::Build
+
+use strict;
+use lib 't/lib';
+use MBTest;
+use DistGen;
+
+plan tests => 8; # or 'no_plan'
+
+# Ensure any Module::Build modules are loaded from correct directory
+blib_load('Module::Build');
+
+# create dist object in a temp directory
+# enter the directory and generate the skeleton files
+my $dist = DistGen->new->chdir_in->regen;
+
+$dist->add_file('t/subtest/foo.t', <<'END_T');
+use strict;
+use Test::More tests => 1;
+ok(1, "this is a recursive test");
+END_T
+
+$dist->regen;
+
+# get a Module::Build object and test with it
+my $mb = $dist->new_from_context(); # quiet by default
+isa_ok( $mb, "Module::Build" );
+is( $mb->dist_name, "Simple", "dist_name is 'Simple'" );
+ok( ! $mb->recursive_test_files, "set for no recursive testing" );
+
+# set for recursive testing using PERL_MB_OPT
+{
+ local $ENV{PERL_MB_OPT} = "--verbose --recursive_test_files 1";
+
+ my $out = stdout_stderr_of( sub {
+ $dist->run_build('test');
+ });
+ like( $out, qr/this is a recursive test/,
+ "recursive tests run via PERL_MB_OPT"
+ );
+}
+
+# set Build.PL opts using PERL_MB_OPT
+{
+ local $ENV{PERL_MB_OPT} = "--verbose --recursive_test_files 1";
+ my $mb = $dist->new_from_context(); # quiet by default
+ ok( $mb->recursive_test_files, "PERL_MB_OPT set recusive tests in Build.PL" );
+ ok( $mb->verbose, "PERL_MB_OPT set verbose in Build.PL" );
+}
+
+# verify settings preserved during 'Build test'
+{
+ ok( !$ENV{PERL_MB_OPT}, "PERL_MB_OPT cleared" );
+ my $out = stdout_stderr_of( sub {
+ $dist->run_build('test');
+ });
+ like( $out, qr/this is a recursive test/,
+ "recursive tests run via Build object"
+ );
+}
+
+# vim:ts=2:sw=2:et:sta:sts=2
diff --git a/cpan/Module-Build/t/pod_parser.t b/cpan/Module-Build/t/pod_parser.t
index 42a78209e2..64d4c75348 100644
--- a/cpan/Module-Build/t/pod_parser.t
+++ b/cpan/Module-Build/t/pod_parser.t
@@ -2,10 +2,9 @@
use strict;
use lib 't/lib';
-use MBTest tests => 8;
+use MBTest tests => 9;
-use_ok 'Module::Build::PodParser';
-ensure_blib('Module::Build::PodParser');
+blib_load('Module::Build::PodParser');
#########################
@@ -66,3 +65,26 @@ EOF
}
+{
+ # Try again with mixed-case =head1s.
+ untie *FH;
+ tie *FH, 'IO::StringBased', <<'EOF';
+=head1 Name
+
+Foo::Bar - Perl extension for blah blah blah
+
+=head1 Author
+
+C<Foo::Bar> was written by Engelbert Humperdinck I<E<lt>eh@example.comE<gt>> in 2004.
+
+Home page: http://example.com/~eh/
+
+=cut
+EOF
+
+ my $pp = Module::Build::PodParser->new(fh => \*FH);
+ ok $pp, 'object created';
+
+ is $pp->get_author->[0], 'C<Foo::Bar> was written by Engelbert Humperdinck I<E<lt>eh@example.comE<gt>> in 2004.', 'author';
+ is $pp->get_abstract, 'Perl extension for blah blah blah', 'abstract';
+}
diff --git a/cpan/Module-Build/t/ppm.t b/cpan/Module-Build/t/ppm.t
index 7fb6450648..4d69c9767a 100644
--- a/cpan/Module-Build/t/ppm.t
+++ b/cpan/Module-Build/t/ppm.t
@@ -3,11 +3,10 @@
use strict;
use lib 't/lib';
use MBTest;
-
-use Module::Build;
-use Module::Build::ConfigData;
use Config;
+blib_load('Module::Build');
+blib_load('Module::Build::ConfigData');
my $manpage_support = Module::Build::ConfigData->feature('manpage_support');
my $HTML_support = Module::Build::ConfigData->feature('HTML_support');
@@ -26,15 +25,13 @@ my $HTML_support = Module::Build::ConfigData->feature('HTML_support');
} elsif ( $^O eq 'VMS' ) {
plan skip_all => "Needs porting work on VMS";
} else {
- plan tests => 13;
+ plan tests => 12;
}
}
-ensure_blib('Module::Build');
my $tmp = MBTest->tmpdir;
-
use DistGen;
my $dist = DistGen->new( dir => $tmp, xs => 1 );
$dist->add_file( 'hello', <<'---' );
@@ -66,7 +63,6 @@ $dist->chdir_in;
use File::Spec::Functions qw(catdir);
-use Module::Build;
my @installstyle = qw(lib perl5);
my $mb = Module::Build->new_from_context(
verbose => 0,
@@ -98,13 +94,10 @@ my $varchname = Module::Build::PPMMaker->_varchname($mb->config);
# do a strict string comparison, but absent an XML parser it's the
# best we can do.
is $ppd, <<"---";
-<SOFTPKG NAME="$dist_filename" VERSION="0,01,0,0">
- <TITLE>@{[$dist->name]}</TITLE>
+<SOFTPKG NAME="$dist_filename" VERSION="0.01">
<ABSTRACT>Perl extension for blah blah blah</ABSTRACT>
<AUTHOR>A. U. Thor, a.u.thor\@a.galaxy.far.far.away</AUTHOR>
<IMPLEMENTATION>
- <PERLCORE VERSION="$perl_version" />
- <OS NAME="$^O" />
<ARCHITECTURE NAME="$varchname" />
<CODEBASE HREF="/path/to/codebase-xs" />
</IMPLEMENTATION>
@@ -185,9 +178,6 @@ SKIP: {
}
-$dist->remove;
-
-
########################################
sub exists_ok {
diff --git a/cpan/Module-Build/t/properties/module_name.t b/cpan/Module-Build/t/properties/module_name.t
new file mode 100644
index 0000000000..c266b41ba2
--- /dev/null
+++ b/cpan/Module-Build/t/properties/module_name.t
@@ -0,0 +1,53 @@
+# sample.t -- a sample test file for Module::Build
+
+use strict;
+use lib 't/lib';
+use MBTest;
+use DistGen;
+
+plan tests => 4;
+
+# Ensure any Module::Build modules are loaded from correct directory
+blib_load('Module::Build');
+
+# enter the directory and generate the skeleton files
+my $dist = DistGen->new( name => "Not::So::Simple" )->chdir_in;
+
+#--------------------------------------------------------------------------#
+# try getting module_name from dist directory name
+#--------------------------------------------------------------------------#
+
+$dist->change_build_pl(
+ dist_name => 'Random-Name',
+ dist_version => 1,
+)->regen;
+
+my $mb = $dist->new_from_context();
+isa_ok( $mb, "Module::Build" );
+is( $mb->module_name, "Not::So::Simple",
+ "module_name guessed from directory name"
+);
+
+#--------------------------------------------------------------------------#
+# Try getting module_name from dist_version_from
+#--------------------------------------------------------------------------#
+
+$dist->add_file( 'lib/Simple/Name.pm', << 'END_PACKAGE' );
+package Simple::Name;
+our $VERSION = 1.23;
+1;
+END_PACKAGE
+
+$dist->change_build_pl(
+ dist_name => 'Random-Name',
+ dist_version_from => 'lib/Simple/Name.pm',
+ dist_abstract => "Don't complain about missing abstract",
+)->regen( clean => 1 );
+
+$mb = $dist->new_from_context();
+isa_ok( $mb, "Module::Build" );
+is( $mb->module_name, "Simple::Name",
+ "module_name guessed from dist_version_from"
+);
+
+# vim:ts=2:sw=2:et:sta:sts=2
diff --git a/cpan/Module-Build/t/properties/needs_compiler.t b/cpan/Module-Build/t/properties/needs_compiler.t
new file mode 100644
index 0000000000..f298e82739
--- /dev/null
+++ b/cpan/Module-Build/t/properties/needs_compiler.t
@@ -0,0 +1,122 @@
+# sample.t -- a sample test file for Module::Build
+
+use strict;
+use lib 't/lib';
+use MBTest;
+use DistGen;
+
+plan tests => 19;
+
+# Ensure any Module::Build modules are loaded from correct directory
+blib_load('Module::Build');
+
+my $dist = DistGen->new->regen->chdir_in;
+
+# get a Module::Build object and test with it
+my $mb;
+stderr_of(sub {
+ ok( $mb = $dist->new_from_context, "Default Build.PL" );
+});
+
+ok( ! $mb->needs_compiler, "needs_compiler is false" );
+ok( ! exists $mb->{properties}{build_requires}{'ExtUtils::CBuilder'},
+ "ExtUtils::CBuilder is not in build_requires"
+);
+
+#--------------------------------------------------------------------------#
+# try with c_source
+#--------------------------------------------------------------------------#
+$dist->change_build_pl({
+ module_name => $dist->name,
+ license => 'perl',
+ c_source => 'src',
+});
+$dist->regen;
+stderr_of(sub {
+ ok( $mb = $dist->new_from_context,
+ "Build.PL with c_source"
+ );
+});
+is( $mb->c_source, 'src', "c_source is set" );
+ok( $mb->needs_compiler, "needs_compiler is true" );
+ok( exists $mb->{properties}{build_requires}{'ExtUtils::CBuilder'},
+ "ExtUtils::CBuilder was added to build_requires"
+);
+
+#--------------------------------------------------------------------------#
+# try with xs files
+#--------------------------------------------------------------------------#
+$dist = DistGen->new(dir => 'MBTest', xs => 1);
+$dist->regen;
+$dist->chdir_in;
+
+stderr_of(sub {
+ ok( $mb = $dist->new_from_context,
+ "Build.PL with xs files"
+ );
+});
+ok( $mb->needs_compiler, "needs_compiler is true" );
+ok( exists $mb->{properties}{build_requires}{'ExtUtils::CBuilder'},
+ "ExtUtils::CBuilder was added to build_requires"
+);
+
+#--------------------------------------------------------------------------#
+# force needs_compiler off, despite xs modules
+#--------------------------------------------------------------------------#
+
+$dist->change_build_pl({
+ module_name => $dist->name,
+ license => 'perl',
+ needs_compiler => 0,
+});
+$dist->regen;
+
+stderr_of(sub {
+ ok( $mb = $dist->new_from_context ,
+ "Build.PL with xs files, but needs_compiler => 0"
+ );
+});
+is( $mb->needs_compiler, 0, "needs_compiler is false" );
+ok( ! exists $mb->{properties}{build_requires}{'ExtUtils::CBuilder'},
+ "ExtUtils::CBuilder is not in build_requires"
+);
+
+#--------------------------------------------------------------------------#
+# don't override specific EU::CBuilder build_requires
+#--------------------------------------------------------------------------#
+
+$dist->change_build_pl({
+ module_name => $dist->name,
+ license => 'perl',
+ build_requires => { 'ExtUtils::CBuilder' => 0.2 },
+});
+$dist->regen;
+
+stderr_of(sub {
+ ok( $mb = $dist->new_from_context ,
+ "Build.PL with xs files, build_requires EU::CB 0.2"
+ );
+});
+ok( $mb->needs_compiler, "needs_compiler is true" );
+is( $mb->build_requires->{'ExtUtils::CBuilder'}, 0.2,
+ "build_requires for ExtUtils::CBuilder is correct version"
+);
+
+#--------------------------------------------------------------------------#
+# falsify compiler and test error handling
+#--------------------------------------------------------------------------#
+
+my $err = stderr_of( sub {
+ $mb = $dist->new_from_context( config => { cc => "adfasdfadjdjk" } )
+});
+ok( $mb, "Build.PL while hiding compiler" );
+like( $err, qr/no compiler detected/,
+ "hidden compiler resulted in warning message during Build.PL"
+);
+eval { $mb->dispatch('build') };
+like( $@, qr/no compiler detected/,
+ "hidden compiler resulted in fatal message during Build"
+);
+
+
+# vim:ts=2:sw=2:et:sta:sts=2
diff --git a/cpan/Module-Build/t/properties/share_dir.t b/cpan/Module-Build/t/properties/share_dir.t
new file mode 100644
index 0000000000..f781a8a7ce
--- /dev/null
+++ b/cpan/Module-Build/t/properties/share_dir.t
@@ -0,0 +1,228 @@
+#!/usr/bin/perl -w
+
+use strict;
+use lib 't/lib';
+use MBTest;
+use File::Spec::Functions qw/catdir catfile/;
+
+#--------------------------------------------------------------------------#
+# Begin testing
+#--------------------------------------------------------------------------#
+
+plan tests => 21;
+
+blib_load('Module::Build');
+
+#--------------------------------------------------------------------------#
+# Create test distribution
+#--------------------------------------------------------------------------#
+
+my $tmp = MBTest->tmpdir;
+
+use DistGen;
+my $dist = DistGen->new( dir => $tmp, name => 'Simple::Share' );
+$dist->regen;
+$dist->chdir_in;
+
+#--------------------------------------------------------------------------#
+# Test setting 'share_dir'
+#--------------------------------------------------------------------------#
+
+my $mb = $dist->new_from_context;
+
+# Test without a 'share' dir
+ok( $mb, "Created Module::Build object" );
+is( $mb->share_dir, undef,
+ "default share undef if no 'share' dir exists"
+);
+ok( ! exists $mb->{properties}{requires}{'File::ShareDir'},
+ "File::ShareDir not added to 'requires'"
+);
+
+# Add 'share' dir and an 'other' dir and content
+$dist->add_file('share/foo.txt',<< '---');
+This is foo.txt
+---
+$dist->add_file('other/share/bar.txt',<< '---');
+This is bar.txt
+---
+$dist->regen;
+ok( -e catfile(qw/share foo.txt/), "Created 'share' directory" );
+ok( -e catfile(qw/other share bar.txt/), "Created 'other/share' directory" );
+
+# Check default when share_dir is not given
+stdout_stderr_of( sub { $mb = $dist->new_from_context });
+is_deeply( $mb->share_dir, { dist => [ 'share' ] },
+ "Default share_dir set as dist-type share"
+);
+is( $mb->{properties}{requires}{'File::ShareDir'}, '1.00',
+ "File::ShareDir 1.00 added to 'requires'"
+);
+
+# share_dir set to scalar
+$dist->change_build_pl(
+ {
+ module_name => $dist->name,
+ license => 'perl',
+ share_dir => 'share',
+ }
+);
+$dist->regen;
+stdout_stderr_of( sub { $mb = $dist->new_from_context });
+is_deeply( $mb->share_dir, { dist => [ 'share' ] },
+ "Scalar share_dir set as dist-type share"
+);
+
+# share_dir set to arrayref
+$dist->change_build_pl(
+ {
+ module_name => $dist->name,
+ license => 'perl',
+ share_dir => [ 'share' ],
+ }
+);
+$dist->regen;
+stdout_stderr_of( sub { $mb = $dist->new_from_context });
+is_deeply( $mb->share_dir, { dist => [ 'share' ] },
+ "Arrayref share_dir set as dist-type share"
+);
+
+# share_dir set to hashref w scalar
+$dist->change_build_pl(
+ {
+ module_name => $dist->name,
+ license => 'perl',
+ share_dir => { dist => 'share' },
+ }
+);
+$dist->regen;
+stdout_stderr_of( sub { $mb = $dist->new_from_context });
+is_deeply( $mb->share_dir, { dist => [ 'share' ] },
+ "Hashref share_dir w/ scalar dist set as dist-type share"
+);
+
+# share_dir set to hashref w array
+$dist->change_build_pl(
+ {
+ module_name => $dist->name,
+ license => 'perl',
+ share_dir => { dist => [ 'share' ] },
+ }
+);
+$dist->regen;
+stdout_stderr_of( sub { $mb = $dist->new_from_context });
+is_deeply( $mb->share_dir, { dist => [ 'share' ] },
+ "Hashref share_dir w/ arrayref dist set as dist-type share"
+);
+
+# Generate a module sharedir (scalar)
+$dist->change_build_pl(
+ {
+ module_name => $dist->name,
+ license => 'perl',
+ share_dir => {
+ dist => 'share',
+ module => { $dist->name => 'other/share' },
+ },
+ }
+);
+$dist->regen;
+stdout_stderr_of( sub { $mb = $dist->new_from_context });
+is_deeply( $mb->share_dir,
+ { dist => [ 'share' ],
+ module => { $dist->name => ['other/share'] },
+ },
+ "Hashref share_dir w/ both dist and module shares (scalar-form)"
+);
+
+# Generate a module sharedir (array)
+$dist->change_build_pl(
+ {
+ module_name => $dist->name,
+ license => 'perl',
+ share_dir => {
+ dist => [ 'share' ],
+ module => { $dist->name => ['other/share'] },
+ },
+ }
+);
+$dist->regen;
+stdout_stderr_of( sub { $mb = $dist->new_from_context });
+is_deeply( $mb->share_dir,
+ { dist => [ 'share' ],
+ module => { $dist->name => ['other/share'] },
+ },
+ "Hashref share_dir w/ both dist and module shares (array-form)"
+);
+
+#--------------------------------------------------------------------------#
+# test constructing to/from mapping
+#--------------------------------------------------------------------------#
+
+is_deeply( $mb->_find_share_dir_files,
+ {
+ catfile(qw/share foo.txt/) => catfile(qw/dist Simple-Share foo.txt/),
+ catfile(qw/other share bar.txt/) => catfile(qw/module Simple-Share bar.txt/),
+ },
+ "share_dir filemap for copying to lib complete"
+);
+
+#--------------------------------------------------------------------------#
+# test moving files to blib
+#--------------------------------------------------------------------------#
+
+$mb->dispatch('build');
+
+ok( -d 'blib', "Build ran and blib exists" );
+ok( -d 'blib/lib/auto/share', "blib/lib/auto/share exists" );
+
+my $share_list = Module::Build->rscan_dir('blib/lib/auto/share', sub {-f});
+
+is_deeply(
+ [ sort @$share_list ], [
+ 'blib/lib/auto/share/dist/Simple-Share/foo.txt',
+ 'blib/lib/auto/share/module/Simple-Share/bar.txt',
+ ],
+ "share_dir files copied to blib"
+);
+
+#--------------------------------------------------------------------------#
+# test installing
+#--------------------------------------------------------------------------#
+
+my $temp_install = 'temp_install';
+mkdir $temp_install;
+ok( -d $temp_install, "temp install dir created" );
+
+$mb->install_base($temp_install);
+stdout_of( sub { $mb->dispatch('install') } );
+
+$share_list = Module::Build->rscan_dir(
+ "$temp_install/lib/perl5/auto/share", sub {-f}
+);
+
+is_deeply(
+ [ sort @$share_list ], [
+ "$temp_install/lib/perl5/auto/share/dist/Simple-Share/foo.txt",
+ "$temp_install/lib/perl5/auto/share/module/Simple-Share/bar.txt",
+ ],
+ "share_dir files correctly installed"
+);
+
+#--------------------------------------------------------------------------#
+# test with File::ShareDir
+#--------------------------------------------------------------------------#
+
+SKIP: {
+ eval { require File::ShareDir; File::ShareDir->VERSION(1.00) };
+ skip "needs File::ShareDir 1.00", 2 if $@;
+
+ unshift @INC, File::Spec->catdir($temp_install, qw/lib perl5/);
+ require Simple::Share;
+
+ eval {File::ShareDir::dist_file('Simple-Share','foo.txt') };
+ is( $@, q{}, "Found shared dist file" );
+
+ eval {File::ShareDir::module_file('Simple::Share','bar.txt') };
+ is( $@, q{}, "Found shared module file" );
+}
diff --git a/cpan/Module-Build/t/resume.t b/cpan/Module-Build/t/resume.t
new file mode 100644
index 0000000000..add123d3d4
--- /dev/null
+++ b/cpan/Module-Build/t/resume.t
@@ -0,0 +1,43 @@
+use strict;
+use lib 't/lib';
+use MBTest;
+plan tests => 3; # or 'no_plan'
+use DistGen;
+
+# Ensure any Module::Build modules are loaded from correct directory
+blib_load('Module::Build');
+
+# create dist object in a temp directory
+# enter the directory and generate the skeleton files
+my $dist = DistGen->new->chdir_in;
+$dist->add_file('mylib/MBUtil.pm', << "---");
+package MBUtil;
+sub foo { 42 }
+1;
+---
+
+$dist->add_file('Build.PL', << "---");
+use strict;
+use lib 'mylib';
+use MBUtil;
+use Module::Build;
+
+die unless MBUtil::foo() == 42;
+
+my \$builder = Module::Build->new(
+module_name => '$dist->{name}',
+license => 'perl',
+);
+
+\$builder->create_build_script();
+---
+
+$dist->regen;
+
+# get a Module::Build object and test with it
+my $mb = $dist->new_from_context(); # quiet by default
+isa_ok( $mb, "Module::Build" );
+is( $mb->dist_name, "Simple", "dist_name is 'Simple'" );
+ok( ( grep { /mylib/ } @INC ), "resume added \@INC addition to \@INC");
+
+# vim:ts=2:sw=2:et:sta:sts=2
diff --git a/cpan/Module-Build/t/runthrough.t b/cpan/Module-Build/t/runthrough.t
index 21d3d1c113..741755c12c 100644
--- a/cpan/Module-Build/t/runthrough.t
+++ b/cpan/Module-Build/t/runthrough.t
@@ -2,12 +2,10 @@
use strict;
use lib 't/lib';
-use MBTest tests => 32;
+use MBTest tests => 30;
-use_ok 'Module::Build';
-ensure_blib('Module::Build');
-
-use Module::Build::ConfigData;
+blib_load('Module::Build');
+blib_load('Module::Build::ConfigData');
my $have_yaml = Module::Build::ConfigData->feature('YAML_support');
#########################
@@ -24,6 +22,9 @@ $dist->change_build_pl
requires => { 'File::Spec' => 0 },
});
+$dist->add_file( 'MANIFEST.SKIP', <<'---' );
+^MYMETA.yml$
+---
$dist->add_file( 'script', <<'---' );
#!perl -w
print "Hello, World!\n";
@@ -169,12 +170,11 @@ SKIP: {
# do a strict string comparison, but absent an XML parser it's the
# best we can do.
is $ppd, <<'EOF';
-<SOFTPKG NAME="Simple" VERSION="0,01,0,0">
- <TITLE>Simple</TITLE>
+<SOFTPKG NAME="Simple" VERSION="0.01">
<ABSTRACT>Perl extension for blah blah blah</ABSTRACT>
<AUTHOR>A. U. Thor, a.u.thor@a.galaxy.far.far.away</AUTHOR>
<IMPLEMENTATION>
- <DEPENDENCY NAME="File-Spec" VERSION="0,0,0,0" />
+ <REQUIRE NAME="File::Spec" VERSION="0" />
<CODEBASE HREF="/path/to/codebase" />
</IMPLEMENTATION>
</SOFTPKG>
@@ -189,8 +189,6 @@ ok ! -e $mb->build_script;
ok ! -e $mb->config_dir;
ok ! -e $mb->dist_dir;
-$dist->remove;
-
SKIP: {
skip( 'Windows-only test', 4 ) unless $^O =~ /^MSWin/;
@@ -223,8 +221,5 @@ echo Hello, World!
my $out = slurp( $script_file );
is $out, $script_data, ' unmodified by pl2bat';
- $dist->remove;
}
-# cleanup
-$dist->remove;
diff --git a/cpan/Module-Build/t/sample.t b/cpan/Module-Build/t/sample.t
new file mode 100644
index 0000000000..d83bc56ecc
--- /dev/null
+++ b/cpan/Module-Build/t/sample.t
@@ -0,0 +1,20 @@
+# sample.t -- a sample test file for Module::Build
+
+use strict;
+use lib 't/lib';
+use MBTest tests => 2; # or 'no_plan'
+use DistGen;
+
+# Ensure any Module::Build modules are loaded from correct directory
+blib_load('Module::Build');
+
+# create dist object in a temp directory
+# enter the directory and generate the skeleton files
+my $dist = DistGen->new->chdir_in->regen;
+
+# get a Module::Build object and test with it
+my $mb = $dist->new_from_context(); # quiet by default
+isa_ok( $mb, "Module::Build" );
+is( $mb->dist_name, "Simple", "dist_name is 'Simple'" );
+
+# vim:ts=2:sw=2:et:sta:sts=2
diff --git a/cpan/Module-Build/t/script_dist.t b/cpan/Module-Build/t/script_dist.t
index e6b7fd8832..02faca0132 100644
--- a/cpan/Module-Build/t/script_dist.t
+++ b/cpan/Module-Build/t/script_dist.t
@@ -8,7 +8,8 @@ use MBTest 'no_plan';
use DistGen qw(undent);
-use Module::Build;
+blib_load('Module::Build');
+blib_load('Module::Build::ConfigData');
# XXX DistGen shouldn't be assuming module-ness?
my $dist = DistGen->new(dir => MBTest->tmpdir);
@@ -69,12 +70,11 @@ is_deeply($mb->dist_author,
['A. U. Thor, a.u.thor@a.galaxy.far.far.away']);
ok $mb->dispatch('distmeta');
-use Module::Build::ConfigData;
SKIP: {
skip( 'YAML_support feature is not enabled', 1 )
unless Module::Build::ConfigData->feature('YAML_support');
- require YAML;
- my $yml = YAML::LoadFile('META.yml');
+ require YAML::Tiny;
+ my $yml = YAML::Tiny::LoadFile('META.yml');
is_deeply($yml->{provides}, \%meta_provides);
}
$dist->chdir_original if $dist->did_chdir;
diff --git a/cpan/Module-Build/t/test_file_exts.t b/cpan/Module-Build/t/test_file_exts.t
index 9dbf73e290..5bb803c7aa 100644
--- a/cpan/Module-Build/t/test_file_exts.t
+++ b/cpan/Module-Build/t/test_file_exts.t
@@ -2,11 +2,10 @@
use strict;
use lib 't/lib';
-use MBTest tests => 5;
+use MBTest tests => 3;
use DistGen;
-use_ok 'Module::Build';
-ensure_blib('Module::Build');
+blib_load('Module::Build');
my $tmp = MBTest->tmpdir;
my $dist = DistGen->new( dir => $tmp );
@@ -39,7 +38,4 @@ my $out = uc(stdout_of(
like $out, qr/^OK 1 - FIRST MYTEST[.]S/m, 'Should see first test output';
like $out, qr/^OK 2 - SECOND MYTEST[.]S/m, 'Should see second test output';
-# Cleanup.
-$dist->remove;
-
# vim:ts=4:sw=4:et:sta
diff --git a/cpan/Module-Build/t/test_type.t b/cpan/Module-Build/t/test_type.t
index 3c6cfb61e4..fe4d599d72 100644
--- a/cpan/Module-Build/t/test_type.t
+++ b/cpan/Module-Build/t/test_type.t
@@ -9,10 +9,9 @@ BEGIN {
use strict;
use lib 't/lib';
-use MBTest tests => 9;
+use MBTest tests => 7;
-use_ok 'Module::Build';
-ensure_blib('Module::Build');
+blib_load('Module::Build');
my $tmp = MBTest->tmpdir;
@@ -72,6 +71,4 @@ like($output, qr/\.\. ?OK/);
is($::x, 3, "called a third time");
-$dist->remove;
-
# vim:ts=4:sw=4:et:sta
diff --git a/cpan/Module-Build/t/test_types.t b/cpan/Module-Build/t/test_types.t
index 5f3f5cff8d..d88e215aa3 100644
--- a/cpan/Module-Build/t/test_types.t
+++ b/cpan/Module-Build/t/test_types.t
@@ -2,16 +2,13 @@
use strict;
use lib 't/lib';
-use MBTest tests => 15 + 12;
+use MBTest tests => 25;
-use_ok 'Module::Build';
-ensure_blib('Module::Build');
-
-my $tmp = MBTest->tmpdir;
+blib_load('Module::Build');
use DistGen;
-my $dist = DistGen->new(dir => $tmp);
+my $dist = DistGen->new()->chdir_in;
$dist->add_file('t/special_ext.st', <<'---');
#!perl
@@ -34,7 +31,6 @@ die "don't run this non-test file";
---
$dist->regen;
-$dist->chdir_in;
#########################
my $mb = Module::Build->subclass(
@@ -98,10 +94,10 @@ is(scalar(@{[$all_output =~ m/OK 1/mg]}), 3 );
is(scalar(@{[$all_output =~ m/OK/mg]}), 8 );
is(scalar(@{[$all_output =~ m/ALL TESTS SUCCESSFUL\./mg]}), 1);
-$dist->remove;
-
{ # once-again
+$dist->revert;
+
$dist->add_file('t/foo/special.st', <<'---');
#!perl
use Test::More tests => 2;
@@ -114,7 +110,6 @@ use strict; use Simple;
ok 1;
---
$dist->regen;
-$dist->chdir_in;
my $mb = Module::Build->subclass(
code => q#
@@ -174,7 +169,6 @@ like($all_output, qr/^OK 2 - SECOND TEST IN ANOTHER_EXT/m);
is(scalar(@{[$all_output =~ m/(OK 1)/mg]}), 5 );
is(scalar(@{[$all_output =~ m/(OK)/mg]}), 13 );
-$dist->remove;
} # end once-again
# vim:ts=4:sw=4:et:sta
diff --git a/cpan/Module-Build/t/tilde.t b/cpan/Module-Build/t/tilde.t
index 5b39204171..692ade0c8a 100644
--- a/cpan/Module-Build/t/tilde.t
+++ b/cpan/Module-Build/t/tilde.t
@@ -4,10 +4,9 @@
use strict;
use lib 't/lib';
-use MBTest tests => 18;
+use MBTest tests => 16;
-use_ok 'Module::Build';
-ensure_blib('Module::Build');
+blib_load('Module::Build');
my $tmp = MBTest->tmpdir;
@@ -111,6 +110,3 @@ SKIP: {
like( run_sample( $p => "~$me/foo")->$p(), qr($expected)i );
}
-
-# cleanup
-$dist->remove;
diff --git a/cpan/Module-Build/t/use_tap_harness.t b/cpan/Module-Build/t/use_tap_harness.t
index d14cb052ba..f6e7e5073a 100644
--- a/cpan/Module-Build/t/use_tap_harness.t
+++ b/cpan/Module-Build/t/use_tap_harness.t
@@ -4,7 +4,7 @@ use strict;
use Test::More;
use lib 't/lib';
if (eval { require TAP::Harness } && TAP::Harness->VERSION >= 3) {
- plan tests => 8;
+ plan tests => 9;
} else {
plan skip_all => 'TAP::Harness 3+ not installed'
}
@@ -12,21 +12,24 @@ if (eval { require TAP::Harness } && TAP::Harness->VERSION >= 3) {
use MBTest;
use DistGen;
-use_ok 'Module::Build';
-ensure_blib('Module::Build');
+blib_load('Module::Build');
my $tmp = MBTest->tmpdir;
my $dist = DistGen->new( dir => $tmp );
$dist->regen;
-
$dist->chdir_in;
+
#########################
# Make sure that TAP::Harness properly does its thing.
-ok my $mb = Module::Build->new(
+$dist->change_build_pl(
module_name => $dist->name,
use_tap_harness => 1,
quiet => 1,
-), 'Construct build object with test_file_exts parameter';
+);
+$dist->regen;
+
+ok my $mb = $dist->new_from_context,
+ 'Construct build object with test_file_exts parameter';
$mb->add_to_cleanup('save_out');
# Use uc() so we don't confuse the current test output
@@ -40,12 +43,16 @@ like $out, qr/^ALL TESTS SUCCESSFUL/m, 'Should see test success message';
#########################
# Make sure that arguments are passed through to TAP::Harness.
-ok $mb = Module::Build->new(
+$dist->change_build_pl(
module_name => $dist->name,
use_tap_harness => 1,
tap_harness_args => { verbosity => 0 },
quiet => 1,
-), 'Construct build object with test_file_exts parameter';
+);
+$dist->regen;
+
+ok $mb = $dist->new_from_context,
+ 'Construct build object with test_file_exts parameter';
$mb->add_to_cleanup('save_out');
# Use uc() so we don't confuse the current test output
@@ -56,6 +63,32 @@ $out = uc(stdout_of(
unlike $out, qr/^OK 1/m, 'Should not see first test output';
like $out, qr/^ALL TESTS SUCCESSFUL/m, 'Should see test success message';
-$dist->remove;
+#--------------------------------------------------------------------------#
+# test that a failing test dies
+#--------------------------------------------------------------------------#
+
+$dist->change_build_pl(
+ module_name => $dist->name,
+ use_tap_harness => 1,
+ tap_harness_args => { verbosity => 1 },
+ quiet => 1,
+);
+$dist->change_file('t/basic.t',<<"---");
+use Test::More tests => 1;
+use strict;
+
+use $dist->{name};
+ok 0;
+---
+$dist->regen;
+
+ok $mb = $dist->new_from_context,
+ 'Construct build object after setting tests to fail';
+# Use uc() so we don't confuse the current test output
+$out = stdout_stderr_of( sub { $dist->run_build('test')} );
+ok( $?, "'Build test' had non-zero exit code" );
+like( $out, qr{Errors in testing\. Cannot continue\.},
+ "Saw emulated Test::Harness die() message"
+);
# vim:ts=4:sw=4:et:sta
diff --git a/cpan/Module-Build/t/versions.t b/cpan/Module-Build/t/versions.t
index 7f511e58f6..5eafbac297 100644
--- a/cpan/Module-Build/t/versions.t
+++ b/cpan/Module-Build/t/versions.t
@@ -2,10 +2,9 @@
use strict;
use lib 't/lib';
-use MBTest tests => 4;
+use MBTest tests => 2;
-use_ok 'Module::Build';
-ensure_blib('Module::Build');
+blib_load('Module::Build');
my $tmp = MBTest->tmpdir;
@@ -20,7 +19,3 @@ my $file = File::Spec->catfile( $dist->dirname, 'lib', @mod ) . '.pm';
is( Module::Build->version_from_file( $file ), '0.01', 'version_from_file' );
ok( Module::Build->compare_versions( '1.01_01', '>', '1.01' ), 'compare: 1.0_01 > 1.0' );
-
-
-# cleanup
-$dist->remove;
diff --git a/cpan/Module-Build/t/write_default_maniskip.t b/cpan/Module-Build/t/write_default_maniskip.t
index 084d81ed3e..40389f20dc 100644
--- a/cpan/Module-Build/t/write_default_maniskip.t
+++ b/cpan/Module-Build/t/write_default_maniskip.t
@@ -8,14 +8,14 @@ use MBTest 'no_plan';
use DistGen;
use Cwd;
-use_ok 'Module::Build';
-ensure_blib 'Module::Build';
+blib_load('Module::Build');
{
my $cwd = Cwd::cwd;
chdir MBTest->tmpdir();
my $build = Module::Build->new(
+ module_name => "Foo::Bar",
dist_name => "Foo-Bar",
dist_version => '1.23',
);
diff --git a/cpan/Module-Build/t/xs.t b/cpan/Module-Build/t/xs.t
index e3f1ed7dd1..6d167c8539 100644
--- a/cpan/Module-Build/t/xs.t
+++ b/cpan/Module-Build/t/xs.t
@@ -3,11 +3,12 @@
use strict;
use lib 't/lib';
use MBTest;
-use Module::Build;
use Config;
my $tmp;
+blib_load('Module::Build');
+
{
my ($have_c_compiler, $C_support_feature, $tmp_exec) = check_compiler();
@@ -20,24 +21,20 @@ my $tmp;
} elsif ( !$Config{usedl} ) {
plan skip_all => 'Perl not compiled for dynamic loading'
} else {
- plan tests => 23;
+ plan tests => 20;
}
require Cwd;
$tmp = MBTest->tmpdir( $tmp_exec ? undef : Cwd::cwd );
}
-ensure_blib('Module::Build');
#########################
use DistGen;
-my $dist = DistGen->new( dir => $tmp, xs => 1 );
-$dist->regen;
-
-$dist->chdir_in;
-my $mb = Module::Build->new_from_context;
+my $dist = DistGen->new( dir => $tmp, xs => 1 )->chdir_in->regen;
+my $mb = $dist->new_from_context;
eval {$mb->dispatch('clean')};
is $@, '';
@@ -83,7 +80,7 @@ is $@, '';
# We can't be verbose in the sub-test, because Test::Harness will
# think that the output is for the top-level test.
-eval {$mb->dispatch('test')};
+stdout_stderr_of( sub { eval {$mb->dispatch('test')} });
is $@, '';
eval {$mb->dispatch('clean')};
@@ -106,42 +103,31 @@ is $@, '';
# Make sure blib/ is gone after 'realclean'
ok ! -e 'blib';
-
-# cleanup
-$dist->remove;
-
-
########################################
# Try a XS distro with a deep namespace
-$dist = DistGen->new( name => 'Simple::With::Deep::Name',
- dir => $tmp, xs => 1 );
-$dist->regen;
-$dist->chdir_in;
-$mb = Module::Build->new_from_context;
-is $@, '';
+$dist->reset( name => 'Simple::With::Deep::Name', dir => $tmp, xs => 1 );
+$dist->chdir_in->regen;
-$mb->dispatch('build');
-is $@, '';
+$mb = $dist->new_from_context;
-$mb->dispatch('test');
+eval { $mb->dispatch('build') };
is $@, '';
-$mb->dispatch('realclean');
+stdout_stderr_of( sub { eval { $mb->dispatch('test') } } );
is $@, '';
-# cleanup
-$dist->remove;
-
+eval { $mb->dispatch('realclean') };
+is $@, '';
########################################
# Try a XS distro using a flat directory structure
# and a 'dist_name' instead of a 'module_name'
-$dist = DistGen->new( name => 'Dist-Name', dir => $tmp, xs => 1 );
+$dist->reset( name => 'Dist-Name', dir => $tmp, xs => 1 )->chdir_in;
$dist->remove_file('lib/Dist-Name.pm');
$dist->remove_file('lib/Dist-Name.xs');
@@ -211,20 +197,15 @@ ok( Simple::okay() eq 'ok' );
---
$dist->regen;
-$dist->chdir_in;
-
-$mb = Module::Build->new_from_context;
-is $@, '';
+$mb = $dist->new_from_context;
-$mb->dispatch('build');
+eval { $mb->dispatch('build') };
is $@, '';
-$mb->dispatch('test');
+stdout_of( sub { eval { $mb->dispatch('test') } } );
is $@, '';
-$mb->dispatch('realclean');
+eval { $mb->dispatch('realclean') };
is $@, '';
-# cleanup
-$dist->remove;