Upgrade to Module::Build 0.2808_01
Rafael Garcia-Suarez [Thu, 25 Oct 2007 09:46:55 +0000 (09:46 +0000)]
p4raw-id: //depot/perl@32192

53 files changed:
MANIFEST
lib/Module/Build.pm
lib/Module/Build/API.pod
lib/Module/Build/Authoring.pod
lib/Module/Build/Base.pm
lib/Module/Build/Changes
lib/Module/Build/Compat.pm
lib/Module/Build/Config.pm
lib/Module/Build/Cookbook.pm
lib/Module/Build/Dumper.pm [new file with mode: 0644]
lib/Module/Build/ModuleInfo.pm
lib/Module/Build/Notes.pm
lib/Module/Build/PPMMaker.pm
lib/Module/Build/Platform/Amiga.pm
lib/Module/Build/Platform/Default.pm
lib/Module/Build/Platform/EBCDIC.pm
lib/Module/Build/Platform/MPEiX.pm
lib/Module/Build/Platform/MacOS.pm
lib/Module/Build/Platform/RiscOS.pm
lib/Module/Build/Platform/Unix.pm
lib/Module/Build/Platform/VMS.pm
lib/Module/Build/Platform/VOS.pm
lib/Module/Build/Platform/Windows.pm
lib/Module/Build/Platform/aix.pm
lib/Module/Build/Platform/cygwin.pm
lib/Module/Build/Platform/darwin.pm
lib/Module/Build/Platform/os2.pm
lib/Module/Build/PodParser.pm
lib/Module/Build/Version.pm
lib/Module/Build/YAML.pm
lib/Module/Build/t/basic.t
lib/Module/Build/t/bundled/Tie/CPHash.pm
lib/Module/Build/t/compat.t
lib/Module/Build/t/destinations.t
lib/Module/Build/t/extend.t
lib/Module/Build/t/files.t
lib/Module/Build/t/help.t
lib/Module/Build/t/install.t
lib/Module/Build/t/lib/DistGen.pm
lib/Module/Build/t/lib/MBTest.pm
lib/Module/Build/t/manifypods.t
lib/Module/Build/t/metadata.t
lib/Module/Build/t/metadata2.t
lib/Module/Build/t/moduleinfo.t
lib/Module/Build/t/new_from_context.t
lib/Module/Build/t/notes.t
lib/Module/Build/t/ppm.t
lib/Module/Build/t/runthrough.t
lib/Module/Build/t/test_type.t
lib/Module/Build/t/test_types.t
lib/Module/Build/t/tilde.t
lib/Module/Build/t/versions.t
lib/Module/Build/t/xs.t

index e25143a..10743b2 100644 (file)
--- a/MANIFEST
+++ b/MANIFEST
@@ -2132,6 +2132,7 @@ lib/Module/Build/Compat.pm        Module::Build
 lib/Module/Build/ConfigData.pm Module::Build
 lib/Module/Build/Config.pm     Module::Build
 lib/Module/Build/Cookbook.pm   Module::Build
+lib/Module/Build/Dumper.pm     Module::Build
 lib/Module/Build/ModuleInfo.pm Module::Build
 lib/Module/Build/Notes.pm      Module::Build
 lib/Module/Build/Platform/aix.pm       Module::Build
index 7f4408b..6a53ad8 100644 (file)
@@ -227,10 +227,8 @@ C<Build test verbose=1>), in which case their values last only for the
 lifetime of that command.  Per-action command line parameters take
 precedence over parameters specified at C<perl Build.PL> time.
 
-The build process also relies heavily on the C<Config.pm> module, and
-all the key=value pairs in C<Config.pm> are available in
-
-C<< $self->{config} >>.  If the user wishes to override any of the
+The build process also relies heavily on the C<Config.pm> module.
+If the user wishes to override any of the
 values in C<Config.pm>, she may specify them like so:
 
   perl Build.PL --config cc=gcc --config ld=gcc
@@ -524,7 +522,7 @@ for a bug report.
 [version 0.28]
 
 This action is identical to the C<install> action.  In the future,
-though, if C<install> starts writing to the file 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.
 
index c7b8cbf..2ad6dc5 100644 (file)
@@ -23,7 +23,7 @@ stabilizes.
 
 This method returns a reasonable facsimile of the currently-executing
 C<Module::Build> object representing the current build.  You can use
-this object to query its C<notes()> method, inquire about installed
+this object to query its L</notes()> method, inquire about installed
 modules, and so on.  This is a great way to share information between
 different parts of your build process.  For instance, you can ask
 the user a question during C<perl Build.PL>, then use their answer
@@ -55,8 +55,8 @@ C<Module::Build> was invoked from.
 
 Creates a new Module::Build object.  Arguments to the new() method are
 listed below.  Most arguments are optional, but you must provide
-either the C<module_name> argument, or C<dist_name> and one of
-C<dist_version> or C<dist_version_from>.  In other words, you must
+either the L</module_name> argument, or L</dist_name> and one of
+L</dist_version> or L</dist_version_from>.  In other words, you must
 provide enough information to determine both a distribution name and
 version.
 
@@ -68,14 +68,15 @@ version.
 [version 0.19]
 
 An array reference of files to be cleaned up when the C<clean> action
-is performed.  See also the add_to_cleanup() method.
+is performed. See also the L<add_to_cleanup()|/"add_to_cleanup(@files)">
+method.
 
 =item auto_features
 
 [version 0.26]
 
 This parameter supports the setting of features (see
-L<feature($name)>) automatically based on a set of prerequisites.  For
+L</feature($name)>) automatically based on a set of prerequisites.  For
 instance, for a module that could optionally use either MySQL or
 PostgreSQL databases, you might use C<auto_features> like this:
 
@@ -101,7 +102,7 @@ if there are no failures, the feature will be enabled (set to C<1>).
 Otherwise the failures will be displayed to the user and the feature
 will be disabled (set to C<0>).
 
-See the documentation for L<requires> for the details of how
+See the documentation for L</requires> for the details of how
 requirements can be specified.
 
 =item autosplit
@@ -109,9 +110,9 @@ requirements can be specified.
 [version 0.04]
 
 An optional C<autosplit> argument specifies a file which should be run
-through the C<Autosplit::autosplit()> function.  If multiple files
-should be split, the argument may be given as an array of the files to
-split.
+through the L<AutoSplit::autosplit()|AutoSplit/autosplit> function.
+If multiple files should be split, the argument may be given as an
+array of the files to split.
 
 In general I don't consider autosplitting a great idea, because it's
 not always clear that autosplitting achieves its intended performance
@@ -123,13 +124,13 @@ startup.
 
 [version 0.28]
 
-The Module::Build class or subclass to use in the build
-script.  Defaults to "Module::Build" or the class name passed to or
-created by a call to C<subclass()>.  This property is useful if you're
+The Module::Build class or subclass to use in the build script.
+Defaults to "Module::Build" or the class name passed to or created by
+a call to L</subclass()>.  This property is useful if you're
 writing a custom Module::Build subclass and have a bootstrapping
 problem--that is, your subclass requires modules that may not be
 installed when C<perl Build.PL> is executed, but you've listed in
-C<build_requires> so that they should be available when C<./Build> is
+L</build_requires> so that they should be available when C<./Build> is
 executed.
 
 =item build_requires
@@ -188,7 +189,7 @@ for the details of how requirements can be specified.
 This parameter lets you use Module::Build::Compat during the
 C<distdir> (or C<dist>) action to automatically create a Makefile.PL
 for compatibility with ExtUtils::MakeMaker.  The parameter's value
-should be one of the styles named in the Module::Build::Compat
+should be one of the styles named in the L<Module::Build::Compat>
 documentation.
 
 =item create_readme
@@ -243,8 +244,8 @@ to a module name, so C<dist_name> can be set independently.
 
 [version 0.11]
 
-Specifies a version number for the distribution.  See C<module_name>
-or C<dist_version_from> for ways to have this set automatically from a
+Specifies a version number for the distribution.  See L</module_name>
+or L</dist_version_from> for ways to have this set automatically from a
 C<$VERSION> variable in a module.  One way or another, a version
 number needs to be set.
 
@@ -253,11 +254,11 @@ number needs to be set.
 [version 0.11]
 
 Specifies a file to look for the distribution version in.  Most
-authors won't need to set this directly, they can use C<module_name>
+authors won't need to set this directly, they can use L</module_name>
 to set it to a reasonable default.
 
 The version is extracted from the specified file according to the same
-rules as C<ExtUtils::MakeMaker> and C<CPAN.pm>.  It involves finding
+rules as L<ExtUtils::MakeMaker> and C<CPAN.pm>.  It involves finding
 the first line that matches the regular expression
 
    /([\$*])(([\w\:\']*)\bVERSION)\b.*\=/
@@ -280,9 +281,9 @@ omitted, the F<META.yml> spec says that installation tools should
 treat it as 1 (true), because this is a safer way to behave.
 
 Currently C<Module::Build> doesn't actually do anything with this flag
-- it's up to higher-level tools like C<CPAN.pm> to do
-something useful with it.  It can potentially bring lots of security,
-packaging, and convenience improvements.
+- it's up to higher-level tools like C<CPAN.pm> to do something useful
+with it.  It can potentially bring lots of security, packaging, and
+convenience improvements.
 
 =item extra_compiler_flags
 
@@ -317,7 +318,7 @@ To link your XS code against glib you might write something like:
 
 You can pass arbitrary command line options to F<Build.PL> or
 F<Build>, and they will be stored in the Module::Build object and can
-be accessed via the C<args()> method.  However, sometimes you want
+be accessed via the L</args()> method.  However, sometimes you want
 more flexibility out of your argument processing than this allows.  In
 such cases, use the C<get_options> parameter to pass in a hash
 reference of argument specifications, and the list of arguments to
@@ -428,50 +429,55 @@ Specifies the licensing terms of your distribution.  Valid options include:
 =item apache
 
 The distribution is licensed under the Apache Software License
-(http://opensource.org/licenses/apachepl.php).
+(L<http://opensource.org/licenses/apachepl.php>).
 
 =item artistic
 
 The distribution is licensed under the Artistic License, as specified
-by the F<Artistic> file in the standard perl distribution.
+by the F<Artistic> file in the standard Perl distribution.
+
+=item artistic_2
+
+The distribution is licensed under the Artistic 2.0 License
+(L<http://opensource.org/licenses/artistic-license-2.0.php>.)
 
 =item bsd
 
 The distribution is licensed under the BSD License
-(http://www.opensource.org/licenses/bsd-license.php).
+(L<http://www.opensource.org/licenses/bsd-license.php>).
 
 =item gpl
 
-The distribution is licensed under the terms of the Gnu General
-Public License (http://www.opensource.org/licenses/gpl-license.php).
+The distribution is licensed under the terms of the GNU General
+Public License (L<http://www.opensource.org/licenses/gpl-license.php>).
 
 =item lgpl
 
-The distribution is licensed under the terms of the Gnu Lesser
+The distribution is licensed under the terms of the GNU Lesser
 General Public License
-(http://www.opensource.org/licenses/lgpl-license.php).
+(L<http://www.opensource.org/licenses/lgpl-license.php>).
 
 =item mit
 
 The distribution is licensed under the MIT License
-(http://opensource.org/licenses/mit-license.php).
+(L<http://opensource.org/licenses/mit-license.php>).
 
 =item mozilla
 
 The distribution is licensed under the Mozilla Public
-License.  (http://opensource.org/licenses/mozilla1.0.php or
-http://opensource.org/licenses/mozilla1.1.php)
+License.  (L<http://opensource.org/licenses/mozilla1.0.php> or
+L<http://opensource.org/licenses/mozilla1.1.php>)
 
 =item open_source
 
 The distribution is licensed under some other Open Source
 Initiative-approved license listed at
-http://www.opensource.org/licenses/ .
+L<http://www.opensource.org/licenses/>.
 
 =item perl
 
 The distribution may be copied and redistributed under the same terms
-as perl itself (this is by far the most common licensing option for
+as Perl itself (this is by far the most common licensing option for
 modules on CPAN).  This is a dual license, in which the user may
 choose between either the GPL or the Artistic license.
 
@@ -515,6 +521,8 @@ A hash of key/value pairs that should be added to the F<META.yml> file
 during the C<distmeta> action.  Any existing entries with the same
 names will be overridden.
 
+See the L</"MODULE METADATA"> section for details.
+
 =item meta_merge
 
 [version 0.28]
@@ -529,6 +537,8 @@ completely blow away the existing hash or array value, but
 C<meta_merge> will merge the supplied data into the existing hash or
 array value.
 
+See the L</"MODULE METADATA"> section for details.
+
 =item module_name
 
 [version 0.03]
@@ -618,7 +628,7 @@ files in your distribution.
 
 [version 0.08]
 
-This is just like the C<requires> argument, except that modules listed
+This is just like the L</requires> argument, except that modules listed
 in this section aren't essential, just a good idea.  We'll just print
 a friendly warning if one of these modules aren't found, but we'll
 continue running.
@@ -651,7 +661,7 @@ that the current module depends on.
 
 One note: currently C<Module::Build> doesn't actually I<require> the
 user to have dependencies installed, it just strongly urges.  In the
-future we may require it.  There's also a C<recommends> section for
+future we may require it.  There's also a L</recommends> section for
 things that aren't absolutely required.
 
 Automated tools like CPAN.pm should refuse to install a module if one
@@ -672,7 +682,7 @@ for the details of how requirements can be specified.
 [version 0.18]
 
 An optional parameter specifying a set of files that should be
-installed as executable perl scripts when the module is installed.
+installed as executable Perl scripts when the module is installed.
 May be given as an array reference of the files, or as a hash
 reference whose keys are the files (and whose values will currently be
 ignored).
@@ -689,7 +699,7 @@ though it will continue to exist for several version releases.
 
 [version 0.16]
 
-If a true value is specified for this parameter, C<Module::Signature>
+If a true value is specified for this parameter, L<Module::Signature>
 will be used (via the 'distsign' action) to create a SIGNATURE file
 for your distribution during the 'distdir' action, and to add the
 SIGNATURE file to the MANIFEST (therefore, don't add it yourself).
@@ -824,7 +834,7 @@ first argument.
 
 [version 0.28]
 
-Invokes the C<AutoSplit> module on the C<$from> file, sending the
+Invokes the L<AutoSplit> module on the C<$from> file, sending the
 output to the C<lib/auto> directory inside C<$to>.  C<$to> is
 typically the C<blib/> directory.
 
@@ -852,7 +862,7 @@ prerequisites that were passed to the C<new()> method.
 This method returns a hash reference indicating whether a version
 dependency on a certain module is satisfied.  The C<$module> argument
 is given as a string like C<"Data::Dumper"> or C<"perl">, and the
-C<$version> argument can take any of the forms described in L<requires>
+C<$version> argument can take any of the forms described in L</requires>
 above.  This allows very fine-grained version checking.
 
 The returned hash reference has the following structure:
@@ -873,16 +883,16 @@ for the case when C<$module> isn't installed at all.
 
 This method may be called either as an object method
 (C<< $build->check_installed_status($module, $version) >>)
-or as a class method 
+or as a class method
 (C<< Module::Build->check_installed_status($module, $version) >>).
 
 =item check_installed_version($module, $version)
 
 [version 0.05]
 
-Like C<check_installed_status()>, but simply returns true or false
-depending on whether module C<$module> satisfies the dependency
-C<$version>.
+Like L<check_installed_status()|/"check_installed_status($module, $version)">,
+but simply returns true or false depending on whether module
+C<$module> satisfies the dependency C<$version>.
 
 If the check succeeds, the return value is the actual version of
 C<$module> installed on the system.  This allows you to do the
@@ -931,7 +941,7 @@ out to C<version.pm>.
 
 With a single argument C<$key>, returns the value associated with that
 key in the C<Config.pm> hash, including any changes the author or user
-has specified.  
+has specified.
 
 With C<$key> and C<$value> arguments, sets the value for future
 callers of C<config($key)>.
@@ -948,7 +958,7 @@ resource hog and violates encapsulation.
 
 With a single argument, returns the value of the configuration
 variable C<$name>.  With two arguments, sets the given configuration
-variable to the given value.  The value may be any perl scalar that's
+variable to the given value.  The value may be any Perl scalar that's
 serializable with C<Data::Dumper>.  For instance, if you write a
 module that can use a MySQL or PostgreSQL back-end, you might create
 configuration variables called C<mysql_connect> and
@@ -960,7 +970,7 @@ will be available for querying during the build/test process and after
 installation via the generated C<...::ConfigData> module, as
 C<< ...::ConfigData->config($name) >>.
 
-The C<feature()> and C<config_data()> methods represent
+The L<feature()|/"feature($name)"> and C<config_data()> methods represent
 Module::Build's main support for configuration of installed modules.
 See also L<Module::Build::Authoring/"SAVING CONFIGURATION INFORMATION">.
 
@@ -1016,13 +1026,13 @@ when the C<realclean> action is performed.
 Among the files created in C<_build/> is a F<_build/prereqs> file
 containing the set of prerequisites for this distribution, as a hash
 of hashes.  This file may be C<eval()>-ed to obtain the authoritative
-set of prereqs, which might be different from the contents of META.yml
-(because F<Build.PL> might have set them dynamically).  But fancy
-developers take heed: do not put any fancy custom runtime code in the
-F<_build/prereqs> file, leave it as a static declaration containing
-only strings and numbers.  Similarly, do not alter the structure of
-the internal C<< $self->{properties}{requires} >> (etc.) data members,
-because that's where this data comes from.
+set of prereqs, which might be different from the contents of
+F<META.yml> (because F<Build.PL> might have set them dynamically).
+But fancy developers take heed: do not put any fancy custom runtime
+code in the F<_build/prereqs> file, leave it as a static declaration
+containing only strings and numbers.  Similarly, do not alter the
+structure of the internal C<< $self->{properties}{requires} >> (etc.)
+data members, because that's where this data comes from.
 
 =item current_action()
 
@@ -1037,7 +1047,7 @@ return "code" while that dependency is being executed.  Once that
 action has completed, current_action() will again return "test".
 
 If you need to know the name of the original action invoked by the
-user, see L<invoked_action()> below.
+user, see L</invoked_action()> below.
 
 =item depends_on(@actions)
 
@@ -1056,9 +1066,10 @@ C<invoke_actions_unless_already_invoked()> or something, but for
 better or worse (perhaps better!) we were still thinking in
 C<make>-like dependency terms when we created this method.
 
-See also C<dispatch()>.  The main distinction between the two is that
-C<depends_on()> is meant to call an action from inside another action,
-whereas C<dispatch()> is meant to set the very top action in motion.
+See also L<dispatch()|/"dispatch($action, %args)">.  The main
+distinction between the two is that C<depends_on()> is meant to call
+an action from inside another action, whereas C<dispatch()> is meant
+to set the very top action in motion.
 
 =item dir_contains($first_dir, $second_dir)
 
@@ -1086,9 +1097,10 @@ This method is intended to be used to programmatically invoke build
 actions, e.g. by applications controlling Module::Build-based builds
 rather than by subclasses.
 
-See also C<depends_on()>.  The main distinction between the two is that
-C<depends_on()> is meant to call an action from inside another action,
-whereas C<dispatch()> is meant to set the very top action in motion.
+See also L<depends_on()|/"depends_on(@actions)">.  The main
+distinction between the two is that C<depends_on()> is meant to call
+an action from inside another action, whereas C<dispatch()> is meant
+to set the very top action in motion.
 
 =item dist_dir()
 
@@ -1147,7 +1159,7 @@ installed and configured.
 
 Features set in this way using the Module::Build object will be
 available for querying during the build/test process and after
-installation via the generated C<...::ConfigData> module, as 
+installation via the generated C<...::ConfigData> module, as
 C<< ...::ConfigData->feature($name) >>.
 
 The C<feature()> and C<config_data()> methods represent
@@ -1193,7 +1205,7 @@ Assigning the value C<undef> to an element causes it to be removed.
 [version 0.28]
 
 Returns the directory in which items of type C<$type> (e.g. C<lib>,
-C<arch>, C<bin>, or anything else returned by the C<install_types()>
+C<arch>, C<bin>, or anything else returned by the L</install_types()>
 method) will be installed during the C<install> action.  Any settings
 for C<install_path>, C<install_base>, and C<prefix> are taken into
 account when determining the return value.
@@ -1242,11 +1254,12 @@ exist.
 
 This is the name of the original action invoked by the user.  This
 value is set when the user invokes F<Build.PL>, the F<Build> script,
-or programatically through the L<dispatch()> method.  It does not
-change as sub-actions are executed as dependencies are evaluated.
+or programatically through the L<dispatch()|/"dispatch($action, %args)">
+method.  It does not change as sub-actions are executed as
+dependencies are evaluated.
 
 To get the name of the currently executing dependency, see
-L<current_action()> above.
+L</current_action()> above.
 
 =item notes()
 
@@ -1474,7 +1487,7 @@ Examples:
 
  # All the *.pm files in lib/
  $m->rscan_dir('lib', qr/\.pm$/)
+
  # All the files in blib/ that aren't *.html files
  $m->rscan_dir('blib', sub {-f $_ and not /\.html$/});
 
@@ -1589,6 +1602,8 @@ accessor methods for the following properties:
 
 =item config_dir()
 
+=item configure_requires()
+
 =item conflicts()
 
 =item create_makefile_pl()
@@ -1666,6 +1681,35 @@ accessor methods for the following properties:
 =back
 
 
+=head1 MODULE METADATA
+
+If you would like to add other useful metadata, C<Module::Build>
+supports this with the C<meta_add> and C<meta_merge> arguments to
+L</new>. The authoritative list of supported metadata can be found at
+L<http://module-build.sourceforge.net/META-spec-current.html>, but for
+convenience - here are a few of the more useful ones:
+
+=over 4
+
+=item keywords
+
+For describing the distribution using keyword (or "tags") in order to
+make CPAN.org indexing and search more efficient and useful.
+
+See L<http://module-build.sourceforge.net/META-spec-current.html#keywords>.
+
+=item resources
+
+A list of additional resources available for users of the
+distribution. This can include links to a homepage on the web, a
+bugtracker, the repository location, a even subscription page for the
+distribution mailing list.
+
+See L<http://module-build.sourceforge.net/META-spec-current.html#resources>.
+
+=back
+
+
 =head1 AUTHOR
 
 Ken Williams <kwilliams@cpan.org>
index b0b7f37..871effd 100644 (file)
@@ -141,20 +141,51 @@ method.
 
 =head1 PREREQUISITES
 
-There are three basic types of prerequisites that can be defined: 1)
-"requires" - are versions of modules that are required for certain
-functionality to be available; 2) "recommends" - are versions of
-modules that are recommended to provide enhanced functionality; and 3)
-"conflicts" - are versions of modules that conflict with, and that can
-cause problems with the distribution.
+=head2 Types of prerequisites
 
-Each of the three types of prerequisites listed above can be applied
-to different aspects of the Build process.  For the module distribution
-itself you simply define "requires", "recommends", or "conflicts".  The
-types can also apply to other aspects of the Build process.  Currently,
-only "build_requires" is defined which is used for modules which are
-required during the Build process.
+To specify what versions of other modules are used by this
+distribution, several types of prerequisites can be defined with the
+following parameters:
 
+=over 3
+
+=item configure_requires
+
+Items that must be installed I<before> configuring this distribution
+(i.e. before running the F<Build.PL> script).  This might be a
+specific minimum version of C<Module::Build> or any other module the
+F<Build.PL> needs in order to do its stuff.  Clients like C<CPAN.pm>
+or C<CPANPLUS> will be expected to pick C<configure_requires> out of the
+F<META.yml> file and install these items before running the
+C<Build.PL>.
+
+*TODO* auto-add M::B?  In what circumstances?
+
+=item build_requires
+
+Items that are necessary for building and testing this distribution,
+but aren't necessary after installation.  This can help users who only
+want to install these items temporarily.  It also helps reduce the
+size of the CPAN dependency graph if everything isn't smooshed into
+C<requires>.
+
+=item requires
+
+Items that are necessary for basic functioning.
+
+=item recommends
+
+Items that are recommended for enhanced functionality, but there are
+ways to use this distribution without having them installed.  You
+might also think of this as "can use" or "is aware of" or "changes
+behavior in the presence of".
+
+=item conflicts
+
+Items that can cause problems with this distribution when installed.
+This is pretty rare.
+
+=back
 
 =head2 Format of prerequisites
 
@@ -168,7 +199,7 @@ the module names and the values are version specifiers:
                perl => '5.6.0'
               },
 
-These four version specifiers have different effects.  The value
+The above four version specifiers have different effects.  The value
 C<'2.4'> means that B<at least> version 2.4 of C<Foo::Module> must be
 installed.  The value C<0> means that B<any> version of C<Bar::Module>
 is acceptable, even if C<Bar::Module> doesn't define a version.  The
@@ -182,6 +213,11 @@ interpreter that are supported by your module.  The same version
 dependency-checking semantics are available, except that we also
 understand perl's new double-dotted version numbers.
 
+=head2 XS Extensions
+
+Modules which need to compile XS code should list C<ExtUtils::CBuilder>
+as a C<build_requires> element.
+
 
 =head1 SAVING CONFIGURATION INFORMATION
 
@@ -210,8 +246,8 @@ library (thus the C<h> part) into perl extensions (thus the C<xs>
 part).
 
 These days, C<h2xs> has largely been superseded by modules like
-C<ExtUtils::ModuleMaker>, C<Module::Starter>, and C<Module::Maker>.
-They have varying degrees of support for C<Module::Build>.
+C<ExtUtils::ModuleMaker>, and C<Module::Starter>.  They have varying
+degrees of support for C<Module::Build>.
 
 
 =head1 AUTOMATION
index 58d7539..3090084 100644 (file)
@@ -1,17 +1,19 @@
 package Module::Build::Base;
 
 use strict;
+use vars qw($VERSION);
+$VERSION = '0.2808_01';
+$VERSION = eval $VERSION;
 BEGIN { require 5.00503 }
 
 use Carp;
-use Config;
 use File::Copy ();
 use File::Find ();
 use File::Path ();
 use File::Basename ();
 use File::Spec 0.82 ();
 use File::Compare ();
-use Data::Dumper ();
+use Module::Build::Dumper ();
 use IO::File ();
 use Text::ParseWords ();
 
@@ -30,13 +32,13 @@ sub new {
   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->dist_name;
-  $self->dist_version;
-
   $self->check_manifest;
   $self->check_prereq;
   $self->check_autofeatures;
 
+  $self->dist_name;
+  $self->dist_version;
+
   $self->_set_install_paths;
   $self->_find_nested_builds;
 
@@ -384,6 +386,17 @@ sub _perl_is_same {
   return $self->_backticks(@cmd) eq Config->myconfig;
 }
 
+# cache _discover_perl_interpreter() results
+{
+  my $known_perl;
+  sub find_perl_interpreter {
+    my $self = shift;
+
+    return $known_perl if defined($known_perl);
+    return $known_perl = $self->_discover_perl_interpreter;
+  }
+}
+
 # Returns the absolute path of the perl interperter used to invoke
 # this process. The path is derived from $^X or $Config{perlpath}. On
 # some platforms $^X contains the complete absolute path of the
@@ -393,8 +406,8 @@ sub _perl_is_same {
 # executable extension on platforms that use one. It's a fatal error
 # if the interpreter can't be found because it can result in undefined
 # behavior by routines that depend on it (generating errors or
-# invoking the wrong perl.
-sub find_perl_interpreter {
+# invoking the wrong perl.)
+sub _discover_perl_interpreter {
   my $proto = shift;
   my $c     = ref($proto) ? $proto->{config} : 'Module::Build::Config';
 
@@ -431,7 +444,7 @@ sub find_perl_interpreter {
 
   } else {
 
-    # Try 3.B, First look in $Config{perlpath}, then search the users
+    # Try 3.B, First look in $Config{perlpath}, then search the user's
     # PATH. We do not want to do either if we are running from an
     # uninstalled perl in a perl source tree.
 
@@ -447,7 +460,7 @@ sub find_perl_interpreter {
   my $exe = $c->get('exe_ext');
   foreach my $thisperl ( @potential_perls ) {
 
-    if (defined $exe and $proto->os_type ne 'VMS') {
+    if (defined $exe) {
       $thisperl .= $exe unless $thisperl =~ m/$exe$/i;
     }
 
@@ -576,7 +589,7 @@ sub features     {
 
   return wantarray ? %features : \%features;
 }
-BEGIN { *feature = \&features }
+BEGIN { *feature = \&features } # Alias
 
 sub _mb_feature {
   my $self = shift;
@@ -782,6 +795,7 @@ __PACKAGE__->add_property($_ => {}) for qw(
   meta_merge
   original_prefix
   prefix_relpaths
+  configure_requires
 );
 
 __PACKAGE__->add_property($_) for qw(
@@ -951,7 +965,7 @@ sub dist_version {
 
   die ("Can't determine distribution version, must supply either 'dist_version',\n".
        "'dist_version_from', or 'module_name' parameter")
-    unless $p->{dist_version};
+    unless defined $p->{dist_version};
 
   return $p->{dist_version};
 }
@@ -1026,8 +1040,12 @@ sub _write_data {
   
   my $file = $self->config_file($filename);
   my $fh = IO::File->new("> $file") or die "Can't create '$file': $!";
-  local $Data::Dumper::Terse = 1;
-  print $fh ref($data) ? Data::Dumper::Dumper($data) : $data;
+  unless (ref($data)) {  # e.g. magicnum
+    print $fh $data;
+    return;
+  }
+
+  print {$fh} Module::Build::Dumper->_data_dump($data);
 }
 
 sub write_config {
@@ -1186,6 +1204,7 @@ sub perl_version {
 
 sub perl_version_to_float {
   my ($self, $version) = @_;
+  return $version if grep( /\./, $version ) < 2;
   $version =~ s/\./../;
   $version =~ s/\.(\d+)/sprintf '%03d', $1/eg;
   return $version;
@@ -1219,7 +1238,7 @@ sub check_installed_status {
     }
     
     $status{have} = $pm_info->version();
-    if ($spec and !$status{have}) {
+    if ($spec and !defined($status{have})) {
       @status{ qw(have message) } = (undef, "Couldn't find a \$VERSION in prerequisite $modname");
       return \%status;
     }
@@ -1335,7 +1354,7 @@ sub print_build_script {
   my $case_tolerant = 0+(File::Spec->can('case_tolerant')
                         && File::Spec->case_tolerant);
   $q{base_dir} = uc $q{base_dir} if $case_tolerant;
-  $q{base_dir} = Win32::GetShortPathName($q{base_dir}) if $^O eq 'MSWin32';
+  $q{base_dir} = Win32::GetShortPathName($q{base_dir}) if $self->is_windowsish;
 
   $q{magic_numfile} = $self->config_file('magicnum');
 
@@ -1677,14 +1696,8 @@ sub read_args {
   return \%args, $action;
 }
 
-
-# (bash shell won't expand tildes mid-word: "--foo=~/thing")
-# TODO: handle ~user/foo
-sub _detildefy {
-    my ($self, $arg) = @_;
-
-    return $arg =~ /^~/ ? (glob $arg)[0] : $arg;
-}
+# Default: do nothing.  Overridden for Unix & Windows.
+sub _detildefy {}
 
 
 # merge Module::Build argument lists that have already been parsed
@@ -1980,7 +1993,8 @@ sub prereq_report {
       my $vspace = q{ } x ($ver_len - length $mod->{need});
       my $f = $mod->{ok} ? ' ' : '!';
       $output .=
-        "  $f $mod->{name} $space     $mod->{need}  $vspace   $mod->{have}\n";
+        "  $f $mod->{name} $space     $mod->{need}  $vspace   ".
+        (defined($mod->{have}) ? $mod->{have} : "")."\n";
     }
   }
   return $output;
@@ -2259,7 +2273,7 @@ sub process_PL_files {
   
   while (my ($file, $to) = each %$files) {
     unless ($self->up_to_date( $file, $to )) {
-      $self->run_perl_script($file, [], [@$to]);
+      $self->run_perl_script($file, [], [@$to]) or die "$file failed";
       $self->add_to_cleanup(@$to);
     }
   }
@@ -2865,7 +2879,7 @@ sub ACTION_ppmdist {
        File::Spec->abs2rel( File::Spec->rel2abs( $file ),
                             File::Spec->rel2abs( $dir  ) );
       my $to_file  =
-       File::Spec->catfile( $ppm, 'blib',
+       File::Spec->catdir( $ppm, 'blib',
                            exists( $types{$type} ) ? $types{$type} : $type,
                            $rel_file );
       $self->copy_if_modified( from => $file, to => $to_file );
@@ -2879,10 +2893,8 @@ sub ACTION_ppmdist {
 
   # create a tarball;
   # the directory tar'ed must be blib so we need to do a chdir first
-  my $start_wd = $self->cwd;
-  chdir( $ppm ) or die "Can't chdir to $ppm";
-  $self->make_tarball( 'blib', File::Spec->catfile( $start_wd, $ppm ) );
-  chdir( $start_wd ) or die "Can't chdir to $start_wd";
+  my $target = File::Spec->catfile( File::Spec->updir, $ppm );
+  $self->_do_in_dir( $ppm, sub { $self->make_tarball( 'blib', $target ) } );
 
   $self->depends_on( 'ppd' );
 
@@ -2979,13 +2991,17 @@ sub _sign_dir {
     $self->_add_to_manifest($manifest, "SIGNATURE    Added here by Module::Build");
   }
   
-  # We protect the signing with an eval{} to make sure we get back to
-  # the right directory after a signature failure.  Would be nice if
-  # Module::Signature took a directory argument.
+  # Would be nice if Module::Signature took a directory argument.
   
+  $self->_do_in_dir($dir, sub {local $Module::Signature::Quiet = 1; Module::Signature::sign()});
+}
+
+sub _do_in_dir {
+  my ($self, $dir, $do) = @_;
+
   my $start_dir = $self->cwd;
   chdir $dir or die "Can't chdir() to $dir: $!";
-  eval {local $Module::Signature::Quiet = 1; Module::Signature::sign()};
+  eval {$do->()};
   my @err = $@ ? ($@) : ();
   chdir $start_dir or push @err, "Can't chdir() back to $start_dir: $!";
   die join "\n", @err if @err;
@@ -3124,18 +3140,18 @@ sub ACTION_disttest {
 
   $self->depends_on('distdir');
 
-  my $start_dir = $self->cwd;
-  my $dist_dir = $self->dist_dir;
-  chdir $dist_dir or die "Cannot chdir to $dist_dir: $!";
-  # XXX could be different names for scripts
+  $self->_do_in_dir
+    ( $self->dist_dir,
+      sub {
+       # XXX could be different names for scripts
 
-  $self->run_perl_script('Build.PL') # XXX Should this be run w/ --nouse-rcfile
-      or die "Error executing 'Build.PL' in dist directory: $!";
-  $self->run_perl_script('Build')
-      or die "Error executing 'Build' in dist directory: $!";
-  $self->run_perl_script('Build', [], ['test'])
-      or die "Error executing 'Build test' in dist directory";
-  chdir $start_dir;
+       $self->run_perl_script('Build.PL') # XXX Should this be run w/ --nouse-rcfile
+         or die "Error executing 'Build.PL' in dist directory: $!";
+       $self->run_perl_script('Build')
+         or die "Error executing 'Build' in dist directory: $!";
+       $self->run_perl_script('Build', [], ['test'])
+         or die "Error executing 'Build test' in dist directory";
+      });
 }
 
 sub _write_default_maniskip {
@@ -3256,27 +3272,26 @@ sub script_files {
     return $_ = {$_ => 1};
   }
   
-  return $_ = { map {$_,1} $self->_files_in( File::Spec->catdir( $self->base_dir, 'bin' ) ) };
+  return $_ = { map {$_,1} $self->_files_in('bin') };
 }
 BEGIN { *scripts = \&script_files; }
 
 {
-  my %licenses =
-    (
-     perl => 'http://dev.perl.org/licenses/',
-     gpl => 'http://www.opensource.org/licenses/gpl-license.php',
-     apache => 'http://apache.org/licenses/LICENSE-2.0',
-     artistic => 'http://opensource.org/licenses/artistic-license.php',
-     lgpl => 'http://opensource.org/licenses/artistic-license.php',
-     bsd => 'http://www.opensource.org/licenses/bsd-license.php',
-     gpl => 'http://www.opensource.org/licenses/gpl-license.php',
-     mit => 'http://opensource.org/licenses/mit-license.php',
-     mozilla => 'http://opensource.org/licenses/mozilla1.1.php',
-     open_source => undef,
-     unrestricted => undef,
-     restrictive => undef,
-     unknown => undef,
-    );
+  my %licenses = (
+    perl         => 'http://dev.perl.org/licenses/',
+    apache       => 'http://apache.org/licenses/LICENSE-2.0',
+    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',
+    bsd          => 'http://opensource.org/licenses/bsd-license.php',
+    gpl          => 'http://opensource.org/licenses/gpl-license.php',
+    mit          => 'http://opensource.org/licenses/mit-license.php',
+    mozilla      => 'http://opensource.org/licenses/mozilla1.1.php',
+    open_source  => undef,
+    unrestricted => undef,
+    restrictive  => undef,
+    unknown      => undef,
+  );
   sub valid_licenses {
     return \%licenses;
   }
@@ -3382,7 +3397,16 @@ sub prepare_metadata {
     $node->{resources}{license} = $url;
   }
 
-  foreach ( @{$self->prereq_action_types} ) {
+  if (exists $p->{configure_requires}) {
+    foreach my $spec (keys %{$p->{configure_requires}}) {
+      warn ("Warning: $spec is listed in 'configure_requires', but ".
+           "it is not found in any of the other prereq fields.\n")
+       unless grep exists $p->{$_}{$spec}, 
+              grep !/conflicts$/, @{$self->prereq_action_types};
+    }
+  }
+
+  foreach ( 'configure_requires', @{$self->prereq_action_types} ) {
     if (exists $p->{$_} and keys %{ $p->{$_} }) {
       $add_node->($_, $p->{$_});
     }
index 14407d4..fd84408 100644 (file)
@@ -1,5 +1,152 @@
 Revision history for Perl extension Module::Build.
 
+ - All .pm files in the Module-Build distribution (except for
+   M::B::Version.pm, which is kind of tied to version.pm) now have the
+   same $VERSION number explicitly specified.
+
+ - When checking prerequisites, the required version of perl is now
+   checked before we start finding the $VERSION declaration of the
+   distribution, which results in much more intuitive error messages
+   e.g. if the author is using 5.6-isms in their declaration but the
+   user doesn't have 5.6. [Slaven Rezic]
+
+ - Added 'artistic_2' license, corrected 'lgpl' license url (bug #29783)
+   [David Thomas]
+
+ - VMS find_perl_interpreter() is just $^X (bug #29810) [Craig A. Berry]
+
+ - Some large VMS fixes, mostly having to do with the non-case-
+   preserving nature of most VMS filesystems, but also correcting for
+   illegal characters in VMS file specs. [John E. Malmberg and Craig
+   A. Berry]
+
+ - Fixed the _detildefy() method on VMS. [John E. Malmberg and Craig
+   A. Berry]
+
+ - We now use a much more reliable method when Data::Dumper-ing saved
+   state data. [Yves]
+
+ - When a module had 0.000 as its version, a few places in the code
+   thought the module had no version at all.  This is now
+   fixed. [Andrew "Zefram" Main]
+
+ - When finding the default set of script_files, we now compute them
+   as relative paths, not absolute. [Spotted by Curtis "Ovid" Poe]
+
+ - Got rid of a call to eliminate_macros, which isn't needed in
+   Module::Build since there is no external make utility involved.
+   Override expand_test_dir to make up for the fact that the
+   home-grown glob() returns absolute, not relative, paths. [Craig
+   A. Berry]
+
+ - Fixed a catdir() that needed to be catfile() in the .packlist
+   creation code. [John E. Malmberg]
+
+ - If a *.PL file ended abnormally during the build, processing should
+   have stopped, but it didn't.  Fixed. [Matthew Cast and David
+   Golden]
+
+ - 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 
+   STDOUT and STDERR [David Golden]
+
+ - Fixed bug in perl_version_to_float when version is already a float
+   [David Golden]
+
+ - Removed a mention of $build->{config} from the documentation, the
+   official interface to Config.pm settings is now via the
+   $build->config() and has been for some time. [Suggested by Michael
+   Schwern]
+
+ - Tweaked some text in the Cookbook to bring it into the modern age,
+   and added a recipe for accessing Config.pm settings. [Ibid]
+
+ - Lots of POD link/readability improvements to the Module::Build::API
+   documentation [Salve J. Nilsen]
+
+ - Added configure_requires as a new type of prereq.  [Suggested by Adam
+   Kennedy]
+
+ - Patch 31156 from bleadperl: some filename dot and extension help
+   for Module::Build on VMS. [Craig Berry]
+
+ - Reworked the _detildefy() method so it doesn't depend on glob()
+   anymore.  This gets rid of a problem with spaces or other special
+   shell characters in things like 'prefix' or 'install_path'
+   entries. [Prodding by Eric Wilhelm]
+
+ - Added midnightbsd to the list of Unix-like OSes we know about
+   [Rafael Garcia-Suarez]
+
+0.2808 - Sat Apr 28 12:59:43 2007
+
+ - Added is_vmsish(), is_windowsish(), and is_unixish() boolean
+   convenience functions.  Fixes some test failures on platforms where
+   $^O is set to a value we don't know about (like 'gnu').
+
+ - Upgraded to version.pm 0.7203. [John Peacock]
+
+ - Support get_action_docs() =head2 style. [ewilhelm]
+
+ - Workaround Test::Pod::Coverage @INC bug. [Eric Wilhelm]
+
+ - Fixed the command-line args --extra_compiler_flags and
+   --extra_linker_flags so they properly shell-split their arguments.
+
+0.2807 - Sat Mar 24 22:19:02 2007
+
+ - Upgraded to version.pm 0.71. [John Peacock]
+
+ - Removed a couple small constructs in the tests ("use warnings;" and
+   "qw$foo bar$[1]") that caused test failures under perl 5.005.
+
+ - Added support for an explicit default value of undef in prompt().
+   [Eric Wilhelm]
+
+ - Improved our prompt() method, which could sometimes hang before the
+   user got a chance to see a prompt. [Andreas Koenig]
+
+ - Added a note about --allow_mb_mismatch to the error message that
+   happens right before someone might want to use that parameter.
+
+ - Added DragonflyBSD to the list of known Unix OSes.
+
+ - get_action_docs() dies on error rather than twiddling $@
+
+ - Made ModuleInfo's _evaluate_version_line() compatible with 'use
+   version ...$VERSION' lines.  [Eric Wilhelm]
+
+ - Added some verbiage in Module::Build::API that officially blesses
+   the _build/prereqs file for external consumption. [Suggested by Andreas Koenig]
+
+ - Added test profiles support via the test_types property and "testall"
+   target. [Eric Wilhelm, Jeff Lavallee]
+
+ - Use syscopy() on OS/2 in copy_if_modified() so we make sure to
+   overwrite any existing target file. [Ilya Zakharevich]
+
+ - Removed seemingly silly '~~' test in t/tilde.t.
+
+ - In our test-time utility library t/lib/MBTest.pm, we need to know
+   about a few .exe-like extensions on OS/2. [Ilya Zakharevich]
+
+ - In t/ppm.t, use DynaLoader::mod2fname() (if available) to determine
+   the correct translation of our test module's name into a DLL
+   name. [Ilya Zakharevich]
+
+ - Avoid an unlink() error on OS/2 when fixing shebang lines. [Ilya
+   Zakharevich]
+
+ - When we're protecting the world from the evils of long RedHat
+   $ENV{PERL5LIB} variables, don't assume $ENV{PERL5LIB} is already
+   defined.  This gets rid of a huge number of warnings for some
+   people. [Dave Rolsky]
+
+0.2806 - Fri Dec 15 22:20:14 2006
+
  - On some systems (haven't identified the actual problem yet)
    $ENV{PERL5LIB} can grow to enormous enough sizes that we can't
    launch any more subprocesses because the environment table is full.
index c64dfc0..d1bc725 100644 (file)
@@ -2,7 +2,7 @@ package Module::Build::Compat;
 
 use strict;
 use vars qw($VERSION);
-$VERSION = '0.03';
+$VERSION = '0.2808_01';
 
 use File::Spec;
 use IO::File;
@@ -42,6 +42,13 @@ 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 
+  # Makefile.PL
+  my $requires = $build->requires;
+  if ( my $minimum_perl = $requires->{perl} ) {
+    print {$fh} "require $minimum_perl;\n";
+  }
+
   # If a *bundled* custom subclass is being used, make sure we add its
   # directory to @INC.
   my $subclass_load = '';
index ccf58d9..76b92b9 100644 (file)
@@ -1,6 +1,9 @@
 package Module::Build::Config;
 
 use strict;
+use vars qw($VERSION);
+$VERSION = '0.2808_01';
+$VERSION = eval $VERSION;
 use Config;
 
 sub new {
index 03341fa..ba721b9 100644 (file)
@@ -9,19 +9,15 @@ Module::Build::Cookbook - Examples of Module::Build Usage
 =head1 DESCRIPTION
 
 C<Module::Build> isn't conceptually very complicated, but examples are
-always helpful.  I got the idea for writing this cookbook when
-attending Brian Ingerson's "Extreme Programming Tools for Module
-Authors" presentation at YAPC 2003, when he said, straightforwardly,
-"Write A Cookbook."
-
-The definitional of how stuff works is in the main C<Module::Build>
-documentation.  It's best to get familiar with that too.
+always helpful.  The following recipes should help developers and/or
+installers put together the pieces from the other parts of the
+documentation.
 
 
 =head1 BASIC RECIPES
 
 
-=head2 The basic installation recipe for modules that use Module::Build
+=head2 Installing modules that use Module::Build
 
 In most cases, you can just issue the following commands:
 
@@ -57,35 +53,42 @@ double-click on the F<Build.PL> script to create the F<Build> script,
 then double-click on the F<Build> script to run its C<build>, C<test>,
 and C<install> actions.
 
-The F<Build> script knows what perl was used to run C<Build.PL>, so
+The F<Build> script knows what perl was used to run F<Build.PL>, so
 you don't need to re-invoke the F<Build> script with the complete perl
 path each time.  If you invoke it with the I<wrong> perl path, you'll
 get a warning or a fatal error.
 
+=head2 Modifying Config.pm values
 
-=head2 Making a CPAN.pm-compatible distribution
+C<Module::Build> relies heavily on various values from perl's
+C<Config.pm> to do its work.  For example, default installation paths
+are given by C<installsitelib> and C<installvendorman3dir> and
+friends, C linker & compiler settings are given by C<ld>,
+C<lddlflags>, C<cc>, C<ccflags>, and so on.  I<If you're pretty sure
+you know what you're doing>, you can tell C<Module::Build> to pretend
+there are different values in F<Config.pm> than what's really there,
+by passing arguments for the C<--config> parameter on the command
+line:
 
-New versions of CPAN.pm understand how to use a F<Build.PL> script,
-but old versions don't.  If you want to help users who have old
-versions, do the following:
+  perl Build.PL --config cc=gcc --config ld=gcc
 
-Create a file in your distribution named F<Makefile.PL>, with the
-following contents:
+Inside the C<Build.PL> script the same thing can be accomplished by
+passing values for the C<config> parameter to C<new()>:
 
-  use Module::Build::Compat;
-  Module::Build::Compat->run_build_pl(args => \@ARGV);
-  Module::Build::Compat->write_makefile();
+ my $build = Module::Build->new
+   (
+    ...
+    config => { cc => 'gcc', ld => 'gcc' },
+    ...
+   );
 
-Now CPAN will work as usual, i.e.: `perl Makefile.PL`, `make`, `make
-test`, and `make install`, provided the end-user already has
-C<Module::Build> installed.
+In custom build code, the same thing can be accomplished by calling
+the L<Module::Build/config> method:
 
-If the end-user might not have C<Module::Build> installed, it's
-probably best to supply a "traditional" F<Makefile.PL>.  The
-C<Module::Build::Compat> module has some very helpful tools for
-keeping a F<Makefile.PL> in sync with a F<Build.PL>.  See its
-documentation, and also the C<create_makefile_pl> parameter to the
-C<< Module::Build->new() >> method.
+ $build->config( cc => 'gcc' );     # Set
+ $build->config( ld => 'gcc' );     # Set
+ ...
+ my $linker = $build->config('ld'); # Get
 
 
 =head2 Installing modules using the programmatic interface
@@ -131,7 +134,7 @@ F</tmp/my-package-1.003> directory.
 
 To install to a non-standard directory (for example, if you don't have
 permission to install in the system-wide directories), you can use the
-C<install_base>:
+C<install_base> or C<prefix> parameters:
 
   ./Build install --install_base /foo/bar
 
@@ -147,7 +150,7 @@ to install to the same locations.
 
 First, ensure you have at least version 0.28 of Module::Build
 installed and 6.31 of ExtUtils::MakeMaker.  Prior versions have
-differing installation behaviors.
+differing (and in some cases quite strange) installation behaviors.
 
 The following installation flags are equivalent between
 ExtUtils::MakeMaker and Module::Build.
@@ -178,10 +181,10 @@ You can install into the same location with Module::Build using this:
 
 =head3 C<prefix> vs C<install_base>
 
-The behavior of C<prefix> is complicated and depends closely on
+The behavior of C<prefix> is complicated and depends on
 how your Perl is configured.  The resulting installation locations
 will vary from machine to machine and even different installations of
-Perl on the same machine.  Because of this, its difficult to document
+Perl on the same machine.  Because of this, it's difficult to document
 where C<prefix> will place your modules.
 
 In contrast, C<install_base> has predictable, easy to explain
@@ -206,7 +209,7 @@ informative output:
 
   ./Build test --test_files t/mytest.t --verbose 1
 
-I run this so frequently that I actually define the following shell alias:
+I run this so frequently that I define the following shell alias:
 
   alias t './Build test --verbose 1 --test_files'
 
@@ -216,6 +219,24 @@ So then I can just execute C<t t/mytest.t> to run a single test.
 =head1 ADVANCED RECIPES
 
 
+=head2 Making a CPAN.pm-compatible distribution
+
+New versions of CPAN.pm understand how to use a F<Build.PL> script,
+but old versions don't.  If authors want to help users who have old
+versions, some form of F<Makefile.PL> should be supplied.  The easiest
+way to accomplish this is to use the C<create_makefile_pl> parameter to
+C<< Module::Build->new() >> in the C<Build.PL> script, which can
+create various flavors of F<Makefile.PL> during the C<dist> action.
+
+As a best practice, we recommend using the "traditional" style of
+F<Makefile.PL> unless your distribution has needs that can't be
+accomplished that way.
+
+The C<Module::Build::Compat> module, which is part of
+C<Module::Build>'s distribution, is responsible for creating these
+F<Makefile.PL>s.  Please see L<Module::Build::Compat> for the details.
+
+
 =head2 Changing the order of the build process
 
 The C<build_elements> property specifies the steps C<Module::Build>
@@ -241,8 +262,7 @@ C<Module::Build> code.
 Sometimes you might have extra types of files that you want to install
 alongside the standard types like F<.pm> and F<.pod> files.  For
 instance, you might have a F<Bar.dat> file containing some data
-related to the C<Foo::Bar> module.  Assuming the data doesn't need to
-be created on the fly, the best place for it to end up is probably as
+related to the C<Foo::Bar> module and you'd like for it to end up as
 F<Foo/Bar.dat> somewhere in perl's C<@INC> path so C<Foo::Bar> can
 access it easily at runtime.  The following code from a sample
 C<Build.PL> file demonstrates how to accomplish this:
@@ -260,9 +280,9 @@ This will find all F<.dat> files in the F<lib/> directory, copy them
 to the F<blib/lib/> directory during the C<build> action, and install
 them during the C<install> action.
 
-If your extra files aren't in the C<lib/> directory, you can
-explicitly say where they are, just as you'd do with F<.pm> or F<.pod>
-files:
+If your extra files aren't located in the C<lib/> directory in your
+distribution, you can explicitly say where they are, just as you'd do
+with F<.pm> or F<.pod> files:
 
   use Module::Build;
   my $build = new Module::Build
@@ -276,8 +296,8 @@ files:
 
 If your extra files actually need to be created on the user's machine,
 or if they need some other kind of special processing, you'll probably
-want to create a special method to do so, named
-C<process_${kind}_files()>:
+want to subclass C<Module::Build> and create a special method to
+process them, named C<process_${kind}_files()>:
 
   use Module::Build;
   my $class = Module::Build->subclass(code => <<'EOF');
@@ -300,20 +320,20 @@ L<"Adding new elements to the install process"> for how to actually
 get them installed.
 
 Please note that these examples use some capabilities of Module::Build
-that first appeared in version 0.26.  Before that it could certainly
+that first appeared in version 0.26.  Before that it could
 still be done, but the simple cases took a bit more work.
 
 
 =head2 Adding new elements to the install process
 
-By default, Module::Build creates seven subdirectories of the F<blib/>
-directory during the build process: F<lib/>, F<arch/>, F<bin/>,
-F<script/>, F<bindoc/>, F<libdoc/>, and F<html/> (some of these may be
+By default, Module::Build creates seven subdirectories of the F<blib>
+directory during the build process: F<lib>, F<arch>, F<bin>,
+F<script>, F<bindoc>, F<libdoc>, and F<html> (some of these may be
 missing or empty if there's nothing to go in them).  Anything copied
 to these directories during the build will eventually be installed
 during the C<install> action (see L<Module::Build/"INSTALL PATHS">.
 
-If you need to create a new type of installable element, e.g. C<conf>,
+If you need to create a new custom type of installable element, e.g. C<conf>,
 then you need to tell Module::Build where things in F<blib/conf/>
 should be installed.  To do this, use the C<install_path> parameter to
 the C<new()> method:
@@ -326,11 +346,7 @@ the C<new()> method:
 
 Or you can call the C<install_path()> method later:
 
-  $build->install_path->{conf} || $installation_path;
-
-(Sneakily, or perhaps uglily, C<install_path()> returns a reference to
-a hash of install paths, and you can modify that hash to your heart's
-content.)
+  $build->install_path(conf => $installation_path);
 
 The user may also specify the path on the command line:
 
@@ -338,7 +354,8 @@ The user may also specify the path on the command line:
 
 The important part, though, is that I<somehow> the install path needs
 to be set, or else nothing in the F<blib/conf/> directory will get
-installed.
+installed, and a runtime error during the C<install> action will
+result.
 
 See also L<"Adding new file types to the build process"> for how to
 create the stuff in F<blib/conf/> in the first place.
@@ -385,11 +402,12 @@ do something unusual.  For instance, you might need to change the
 ownership of a file or do something else peculiar to your application.
 
 You can subclass C<Module::Build> on the fly using the C<subclass()>
-method and override the methods that perform the actions. You may need
-to read through C<Module::Build::Authoring> to find the methods you
-want to override, but the general pattern is C<ACTION_> followed by
-the name of the action you want to modify.  Here's an example of how
-it would work for C<install>:
+method and override the methods that perform the actions.  You may
+need to read through C<Module::Build::Authoring> and
+C<Module::Build::API> to find the methods you want to override.  All
+"action" methods are implemented by a method called "ACTION_" followed
+by the action's name, so here's an example of how it would work for
+the C<install> action:
 
   # Build.PL
   use Module::Build;
@@ -409,9 +427,6 @@ it would work for C<install>:
       # rest of the usual Module::Build parameters
   )->create_build_script;
 
-See the L<Module::Build::Authoring> pod in 0.27 or above for more
-complete documentation on this.
-
 
 =head1 AUTHOR
 
diff --git a/lib/Module/Build/Dumper.pm b/lib/Module/Build/Dumper.pm
new file mode 100644 (file)
index 0000000..7021ece
--- /dev/null
@@ -0,0 +1,16 @@
+package Module::Build::Dumper;
+
+# This is just a split-out of a wrapper function to do Data::Dumper
+# stuff "the right way".  See:
+# http://groups.google.com/group/perl.module.build/browse_thread/thread/c8065052b2e0d741
+
+use Data::Dumper;
+
+sub _data_dump {
+  my ($self, $data) = @_;
+  return ("do{ my "
+         . Data::Dumper->new([$data],['x'])->Purity(1)->Dump()
+         . '$x; }')
+}
+
+1;
index 7241f83..66a6671 100644 (file)
@@ -5,6 +5,9 @@ package Module::Build::ModuleInfo;
 # parrot future to look at other types of modules).
 
 use strict;
+use vars qw($VERSION);
+$VERSION = '0.2808_01';
+$VERSION = eval $VERSION;
 
 use File::Spec;
 use IO::File;
index aaabbc3..8afdd8c 100644 (file)
@@ -3,8 +3,12 @@ package Module::Build::Notes;
 # A class for persistent hashes
 
 use strict;
+use vars qw($VERSION);
+$VERSION = '0.2808_01';
+$VERSION = eval $VERSION;
 use Data::Dumper;
 use IO::File;
+use Module::Build::Dumper;
 
 sub new {
   my ($class, %args) = @_;
@@ -104,8 +108,7 @@ sub _dump {
   my ($self, $file, $data) = @_;
   
   my $fh = IO::File->new("> $file") or die "Can't create '$file': $!";
-  local $Data::Dumper::Terse = 1;
-  print $fh Data::Dumper::Dumper($data);
+  print {$fh} Module::Build::Dumper->_data_dump($data);
 }
 
 sub write_config_data {
@@ -138,6 +141,9 @@ sub config_names  { keys %%$config }
 sub write {
   my $me = __FILE__;
   require IO::File;
+
+  # Can't use Module::Build::Dumper here because M::B is only a
+  # build-time prereq of this module
   require Data::Dumper;
 
   my $mode_orig = (stat $me)[2] & 07777;
@@ -149,9 +155,11 @@ sub write {
   }
   die "Couldn't find __DATA__ token in $me" if eof($fh);
 
-  local $Data::Dumper::Terse = 1;
   seek($fh, tell($fh), 0);
-  $fh->print( Data::Dumper::Dumper([$config, $features, $auto_features]) );
+  my $data = [$config, $features, $auto_features];
+  $fh->print( 'do{ my '
+             . Data::Dumper->new([$data],['x'])->Purity(1)->Dump()
+             . '$x; }' );
   truncate($fh, tell($fh));
   $fh->close;
 
@@ -281,8 +289,7 @@ __DATA__
 
 EOF
 
-  local $Data::Dumper::Terse = 1;
-  print $fh Data::Dumper::Dumper([$args{config_data}, $args{feature}, $args{auto_features}]);
+  print {$fh} Module::Build::Dumper->_data_dump([$args{config_data}, $args{feature}, $args{auto_features}]);
 }
 
 1;
index 07c77b8..f4b2cd8 100644 (file)
@@ -1,6 +1,9 @@
 package Module::Build::PPMMaker;
 
 use strict;
+use vars qw($VERSION);
+$VERSION = '0.2808_01';
+$VERSION = eval $VERSION;
 
 # This code is mostly borrowed from ExtUtils::MM_Unix 6.10_03, with a
 # few tweaks based on the PPD spec at
index 34671a5..d437560 100644 (file)
@@ -1,6 +1,9 @@
 package Module::Build::Platform::Amiga;
 
 use strict;
+use vars qw($VERSION);
+$VERSION = '0.2808_01';
+$VERSION = eval $VERSION;
 use Module::Build::Base;
 
 use vars qw(@ISA);
index c60e21c..1fc3415 100644 (file)
@@ -1,6 +1,9 @@
 package Module::Build::Platform::Default;
 
 use strict;
+use vars qw($VERSION);
+$VERSION = '0.2808_01';
+$VERSION = eval $VERSION;
 use Module::Build::Base;
 
 use vars qw(@ISA);
index 1c9094a..da5b75c 100644 (file)
@@ -1,6 +1,9 @@
 package Module::Build::Platform::EBCDIC;
 
 use strict;
+use vars qw($VERSION);
+$VERSION = '0.2808_01';
+$VERSION = eval $VERSION;
 use Module::Build::Base;
 
 use vars qw(@ISA);
index af3fdf2..6706484 100644 (file)
@@ -1,6 +1,9 @@
 package Module::Build::Platform::MPEiX;
 
 use strict;
+use vars qw($VERSION);
+$VERSION = '0.2808_01';
+$VERSION = eval $VERSION;
 use Module::Build::Base;
 
 use vars qw(@ISA);
index 1ba1cf2..9cd7b8f 100644 (file)
@@ -1,6 +1,9 @@
 package Module::Build::Platform::MacOS;
 
 use strict;
+use vars qw($VERSION);
+$VERSION = '0.2808_01';
+$VERSION = eval $VERSION;
 use Module::Build::Base;
 use vars qw(@ISA);
 @ISA = qw(Module::Build::Base);
index 3fec453..8883e20 100644 (file)
@@ -1,6 +1,9 @@
 package Module::Build::Platform::RiscOS;
 
 use strict;
+use vars qw($VERSION);
+$VERSION = '0.2808_01';
+$VERSION = eval $VERSION;
 use Module::Build::Base;
 
 use vars qw(@ISA);
index 214a33b..e5fa17c 100644 (file)
@@ -1,6 +1,9 @@
 package Module::Build::Platform::Unix;
 
 use strict;
+use vars qw($VERSION);
+$VERSION = '0.2808_01';
+$VERSION = eval $VERSION;
 use Module::Build::Base;
 
 use vars qw(@ISA);
@@ -39,6 +42,16 @@ sub _construct {
   return $self;
 }
 
+sub _detildefy {
+  my ($self, $value) = @_;
+  $value =~ s[^~(\w*)(?=/|$)]   # tilde with optional username
+    [$1 ?
+     ((getpwnam $1)[7] || "~$1") :
+     (getpwuid $>)[7]
+    ]ex;
+  return $value;
+}
+
 1;
 __END__
 
index d931c93..ed0a682 100644 (file)
@@ -1,6 +1,9 @@
 package Module::Build::Platform::VMS;
 
 use strict;
+use vars qw($VERSION);
+$VERSION = '0.2808_01';
+$VERSION = eval $VERSION;
 use Module::Build::Base;
 
 use vars qw(@ISA);
@@ -345,9 +348,10 @@ sub _detildefy {
 
 =item find_perl_interpreter
 
-On VMS, $^X returns the fully qualified absolute path including version number. 
-It's logically impossible to improve on it for getting the perl we're currently
-running, and attempting to manipulate it is usually lossy.
+On VMS, $^X returns the fully qualified absolute path including version
+number.  It's logically impossible to improve on it for getting the perl
+we're currently running, and attempting to manipulate it is usually
+lossy.
 
 =cut
 
index 2bd5f79..a3e5c8e 100644 (file)
@@ -1,6 +1,9 @@
 package Module::Build::Platform::VOS;
 
 use strict;
+use vars qw($VERSION);
+$VERSION = '0.2808_01';
+$VERSION = eval $VERSION;
 use Module::Build::Base;
 
 use vars qw(@ISA);
index 2cc3ffd..2ac4322 100644 (file)
@@ -1,6 +1,9 @@
 package Module::Build::Platform::Windows;
 
 use strict;
+use vars qw($VERSION);
+$VERSION = '0.2808_01';
+$VERSION = eval $VERSION;
 
 use Config;
 use File::Basename;
@@ -19,6 +22,13 @@ sub manpage_separator {
 
 sub have_forkpipe { 0 }
 
+sub _detildefy {
+  my ($self, $value) = @_;
+  $value =~ s,^~(?= [/\\] | $ ),$ENV{HOME},x
+    if $ENV{HOME};
+  return $value;
+}
+
 sub ACTION_realclean {
   my ($self) = @_;
 
index 983b25d..36257a7 100644 (file)
@@ -1,6 +1,9 @@
 package Module::Build::Platform::aix;
 
 use strict;
+use vars qw($VERSION);
+$VERSION = '0.2808_01';
+$VERSION = eval $VERSION;
 use Module::Build::Platform::Unix;
 
 use vars qw(@ISA);
index 3c3db95..71d465f 100644 (file)
@@ -1,6 +1,9 @@
 package Module::Build::Platform::cygwin;
 
 use strict;
+use vars qw($VERSION);
+$VERSION = '0.2808_01';
+$VERSION = eval $VERSION;
 use Module::Build::Platform::Unix;
 
 use vars qw(@ISA);
index ef381c4..60df8c4 100644 (file)
@@ -1,6 +1,9 @@
 package Module::Build::Platform::darwin;
 
 use strict;
+use vars qw($VERSION);
+$VERSION = '0.2808_01';
+$VERSION = eval $VERSION;
 use Module::Build::Platform::Unix;
 
 use vars qw(@ISA);
index 0496d2e..1b8ca0c 100644 (file)
@@ -1,6 +1,9 @@
 package Module::Build::Platform::os2;
 
 use strict;
+use vars qw($VERSION);
+$VERSION = '0.2808_01';
+$VERSION = eval $VERSION;
 use Module::Build::Platform::Unix;
 
 use vars qw(@ISA);
index bfc77db..53a191e 100644 (file)
@@ -1,6 +1,9 @@
 package Module::Build::PodParser;
 
 use strict;
+use vars qw($VERSION);
+$VERSION = '0.2808_01';
+$VERSION = eval $VERSION;
 use vars qw(@ISA);
 
 sub new {
index 2a956ff..5ba357b 100644 (file)
@@ -3,4 +3,587 @@ use strict;
 
 use vars qw($VERSION);
 $VERSION = 0.7203;
-use base qw/version/;
+
+eval "use version $VERSION";
+if ($@) { # can't locate version files, use our own
+
+    # Avoid redefined warnings if an old version.pm was available
+    delete $version::{$_} foreach keys %version::;
+
+    # first we get the stub version module
+    my $version;
+    while (<DATA>) {
+       s/(\$VERSION)\s=\s\d+/\$VERSION = 0/;
+       $version .= $_ if $_;
+       last if /^1;$/;
+    }
+
+    # and now get the current version::vpp code
+    my $vpp;
+    while (<DATA>) {
+       s/(\$VERSION)\s=\s\d+/\$VERSION = 0/;
+       $vpp .= $_ if $_;
+       last if /^1;$/;
+    }
+
+    # but we eval them in reverse order since version depends on
+    # version::vpp to already exist
+    eval $vpp; die $@ if $@;
+    $INC{'version/vpp.pm'} = 'inside Module::Build::Version';
+    eval $version; die $@ if $@;
+    $INC{'version.pm'} = 'inside Module::Build::Version';
+}
+
+# now we can safely subclass version, installed or not
+use vars qw(@ISA);
+@ISA = qw(version);
+
+1;
+__DATA__
+# stub version module to make everything else happy
+package version;
+
+use 5.005_04;
+use strict;
+
+use vars qw(@ISA $VERSION $CLASS *qv);
+
+$VERSION = 0.000;
+
+$CLASS = 'version';
+
+push @ISA, "version::vpp";
+*version::qv = \&version::vpp::qv;
+
+# Preloaded methods go here.
+sub import {
+    my ($class) = @_;
+    my $callpkg = caller();
+    no strict 'refs';
+    
+    *{$callpkg."::qv"} = 
+           sub {return bless version::qv(shift), $class }
+       unless defined(&{"$callpkg\::qv"});
+
+}
+
+1;
+# replace everything from here to the end with the current version/vpp.pm
+
+package version::vpp;
+use strict;
+
+use locale;
+use vars qw ($VERSION @ISA @REGEXS);
+$VERSION = 0.7203;
+
+push @REGEXS, qr/
+       ^v?     # optional leading 'v'
+       (\d*)   # major revision not required
+       \.      # requires at least one decimal
+       (?:(\d+)\.?){1,}
+       /x;
+
+use overload (
+    '""'       => \&stringify,
+    '0+'       => \&numify,
+    'cmp'      => \&vcmp,
+    '<=>'      => \&vcmp,
+    'bool'     => \&vbool,
+    'nomethod' => \&vnoop,
+);
+
+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} } ];
+           $self->{qv} = 1 if $value->{qv};
+           $self->{alpha} = 1 if $value->{alpha};
+           $self->{original} = ''.$value->{original};
+           return $self;
+       }
+
+       require POSIX;
+       my $currlocale = POSIX::setlocale(&POSIX::LC_ALL);
+       my $radix_comma = ( POSIX::localeconv()->{decimal_point} eq ',' );
+
+       if ( not defined $value or $value =~ /^undef$/ ) {
+           # RT #19517 - special case for undef comparison
+           # or someone forgot to pass a value
+           push @{$self->{version}}, 0;
+           $self->{original} = "0";
+           return ($self);
+       }
+
+       if ( $#_ == 2 ) { # must be CVS-style
+           $value = 'v'.$_[2];
+       }
+
+       $value = _un_vstring($value);
+
+       # exponential notation
+       if ( $value =~ /\d+.?\d*e-?\d+/ ) {
+           $value = sprintf("%.9f",$value);
+           $value =~ s/(0+)$//;
+       }
+       
+       # if the original locale used commas for decimal points, we
+       # just replace commas with decimal places, rather than changing
+       # locales
+       if ( $radix_comma ) {
+           $value =~ tr/,/./;
+       }
+
+       # 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
+       my $qv = 0;
+       my $alpha = 0;
+       my $width = 3;
+       my $saw_period = 0;
+       my ($start, $last, $pos, $s);
+       $s = 0;
+
+       while ( substr($value,$s,1) =~ /\s/ ) { # leading whitespace is OK
+           $s++;
+       }
+
+       if (substr($value,$s,1) eq 'v') {
+           $s++;    # get past 'v'
+           $qv = 1; # force quoted version processing
+       }
+
+       $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 '.' ) {
+               if ($alpha) {
+                   require Carp;
+                   Carp::croak("Invalid version format ".
+                       "(underscores before decimal)");
+               }
+               $saw_period++;
+               $last = $pos;
+           }
+           elsif ( substr($value,$pos,1) eq '_' ) {
+               if ($alpha) {
+                   require Carp;
+                   Carp::croak("Invalid version format ".
+                       "(multiple underscores)");
+               }
+               $alpha = 1;
+               $width = $pos - $last - 1; # natural width of sub-version
+           }
+           $pos++;
+       }
+
+       if ( $alpha && !$saw_period ) {
+           require Carp;
+           Carp::croak("Invalid version format (alpha without decimal)");
+       }
+
+       if ( $alpha && $saw_period && $width == 0 ) {
+           require Carp;
+           Carp::croak("Invalid version format (misplaced _ in number)");
+       }
+
+       if ( $saw_period > 1 ) {
+           $qv = 1; # force quoted version processing
+       }
+
+       $pos = $s;
+
+       if ( $qv ) {
+           $self->{qv} = 1;
+       }
+
+       if ( $alpha ) {
+           $self->{alpha} = 1;
+       }
+
+       if ( !$qv && $width < 3 ) {
+           $self->{width} = $width;
+       }
+
+       while ( substr($value,$pos,1) =~ /\d/ ) {
+           $pos++;
+       }
+
+       if ( substr($value,$pos,1) !~ /[a-z]/ ) { ### FIX THIS ###
+           my $rev;
+
+           while (1) {
+               $rev = 0;
+               {
+
+                   # this is atoi() that delimits on underscores
+                   my $end = $pos;
+                   my $mult = 1;
+                   my $orev;
+
+                   # the following if() will only be true after the decimal
+                   # point of a version originally created with a bare
+                   # floating point number, i.e. not quoted in any way
+                   if ( !$qv && $s > $start && $saw_period == 1 ) {
+                       $mult *= 100;
+                       while ( $s < $end ) {
+                           $orev = $rev;
+                           $rev += substr($value,$s,1) * $mult;
+                           $mult /= 10;
+                           if ( abs($orev) > abs($rev) ) {
+                               require Carp;
+                               Carp::croak("Integer overflow in version");
+                           }
+                           $s++;
+                           if ( substr($value,$s,1) eq '_' ) {
+                               $s++;
+                           }
+                       }
+                   }
+                   else {
+                       while (--$end >= $s) {
+                           $orev = $rev;
+                           $rev += substr($value,$end,1) * $mult;
+                           $mult *= 10;
+                           if ( abs($orev) > abs($rev) ) {
+                               require Carp;
+                               Carp::croak("Integer overflow in version");
+                           }
+                       }
+                   }
+               }
+
+               # Append revision
+               push @{$self->{version}}, $rev;
+               if ( substr($value,$pos,1) eq '.' 
+                   && substr($value,$pos+1,1) =~ /\d/ ) {
+                   $s = ++$pos;
+               }
+               elsif ( substr($value,$pos,1) eq '_' 
+                   && substr($value,$pos+1,1) =~ /\d/ ) {
+                   $s = ++$pos;
+               }
+               elsif ( substr($value,$pos,1) =~ /\d/ ) {
+                   $s = $pos;
+               }
+               else {
+                   $s = $pos;
+                   last;
+               }
+               if ( $qv ) {
+                   while ( substr($value,$pos,1) =~ /\d/ ) {
+                       $pos++;
+                   }
+               }
+               else {
+                   my $digits = 0;
+                   while (substr($value,$pos,1) =~ /[\d_]/ && $digits < 3) {
+                       if ( substr($value,$pos,1) ne '_' ) {
+                           $digits++;
+                       }
+                       $pos++;
+                   }
+               }
+           }
+       }
+       if ( $qv ) { # quoted versions always get at least three terms
+           my $len = scalar @{$self->{version}};
+           $len = 3 - $len;
+           while ($len-- > 0) {
+               push @{$self->{version}}, 0;
+           }
+       }
+
+       if ( substr($value,$pos) ) { # any remaining text
+           warn "Version string '$value' contains invalid data; ".
+                "ignoring: '".substr($value,$pos)."'";
+       }
+
+       # cache the original value for use when stringification
+       $self->{original} = substr($value,0,$pos);
+
+       return ($self);
+}
+
+sub numify 
+{
+    my ($self) = @_;
+    unless (_verify($self)) {
+       require Carp;
+       Carp::croak("Invalid version object");
+    }
+    my $width = $self->{width} || 3;
+    my $alpha = $self->{alpha} || "";
+    my $len = $#{$self->{version}};
+    my $digit = $self->{version}[0];
+    my $string = sprintf("%d.", $digit );
+
+    for ( my $i = 1 ; $i < $len ; $i++ ) {
+       $digit = $self->{version}[$i];
+       if ( $width < 3 ) {
+           my $denom = 10**(3-$width);
+           my $quot = int($digit/$denom);
+           my $rem = $digit - ($quot * $denom);
+           $string .= sprintf("%0".$width."d_%d", $quot, $rem);
+       }
+       else {
+           $string .= sprintf("%03d", $digit);
+       }
+    }
+
+    if ( $len > 0 ) {
+       $digit = $self->{version}[$len];
+       if ( $alpha && $width == 3 ) {
+           $string .= "_";
+       }
+       $string .= sprintf("%0".$width."d", $digit);
+    }
+    else # $len = 0
+    {
+       $string .= sprintf("000");
+    }
+
+    return $string;
+}
+
+sub normal 
+{
+    my ($self) = @_;
+    unless (_verify($self)) {
+       require Carp;
+       Carp::croak("Invalid version object");
+    }
+    my $alpha = $self->{alpha} || "";
+    my $len = $#{$self->{version}};
+    my $digit = $self->{version}[0];
+    my $string = sprintf("v%d", $digit );
+
+    for ( my $i = 1 ; $i < $len ; $i++ ) {
+       $digit = $self->{version}[$i];
+       $string .= sprintf(".%d", $digit);
+    }
+
+    if ( $len > 0 ) {
+       $digit = $self->{version}[$len];
+       if ( $alpha ) {
+           $string .= sprintf("_%0d", $digit);
+       }
+       else {
+           $string .= sprintf(".%0d", $digit);
+       }
+    }
+
+    if ( $len <= 2 ) {
+       for ( $len = 2 - $len; $len != 0; $len-- ) {
+           $string .= sprintf(".%0d", 0);
+       }
+    }
+
+    return $string;
+}
+
+sub stringify
+{
+    my ($self) = @_;
+    unless (_verify($self)) {
+       require Carp;
+       Carp::croak("Invalid version object");
+    }
+    return $self->{original};
+}
+
+sub vcmp
+{
+    require UNIVERSAL;
+    my ($left,$right,$swap) = @_;
+    my $class = ref($left);
+    unless ( UNIVERSAL::isa($right, $class) ) {
+       $right = $class->new($right);
+    }
+
+    if ( $swap ) {
+       ($left, $right) = ($right, $left);
+    }
+    unless (_verify($left)) {
+       require Carp;
+       Carp::croak("Invalid version object");
+    }
+    unless (_verify($right)) {
+       require Carp;
+       Carp::croak("Invalid version object");
+    }
+    my $l = $#{$left->{version}};
+    my $r = $#{$right->{version}};
+    my $m = $l < $r ? $l : $r;
+    my $lalpha = $left->is_alpha;
+    my $ralpha = $right->is_alpha;
+    my $retval = 0;
+    my $i = 0;
+    while ( $i <= $m && $retval == 0 ) {
+       $retval = $left->{version}[$i] <=> $right->{version}[$i];
+       $i++;
+    }
+
+    # tiebreaker for alpha with identical terms
+    if ( $retval == 0 
+       && $l == $r 
+       && $left->{version}[$m] == $right->{version}[$m]
+       && ( $lalpha || $ralpha ) ) {
+
+       if ( $lalpha && !$ralpha ) {
+           $retval = -1;
+       }
+       elsif ( $ralpha && !$lalpha) {
+           $retval = +1;
+       }
+    }
+
+    # possible match except for trailing 0's
+    if ( $retval == 0 && $l != $r ) {
+       if ( $l < $r ) {
+           while ( $i <= $r && $retval == 0 ) {
+               if ( $right->{version}[$i] != 0 ) {
+                   $retval = -1; # not a match after all
+               }
+               $i++;
+           }
+       }
+       else {
+           while ( $i <= $l && $retval == 0 ) {
+               if ( $left->{version}[$i] != 0 ) {
+                   $retval = +1; # not a match after all
+               }
+               $i++;
+           }
+       }
+    }
+
+    return $retval;  
+}
+
+sub vbool {
+    my ($self) = @_;
+    return vcmp($self,$self->new("0"),1);
+}
+
+sub vnoop { 
+    require Carp; 
+    Carp::croak("operation not supported with version object");
+}
+
+sub is_alpha {
+    my ($self) = @_;
+    return (exists $self->{alpha});
+}
+
+sub qv {
+    my ($value) = @_;
+
+    $value = _un_vstring($value);
+    $value = 'v'.$value unless $value =~ /(^v|\d+\.\d+\.\d)/;
+    my $version = version->new($value); # always use base class
+    return $version;
+}
+
+sub is_qv {
+    my ($self) = @_;
+    return (exists $self->{qv});
+}
+
+
+sub _verify {
+    my ($self) = @_;
+    if ( ref($self)
+       && eval { exists $self->{version} }
+       && ref($self->{version}) eq 'ARRAY'
+       ) {
+       return 1;
+    }
+    else {
+       return 0;
+    }
+}
+
+sub _un_vstring {
+    my $value = shift;
+    # may be a v-string
+    if ( $] >= 5.006_000 && length($value) >= 3 && $value !~ /[._]/ ) {
+       my $tvalue = sprintf("v%vd",$value);
+       if ( $tvalue =~ /^v\d+\.\d+\.\d+$/ ) {
+           # must be a v-string
+           $value = $tvalue;
+       }
+    }
+    return $value;
+}
+
+# Thanks to Yitzchak Scott-Thoennes for this mode of operation
+{
+    local $^W;
+    *UNIVERSAL::VERSION = sub {
+       my ($obj, $req) = @_;
+       my $class = ref($obj) || $obj;
+
+       no strict 'refs';
+       eval "require $class" unless %{"$class\::"}; # already existing
+       return undef if $@ =~ /Can't locate/ and not defined $req;
+       
+       if ( not %{"$class\::"} and $] >= 5.008) { # file but no package
+           require Carp;
+           Carp::croak( "$class defines neither package nor VERSION"
+               ."--version check failed");
+       }
+       
+       my $version = eval "\$$class\::VERSION";
+       if ( defined $version ) {
+           local $^W if $] <= 5.008;
+           $version = version::vpp->new($version);
+       }
+
+       if ( defined $req ) {
+           unless ( defined $version ) {
+               require Carp;
+               my $msg =  $] < 5.006 
+               ? "$class version $req required--this is only version "
+               : "$class does not define \$$class\::VERSION"
+                 ."--version check failed";
+
+               if ( $ENV{VERSION_DEBUG} ) {
+                   Carp::confess($msg);
+               }
+               else {
+                   Carp::croak($msg);
+               }
+           }
+
+           $req = version::vpp->new($req);
+
+           if ( $req > $version ) {
+               require Carp;
+               if ( $req->is_qv ) {
+                   Carp::croak( 
+                       sprintf ("%s version %s required--".
+                           "this is only version %s", $class,
+                           $req->normal, $version->normal)
+                   );
+               }
+               else {
+                   Carp::croak( 
+                       sprintf ("%s version %s required--".
+                           "this is only version %s", $class,
+                           $req->stringify, $version->stringify)
+                   );
+               }
+           }
+       }
+
+       return defined $version ? $version->stringify : undef;
+    };
+}
+
+1; #this line is important and will help the module return a true value
index 2106308..4922bd5 100644 (file)
@@ -1,6 +1,9 @@
 package Module::Build::YAML;
 
 use strict;
+use vars qw($VERSION);
+$VERSION = '0.2808_01';
+$VERSION = eval $VERSION;
 
 use vars qw($VERSION @EXPORT @EXPORT_OK);
 $VERSION = "0.50";
index 57a8550..a1adaa7 100644 (file)
@@ -6,7 +6,7 @@ use MBTest tests => 52;
 
 use Cwd ();
 my $cwd = Cwd::cwd;
-my $tmp = File::Spec->catdir( $cwd, 't', '_tmp' );
+my $tmp = MBTest->tmpdir;
 
 use DistGen;
 my $dist = DistGen->new( dir => $tmp );
@@ -122,23 +122,18 @@ SKIP: {
 # Getopt::Long specs work as expected.
 {
   use Config;
-  $dist->change_file( 'Build.PL', <<"---" );
-use Module::Build;
-
-my \$build = Module::Build->new(
-  module_name => @{[$dist->name]},
-  license     => 'perl',
-  get_options => { foo => {},
-                   bar => { type    => '+'  },
-                   bat => { type    => '=s' },
-                   dee => { type    => '=s',
-                            default => 'goo'
-                          },
-                 }
-);
-
-\$build->create_build_script;
----
+  $dist->change_build_pl
+    ({
+      module_name => @{[$dist->name]},
+      license     => 'perl',
+      get_options => { foo => {},
+                      bar => { type    => '+'  },
+                      bat => { type    => '=s' },
+                      dee => { type    => '=s',
+                               default => 'goo'
+                             },
+                    }
+     });
 
   $dist->regen;
   eval {Module::Build->run_perl_script('Build.PL', [], ['--nouse-rcfile', '--config', "foocakes=barcakes", '--foo', '--bar', '--bar', '-bat=hello', 'gee=whiz', '--any', 'hey', '--destdir', 'yo', '--verbose', '1'])};
index 74fb275..4276a9d 100644 (file)
@@ -5,7 +5,7 @@ package Tie::CPHash;
 #
 # Author: Christopher J. Madsen <cjm@pobox.com>
 # Created: 08 Nov 1997
-# $Revision: 1849 $  $Date: 2006-03-21T13:27:29.000000Z $
+# $Revision: 5841 $  $Date: 2006-03-21 07:27:29 -0600 (Tue, 21 Mar 2006) $
 #
 # This program is free software; you can redistribute it and/or modify
 # it under the same terms as Perl itself.
index 64f0aeb..8eb654a 100644 (file)
@@ -4,6 +4,7 @@ use strict;
 use lib $ENV{PERL_CORE} ? '../lib/Module/Build/t/lib' : 't/lib';
 use MBTest;
 use File::Spec;
+use IO::File;
 use Config;
 
 # Don't let our own verbosity/test_file get mixed up with our subprocess's
@@ -12,21 +13,22 @@ local  @ENV{@makefile_keys};
 delete @ENV{@makefile_keys};
 
 my @makefile_types = qw(small passthrough traditional);
-my $tests_per_type = 10;
+my $tests_per_type = 14;
 if ( $Config{make} && find_in_path($Config{make}) ) {
-    plan tests => 30 + @makefile_types*$tests_per_type;
+    plan tests => 38 + @makefile_types*$tests_per_type*2;
 } else {
     plan skip_all => "Don't know how to invoke 'make'";
 }
-ok(1);  # Loaded
+ok 1, "Loaded";
 
 
 #########################
 
 use Cwd ();
 my $cwd = Cwd::cwd;
-my $tmp = File::Spec->catdir( $cwd, 't', '_tmp' );
+my $tmp = MBTest->tmpdir;
 
+# Create test distribution; set requires and build_requires
 use DistGen;
 my $dist = DistGen->new( dir => $tmp );
 $dist->regen;
@@ -45,32 +47,48 @@ my @make = $Config{make} eq 'nmake' ? ('nmake', '-nologo') : ($Config{make});
 
 #########################
 
+# Test without requires
 
-my $mb = Module::Build->new_from_context;
-ok $mb;
+test_makefile_types();
+
+# Test with requires
+
+my $distname = $dist->name;
+$dist->change_build_pl({ 
+  module_name         => $distname,
+  license             => 'perl',
+  requires            => {
+    'perl'        => $],
+    'File::Spec'  => 0,
+  },
+  build_requires      => {
+    'Test::More'  => 0,
+  },
+});
+
+$dist->regen;
+
+test_makefile_types( requires => {
+    'perl' => $],
+    'File::Spec' => 0,
+    'Test::More' => 0,
+});
+
+######################
+
+$dist->change_build_pl({ 
+  module_name         => $distname,
+  license             => 'perl',
+});
+$dist->regen;
+
+# Create M::B instance but don't pollute STDOUT
+my $mb;
+stdout_of( sub {
+    $mb = Module::Build->new_from_context;
+});
+ok $mb, "Module::Build->new_from_context";
 
-foreach my $type (@makefile_types) {
-  Module::Build::Compat->create_makefile_pl($type, $mb);
-  test_makefile_creation($mb);
-  
-  ok $mb->do_system(@make);
-  
-  # Can't let 'test' STDOUT go to our STDOUT, or it'll confuse Test::Harness.
-  my $success;
-  my $output = stdout_of( sub {
-                           $success = $mb->do_system(@make, 'test');
-                         } );
-  ok $success;
-  like uc $output, qr{DONE\.|SUCCESS};
-  
-  ok $mb->do_system(@make, 'realclean');
-  
-  # Try again with some Makefile.PL arguments
-  test_makefile_creation($mb, [], 'INSTALLDIRS=vendor', 1);
-  
-  1 while unlink 'Makefile.PL';
-  ok ! -e 'Makefile.PL';
-}
 
 {
   # Make sure fake_makefile() can run without 'build_class', as it may be
@@ -78,35 +96,45 @@ foreach my $type (@makefile_types) {
   my $warning = '';
   local $SIG{__WARN__} = sub { $warning = shift; };
   my $maketext = eval { Module::Build::Compat->fake_makefile(makefile => 'Makefile') };
-  is $@, '';
-  like $maketext, qr/^realclean/m;
-  like $warning, qr/build_class/;
+  is $@, '', "fake_makefile lived";
+  like $maketext, qr/^realclean/m, "found 'realclean' in fake_makefile output";
+  like $warning, qr/build_class/, "saw warning about 'build_class'";
 }
 
 {
   # Make sure custom builder subclass is used in the created
   # Makefile.PL - make sure it fails in the right way here.
   local @Foo::Builder::ISA = qw(Module::Build);
-  my $foo_builder = Foo::Builder->new_from_context;
+  my $foo_builder;
+  stdout_of( sub {
+    $foo_builder = Foo::Builder->new_from_context;
+  });
   foreach my $style ('passthrough', 'small') {
     Module::Build::Compat->create_makefile_pl($style, $foo_builder);
-    ok -e 'Makefile.PL';
+    ok -e 'Makefile.PL', "$style Makefile.PL created";
     
     # Should fail with "can't find Foo/Builder.pm"
-    my $warning = stderr_of
-      (sub {
-        my $result = $mb->run_perl_script('Makefile.PL');
-        ok ! $result;
-       });
-    like $warning, qr{Foo/Builder.pm};
+    my $result;
+    my ($stdout, $stderr ) = stdout_stderr_of (sub {
+      $result = $mb->run_perl_script('Makefile.PL');
+    });
+    ok ! $result, "Makefile.PL failed";
+    like $stderr, qr{Foo/Builder.pm}, "custom builder wasn't found";
   }
   
   # Now make sure it can actually work.
-  my $bar_builder = Module::Build->subclass( class => 'Bar::Builder' )->new_from_context;
+  my $bar_builder;
+  stdout_of( sub {
+    $bar_builder = Module::Build->subclass( class => 'Bar::Builder' )->new_from_context;
+  });
   foreach my $style ('passthrough', 'small') {
     Module::Build::Compat->create_makefile_pl($style, $bar_builder);
-    ok -e 'Makefile.PL';
-    ok $mb->run_perl_script('Makefile.PL');
+    ok -e 'Makefile.PL', "$style Makefile.PL created via subclass";
+    my $result;
+    stdout_of( sub {
+      $result = $mb->run_perl_script('Makefile.PL');
+    });
+    ok $result, "Makefile.PL ran without error";
   }
 }
 
@@ -115,33 +143,36 @@ foreach my $type (@makefile_types) {
   Module::Build::Compat->create_makefile_pl('passthrough', $mb);
 
   my $libdir = File::Spec->catdir( $cwd, 't', 'libdir' );
-  my $result = $mb->run_perl_script('Makefile.PL', [],
-                                    [
-                                     "LIB=$libdir",
-                                     'TEST_VERBOSE=1',
-                                     'INSTALLDIRS=perl',
-                                     'POLLUTE=1',
-                                    ]
-                                  );
-  ok $result;
-  ok -e 'Build.PL';
+  my $result;
+  stdout_of( sub {
+    $result = $mb->run_perl_script('Makefile.PL', [],
+      [
+      "LIB=$libdir",
+      'TEST_VERBOSE=1',
+      'INSTALLDIRS=perl',
+      'POLLUTE=1',
+      ]
+    );
+  });
+  ok $result, "passthrough Makefile.PL ran with arguments";
+  ok -e 'Build.PL', "Build.PL generated";
 
   my $new_build = Module::Build->resume();
-  is $new_build->installdirs, 'core';
-  is $new_build->verbose, 1;
-  is $new_build->install_destination('lib'), $libdir;
-  is $new_build->extra_compiler_flags->[0], '-DPERL_POLLUTE';
+  is $new_build->installdirs, 'core', "installdirs is core";
+  is $new_build->verbose, 1, "tests set for verbose";
+  is $new_build->install_destination('lib'), $libdir, "custom libdir";
+  is $new_build->extra_compiler_flags->[0], '-DPERL_POLLUTE', "PERL_POLLUTE set";
 
   # Make sure those switches actually had an effect
   my ($ran_ok, $output);
   $output = stdout_of( sub { $ran_ok = $new_build->do_system(@make, 'test') } );
-  ok $ran_ok;
+  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';
 
   # Make sure various Makefile arguments are supported
   $output = stdout_of( sub { $ran_ok = $mb->do_system(@make, 'test', 'TEST_VERBOSE=0') } );
-  ok $ran_ok;
+  ok $ran_ok, "make test without verbose ran ok";
   $output =~ s/^/# /gm;  # Don't confuse our own test output
   like $output, qr/(?:# .+basic\.+ok\s+(?:[\d.]+\s*m?s\s*)?)# All tests/,
       'Should be non-verbose';
@@ -149,11 +180,11 @@ foreach my $type (@makefile_types) {
   $mb->delete_filetree($libdir);
   ok ! -e $libdir, "Sample installation directory should be cleaned up";
 
-  $mb->do_system(@make, 'realclean');
+  stdout_of( sub { $mb->do_system(@make, 'realclean'); } );
   ok ! -e 'Makefile', "Makefile shouldn't exist";
 
   1 while unlink 'Makefile.PL';
-  ok ! -e 'Makefile.PL';
+  ok ! -e 'Makefile.PL', "Makefile.PL cleaned up";
 }
 
 { # Make sure tilde-expansion works
@@ -163,29 +194,148 @@ foreach my $type (@makefile_types) {
 
   Module::Build::Compat->create_makefile_pl('passthrough', $mb);
 
-  $mb->run_perl_script('Makefile.PL', [], ['INSTALL_BASE=~/foo']);
+  stdout_of( sub {
+    $mb->run_perl_script('Makefile.PL', [], ['INSTALL_BASE=~/foo']);
+  });
   my $b2 = Module::Build->current;
-  ok $b2->install_base;
+  ok $b2->install_base, "install_base set";
   unlike $b2->install_base, qr/^~/, "Tildes should be expanded";
   
-  $mb->do_system(@make, 'realclean');
+  stdout_of( sub { $mb->do_system(@make, 'realclean'); } );
+  ok ! -e 'Makefile', "Makefile shouldn't exist";
+
   1 while unlink 'Makefile.PL';
+  ok ! -e 'Makefile.PL', "Makefile.PL cleaned up";
 }
+
 #########################################################
 
+sub test_makefile_types {
+  my %opts = @_;
+  $opts{requires} ||= {};
+
+  foreach my $type (@makefile_types) {
+    # Create M::B instance 
+    my $mb;
+    stdout_of( sub {
+        $mb = Module::Build->new_from_context;
+    });
+    ok $mb, "Module::Build->new_from_context";
+
+    # Create and test Makefile.PL
+    Module::Build::Compat->create_makefile_pl($type, $mb);
+    ok -e 'Makefile.PL', "$type Makefile.PL created";
+    test_makefile_pl_requires_perl( $opts{requires}{perl} );
+    test_makefile_creation($mb);
+    test_makefile_prereq_pm( $opts{requires} );
+      
+    my ($output,$success);
+    # Capture output to keep our STDOUT clean
+    $output = stdout_of( sub {
+      $success = $mb->do_system(@make);
+    });
+    ok $success, "make ran without error";
+
+    # Can't let 'test' STDOUT go to our STDOUT, or it'll confuse Test::Harness.
+    $output = stdout_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 {
+      $success = $mb->do_system(@make, 'realclean');
+    });
+    ok $success, "make realclean ran without error";
+
+    # Try again with some Makefile.PL arguments
+    test_makefile_creation($mb, [], 'INSTALLDIRS=vendor', 1);
+    
+    1 while unlink 'Makefile.PL';
+    ok ! -e 'Makefile.PL', "cleaned up Makefile";
+  }
+}
+
 sub test_makefile_creation {
   my ($build, $preargs, $postargs, $cleanup) = @_;
   
-  my $result = $build->run_perl_script('Makefile.PL', $preargs, $postargs);
-  ok $result;
-  ok -e 'Makefile', "Makefile should exist";
+  my ($output, $result);
+  # capture output to avoid polluting our test output
+  $output = stdout_of( sub {
+      $result = $build->run_perl_script('Makefile.PL', $preargs, $postargs);
+  });
+  my $label = "Makefile.PL ran without error";
+  if ( defined $postargs && length $postargs ) {
+    $label .= " (postargs: $postargs)";
+  }
+  ok $result, $label;
+  ok -e 'Makefile', "Makefile exists";
   
   if ($cleanup) {
-    $build->do_system(@make, 'realclean');
-    ok ! -e 'Makefile', "Makefile shouldn't exist";
+    $output = stdout_of( sub {
+      $build->do_system(@make, 'realclean');
+    });
+    ok ! -e 'Makefile', "Makefile cleaned up";
+  }
+  else {
+    pass '(skipping cleanup)'; # keep test count constant
   }
 }
 
+sub test_makefile_prereq_pm {
+  my %requires = %{ $_[0] };
+  delete $requires{perl}; # until EU::MM supports this
+  SKIP: {
+    skip 'Makefile not found', 1 unless -e 'Makefile';
+    my $prereq_pm = find_makefile_prereq_pm();
+    is_deeply $prereq_pm, \%requires,
+      "Makefile has correct PREREQ_PM line";
+  }
+}
+
+sub test_makefile_pl_requires_perl {
+  my $perl_version = shift || q{};
+  SKIP: {
+    skip 'Makefile.PL not found', 1 unless -e 'Makefile.PL';
+    my $file_contents = slurp 'Makefile.PL';
+    my $found_requires = $file_contents =~ m{^require $perl_version;}ms;
+    if (length $perl_version) {
+      ok $found_requires, "Makefile.PL has 'require $perl_version;'"
+        or diag "Makefile.PL:\n$file_contents";
+    }
+    else {
+      ok ! $found_requires, "Makefile.PL does not require a perl version";
+    }
+  }
+}
+
+# Following subroutine adapted from code in CPAN.pm 
+# by Andreas Koenig and A. Speer.
+sub find_makefile_prereq_pm {
+  my $fh = IO::File->new( 'Makefile', 'r' ) 
+    or die "Can't read Makefile: $!";
+  my $req = {};
+  local($/) = "\n";
+  while (<$fh>) {
+    # locate PREREQ_PM
+    last if /MakeMaker post_initialize section/;
+    my($p) = m{^[\#]
+      \s+PREREQ_PM\s+=>\s+(.+)
+    }x;
+    next unless $p;
+
+    # extract modules
+    while ( $p =~ m/(?:\s)([\w\:]+)=>(q\[.*?\]|undef),?/g ){
+      my($m,$n) = ($1,$2);
+      if ($n =~ /^q\[(.*?)\]$/) {
+        $n = $1;
+      }
+      $req->{$m} = $n;
+    }
+    last;
+  }
+  return $req;
+}
 
 # cleanup
 chdir( $cwd ) or die "Can''t chdir to '$cwd': $!";
index 286687e..e3b4173 100644 (file)
@@ -6,7 +6,7 @@ use MBTest tests => 113;
 
 use Cwd ();
 my $cwd = Cwd::cwd;
-my $tmp = File::Spec->catdir( $cwd, 't', '_tmp' );
+my $tmp = MBTest->tmpdir;
 
 use DistGen;
 my $dist = DistGen->new( dir => $tmp );
@@ -16,7 +16,7 @@ chdir( $dist->dirname ) or die "Can't chdir to '@{[$dist->dirname]}': $!";
 
 
 use Config;
-use File::Spec::Functions qw( catdir splitdir splitpath );
+use File::Spec::Functions qw( catdir splitdir );
 
 #########################
 
@@ -300,12 +300,10 @@ sub have_same_ending {
   my ($dir1, $dir2, $message) = @_;
 
   $dir1 =~ s{/$}{} if $^O eq 'cygwin'; # remove any trailing slash
-  my (undef, $dirs1, undef) = splitpath $dir1;
-  my @dir1 = splitdir $dirs1;
+  my @dir1 = splitdir $dir1;
 
   $dir2 =~ s{/$}{} if $^O eq 'cygwin'; # remove any trailing slash
-  my (undef, $dirs2, undef) = splitpath $dir2;
-  my @dir2 = splitdir $dirs2;
+  my @dir2 = splitdir $dir2;
 
   is $dir1[-1], $dir2[-1], $message;
 }
index 924c9db..a6e27e4 100644 (file)
@@ -6,7 +6,7 @@ use MBTest tests => 65;
 
 use Cwd ();
 my $cwd = Cwd::cwd;
-my $tmp = File::Spec->catdir( $cwd, 't', '_tmp' );
+my $tmp = MBTest->tmpdir;
 
 use DistGen;
 my $dist = DistGen->new( dir => $tmp );
index ef209d0..eac96b7 100644 (file)
@@ -6,7 +6,7 @@ use MBTest tests => 6;
 
 use Cwd ();
 my $cwd = Cwd::cwd;
-my $tmp = File::Spec->catdir( $cwd, 't', '_tmp' );
+my $tmp = MBTest->tmpdir;
 
 use DistGen;
 my $dist = DistGen->new( dir => $tmp );
index ba42514..ef43e12 100644 (file)
@@ -8,7 +8,7 @@ use Cwd ();
 use File::Path ();
 
 my $cwd = Cwd::cwd();
-my $tmp = File::Spec->catdir($cwd, 't', '_tmp');
+my $tmp = MBTest->tmpdir;
 
 use DistGen;
 
index bfb8f47..397dfe6 100644 (file)
@@ -6,7 +6,7 @@ use MBTest tests => 34;
 
 use Cwd ();
 my $cwd = Cwd::cwd;
-my $tmp = File::Spec->catdir( $cwd, 't', '_tmp' );
+my $tmp = MBTest->tmpdir;
 
 use DistGen;
 my $dist = DistGen->new( dir => $tmp );
@@ -24,17 +24,13 @@ $dist->add_file( 'script', <<'---' );
 #!perl -w
 print "Hello, World!\n";
 ---
-$dist->change_file( 'Build.PL', <<"---" );
-use Module::Build;
-
-my \$build = new Module::Build(
-  module_name => @{[$dist->name]},
+$dist->change_build_pl
+({
+  module_name => $dist->name,
   scripts     => [ 'script' ],
   license     => 'perl',
   requires    => { 'File::Spec' => 0 },
-);
-\$build->create_build_script;
----
+});
 $dist->regen;
 
 
@@ -60,7 +56,7 @@ my $mb = Module::Build->new_from_context(
 ok $mb;
 
 
-my $destdir = File::Spec->catdir($cwd, 't', 'install_test');
+my $destdir = File::Spec->catdir($cwd, 't', 'install_test.' . $$);
 $mb->add_to_cleanup($destdir);
 
 {
index 5341f44..91f7c33 100644 (file)
@@ -2,7 +2,7 @@ package DistGen;
 
 use strict;
 
-use vars qw( $VERSION $VERBOSE );
+use vars qw( $VERSION $VERBOSE @EXPORT_OK);
 
 $VERSION = '0.01';
 $VERBOSE = 0;
@@ -15,6 +15,7 @@ use File::Path ();
 use File::Spec ();
 use IO::File ();
 use Tie::CPHash;
+use Data::Dumper;
 
 BEGIN {
     if( $^O eq 'VMS' ) {
@@ -23,6 +24,13 @@ BEGIN {
         VMS::Filespec->import;
     }
 }
+BEGIN {
+  require Exporter;
+  *{import} = \&Exporter::import;
+  @EXPORT_OK = qw(
+    undent
+  );
+}
 
 sub new {
   my $package = shift;
@@ -52,134 +60,150 @@ sub new {
   return $self;
 }
 
+# not a method
+sub undent {
+  my ($string) = @_;
+
+  my ($space) = $string =~ m/^(\s+)/;
+  $string =~ s/^$space//gm;
+
+  return($string);
+}
 
 sub _gen_default_filedata {
   my $self = shift;
 
-  $self->add_file( 'Build.PL', <<"---" ) unless $self->{filedata}{'Build.PL'};
-use strict;
-use Module::Build;
+  # TODO maybe a public method like this (but with a better name?)
+  my $add_unless = sub {
+    my $self = shift;
+    my ($member, $data) = @_;
+    $self->add_file($member, $data) unless($self->{filedata}{$member});
+  };
+
+  $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();
+    ---
 
   my $module_filename =
     join( '/', ('lib', split(/::/, $self->{name})) ) . '.pm';
 
   unless ( $self->{xs} ) {
-    $self->add_file( $module_filename, <<"---" ) unless $self->{filedata}{$module_filename};
-package $self->{name};
+    $self->$add_unless($module_filename, undent(<<"      ---"));
+      package $self->{name};
 
-use vars qw( \$VERSION );
-\$VERSION = '0.01';
+      use vars qw( \$VERSION );
+      \$VERSION = '0.01';
 
-use strict;
+      use strict;
 
-1;
+      1;
 
-__END__
+      __END__
 
-=head1 NAME
+      =head1 NAME
 
-$self->{name} - Perl extension for blah blah blah
+      $self->{name} - Perl extension for blah blah blah
 
-=head1 DESCRIPTION
+      =head1 DESCRIPTION
 
-Stub documentation for $self->{name}.
+      Stub documentation for $self->{name}.
 
-=head1 AUTHOR
+      =head1 AUTHOR
 
-A. U. Thor, a.u.thor\@a.galaxy.far.far.away
+      A. U. Thor, a.u.thor\@a.galaxy.far.far.away
 
-=cut
----
+      =cut
+      ---
 
-  $self->add_file( 't/basic.t', <<"---" ) unless $self->{filedata}{'t/basic.t'};
-use Test::More tests => 1;
-use strict;
+  $self->$add_unless('t/basic.t', undent(<<"    ---"));
+    use Test::More tests => 1;
+    use strict;
 
-use $self->{name};
-ok 1;
----
+    use $self->{name};
+    ok 1;
+    ---
 
   } else {
-    $self->add_file( $module_filename, <<"---" ) unless $self->{filedata}{$module_filename};
-package $self->{name};
+    $self->$add_unless($module_filename, undent(<<"      ---"));
+      package $self->{name};
 
-\$VERSION = '0.01';
+      \$VERSION = '0.01';
 
-require Exporter;
-require DynaLoader;
+      require Exporter;
+      require DynaLoader;
 
-\@ISA = qw(Exporter DynaLoader);
-\@EXPORT_OK = qw( okay );
+      \@ISA = qw(Exporter DynaLoader);
+      \@EXPORT_OK = qw( okay );
 
-bootstrap $self->{name} \$VERSION;
+      bootstrap $self->{name} \$VERSION;
 
-1;
+      1;
 
-__END__
+      __END__
 
-=head1 NAME
+      =head1 NAME
 
-$self->{name} - Perl extension for blah blah blah
+      $self->{name} - Perl extension for blah blah blah
 
-=head1 DESCRIPTION
+      =head1 DESCRIPTION
 
-Stub documentation for $self->{name}.
+      Stub documentation for $self->{name}.
 
-=head1 AUTHOR
+      =head1 AUTHOR
 
-A. U. Thor, a.u.thor\@a.galaxy.far.far.away
+      A. U. Thor, a.u.thor\@a.galaxy.far.far.away
 
-=cut
----
+      =cut
+      ---
 
     my $xs_filename =
       join( '/', ('lib', split(/::/, $self->{name})) ) . '.xs';
-    $self->add_file( $xs_filename, <<"---" ) unless $self->{filedata}{$xs_filename};
-#include "EXTERN.h"
-#include "perl.h"
-#include "XSUB.h"
-
-MODULE = $self->{name}         PACKAGE = $self->{name}
-
-SV *
-okay()
-    CODE:
-        RETVAL = newSVpv( "ok", 0 );
-    OUTPUT:
+    $self->$add_unless($xs_filename, undent(<<"      ---"));
+      #include "EXTERN.h"
+      #include "perl.h"
+      #include "XSUB.h"
+
+      MODULE = $self->{name}         PACKAGE = $self->{name}
+
+      SV *
+      okay()
+          CODE:
+              RETVAL = newSVpv( "ok", 0 );
+          OUTPUT:
+              RETVAL
+
+      char *
+      xs_version()
+          CODE:
+        RETVAL = XS_VERSION;
+          OUTPUT:
         RETVAL
 
-char *
-xs_version()
-    CODE:
-       RETVAL = XS_VERSION;
-    OUTPUT:
-       RETVAL
-
-char *
-version()
-    CODE:
-       RETVAL = VERSION;
-    OUTPUT:
-       RETVAL
----
-
-  $self->add_file( 't/basic.t', <<"---" ) unless $self->{filedata}{'t/basic.t'};
-use Test::More tests => 2;
-use strict;
+      char *
+      version()
+          CODE:
+        RETVAL = VERSION;
+          OUTPUT:
+        RETVAL
+      ---
 
-use $self->{name};
-ok 1;
+  $self->$add_unless('t/basic.t', undent(<<"    ---"));
+    use Test::More tests => 2;
+    use strict;
 
-ok( $self->{name}::okay() eq 'ok' );
----
+    use $self->{name};
+    ok 1;
+
+    ok( $self->{name}::okay() eq 'ok' );
+    ---
   }
 }
 
@@ -357,6 +381,22 @@ sub remove_file {
   $self->{pending}{remove}{$file} = 1;
 }
 
+sub change_build_pl {
+  my ($self, $opts) = @_;
+
+  local $Data::Dumper::Terse = 1;
+  (my $args = Dumper($opts)) =~ s/^\s*\{|\}\s*$//g;
+
+  $self->change_file( 'Build.PL', undent(<<"    ---") );
+    use strict;
+    use Module::Build;
+    my \$b = Module::Build->new(
+    $args
+    );
+    \$b->create_build_script();
+    ---
+}
+
 sub change_file {
   my $self = shift;
   my $file = shift;
@@ -374,92 +414,122 @@ __END__
 
 DistGen - Creates simple distributions for testing.
 
+=head1 SYNOPSIS
 
-=head1 DESCRIPTION
+  use DistGen;
 
+  my $dist = DistGen->new(dir => $tmp);
+  ...
+  $dist->add_file('t/some_test.t', $contents);
+  ...
+  $dist->regen;
 
+  chdir($dist->dirname) or
+    die "Cannot chdir to '@{[$dist->dirname]}': $!";
+  ...
+  $dist->clean;
+  ...
+  chdir($cwd) or die "cannot return to $cwd";
+  $dist->remove;
 
 =head1 API
 
-
 =head2 Constructor
 
 =head3 new()
 
-Create a new distribution generator. Does not actually write the
-contents.
+Create a new object.  Does not write its contents (see L</regen()>.)
+
+  my $tmp = MBTest->tmpdir;
+  my $dist = DistGen->new(
+    name => 'Foo::Bar',
+    dir  => $tmp,
+    xs   => 1,
+  );
+
+The parameters are as follows.
 
 =over
 
 =item name
 
 The name of the module this distribution represents. The default is
-'Simple'.
+'Simple'.  This should be a "Foo::Bar" (module) name, not a "Foo-Bar"
+dist name.
 
 =item dir
 
-The directory in which to create the distribution directory. The
-default is File::Spec->curdir.
+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".)
 
 =item xs
 
-Generates an XS based module.
+If true, generates an XS based module.
 
 =back
 
-
 =head2 Manipulating the Distribution
 
-=head3 regen( [OPTIONS] )
-
-Regenerate all files that are missing or that have changed. If the
-optional C<clean> argument is given, it also removes any extraneous
-files that do not belong to the distribution.
+These methods immediately affect the filesystem.
 
-=over
+=head3 regen()
 
-=item clean
+Regenerate all missing or changed files.
 
-When true, removes any files not part of the distribution while
-regenerating.
+  $dist->regen(clean => 1);
 
-=back
+If the optional C<clean> argument is given, it also removes any
+extraneous files that do not belong to the distribution.
 
 =head3 clean()
 
 Removes any files that are not part of the distribution.
 
-=head3 revert( [$filename] )
+  $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);
+
+=end TODO
 
-Removes the complete distribution.
+=head3 remove()
 
+Removes the entire distribution directory.
 
 =head2 Editing Files
 
-Note that all ${filename}s should be specified with unix-style paths,
+Note that C<$filename> should always be specified with unix-style paths,
 and are relative to the distribution root directory. Eg 'lib/Module.pm'
 
-=head3 add_file( $filename, $content )
+No filesystem action is performed until the distribution is regenerated.
+
+=head3 add_file()
+
+Add a $filename containing $content to the distribution.
+
+  $dist->add_file( $filename, $content );
 
-Add a $filename containg $content to the distribution. No action is
-performed until the distribution is regenerated.
+=head3 remove_file()
 
-=head3 remove_file( $filename )
+Removes C<$filename> from the distribution.
 
-Removes $filename from the distribution. No action is performed until
-the distribution is regenerated.
+  $dist->remove_file( $filename );
 
-=head3 change_file( $filename, $content )
+=head3 change_file()
 
 Changes the contents of $filename to $content. No action is performed
 until the distribution is regenerated.
 
+  $dist->change_file( $filename, $content );
 
 =head2 Properties
 
@@ -469,6 +539,22 @@ Returns the name of the distribution.
 
 =head3 dirname()
 
-Returns the directory name where the distribution is created.
+Returns the directory where the distribution is created.
+
+  $dist->dirname; # e.g. t/_tmp/Simple
+
+=head2 Functions
+
+=head3 undent()
+
+Removes leading whitespace from a multi-line string according to the
+amount of whitespace on the first line.
+
+  my $string = undent("  foo(\n    bar => 'baz'\n  )");
+  $string eq "foo(
+    bar => 'baz'
+  )";
 
 =cut
+
+# vim:ts=2:sw=2:et:sta
index f25c840..6764daf 100644 (file)
@@ -3,6 +3,7 @@ package MBTest;
 use strict;
 
 use File::Spec;
+use File::Path ();
 
 BEGIN {
   # Make sure none of our tests load the users ~/.modulebuildrc file
@@ -13,7 +14,7 @@ BEGIN {
   # Test::More" in the test script.
   my $t_lib = File::Spec->catdir('t', 'bundled');
 
-  if (!$ENV{PERL_CORE}) {
+  unless ($ENV{PERL_CORE}) {
     push @INC, $t_lib; # Let user's installed version override
   } else {
     # We change directories, so expand @INC to absolute paths
@@ -34,6 +35,7 @@ BEGIN {
 use Exporter;
 use Test::More;
 use Config;
+use Cwd ();
 
 # We pass everything through to Test::More
 use vars qw($VERSION @ISA @EXPORT %EXPORT_TAGS $TODO);
@@ -44,17 +46,50 @@ $VERSION = 0.01;
 
 # We have a few extra exports, but Test::More has a special import()
 # that won't take extra additions.
-my @extra_exports = qw(stdout_of stderr_of slurp find_in_path check_compiler have_module);
+my @extra_exports = qw(
+  stdout_of
+  stderr_of
+  stdout_stderr_of
+  slurp
+  find_in_path
+  check_compiler
+  have_module
+);
 push @EXPORT, @extra_exports;
 __PACKAGE__->export(scalar caller, @extra_exports);
+# XXX ^-- that should really happen in import()
+########################################################################
+
+{ # Setup a temp directory if it doesn't exist
+  my $cwd = Cwd::cwd;
+  my $tmp = File::Spec->catdir( $cwd, 't', '_tmp.' . $$);
+  mkdir $tmp, 0777 unless -d $tmp;
+
+  sub tmpdir { $tmp }
+  END {
+    if(-d $tmp) {
+      File::Path::rmtree($tmp) or warn "cannot clean dir '$tmp'";
+    }
+  }
+}
+########################################################################
 
+{ # backwards compatible temp filename recipe adapted from perlfaq
+  my $tmp_count = 0;
+  my $tmp_base_name = sprintf("%d-%d", $$, time());
+  sub temp_file_name {
+    sprintf("%s-%04d", $tmp_base_name, ++$tmp_count)
+  }
+}
+########################################################################
 
 sub save_handle {
   my ($handle, $subr) = @_;
-  my $outfile = 'save_out';
+  my $outfile = temp_file_name();
 
   local *SAVEOUT;
-  open SAVEOUT, ">&" . fileno($handle) or die "Can't save output handle: $!";
+  open SAVEOUT, ">&" . fileno($handle)
+    or die "Can't save output handle: $!";
   open $handle, "> $outfile" or die "Can't create $outfile: $!";
 
   eval {$subr->()};
@@ -67,6 +102,14 @@ sub save_handle {
 
 sub stdout_of { save_handle(\*STDOUT, @_) }
 sub stderr_of { save_handle(\*STDERR, @_) }
+sub stdout_stderr_of {
+  my $subr = shift;
+  my ($stdout, $stderr);
+  $stdout = stdout_of ( sub {
+      $stderr = stderr_of( $subr )
+  });
+  return ($stdout, $stderr);
+}
 
 sub slurp {
   my $fh = IO::File->new($_[0]) or die "Can't open $_[0]: $!";
@@ -74,8 +117,8 @@ sub slurp {
   return scalar <$fh>;
 }
 
+# Some extensions we should know about if we're looking for executables
 sub exe_exts {
-  # Some extensions we should know about if we're looking for executables
 
   if ($^O eq 'MSWin32') {
     return split($Config{path_sep}, $ENV{PATHEXT} || '.com;.exe;.bat');
@@ -121,3 +164,4 @@ sub have_module {
 }
 
 1;
+# vim:ts=2:sw=2:et:sta
index cf8aa50..b3b8084 100644 (file)
@@ -17,7 +17,7 @@ if ( Module::Build::ConfigData->feature('manpage_support') ) {
 
 use Cwd ();
 my $cwd = Cwd::cwd;
-my $tmp = File::Spec->catdir( $cwd, 't', '_tmp' );
+my $tmp = MBTest->tmpdir;
 
 use DistGen;
 my $dist = DistGen->new( dir => $tmp );
@@ -58,7 +58,7 @@ $dist->regen;
 chdir( $dist->dirname ) or die "Can't chdir to '@{[$dist->dirname]}': $!";
 
 use File::Spec::Functions qw( catdir );
-my $destdir = catdir($cwd, 't', 'install_test');
+my $destdir = catdir($cwd, 't', 'install_test.' . $$);
 
 
 my $mb = Module::Build->new(
@@ -118,7 +118,7 @@ while (my ($from, $v) = each %distro) {
     next;
   }
   
-  my $to = File::Spec->catfile('blib', ($from =~ /^[\.\/\[]*lib/ ? 'libdoc' : 'bindoc'), $v);
+  my $to = File::Spec->catfile('blib', ($from =~ /^lib/ ? 'libdoc' : 'bindoc'), $v);
   ok $mb->contains_pod($from), "$from should contain POD";
   ok -e $to, "Created $to manpage";
 }
index 0d13e85..00eebe5 100644 (file)
@@ -2,32 +2,33 @@
 
 use strict;
 use lib $ENV{PERL_CORE} ? '../lib/Module/Build/t/lib' : 't/lib';
-use MBTest tests => 47;
+use MBTest tests => 49;
 
 use Cwd ();
 my $cwd = Cwd::cwd;
-my $tmp = File::Spec->catdir( $cwd, 't', '_tmp' );
+my $tmp = MBTest->tmpdir;
 
 
 use Module::Build;
 use Module::Build::ConfigData;
-my $has_YAML = Module::Build::ConfigData->feature('YAML_support');
+
+my %metadata = 
+  (
+   module_name   => 'Simple',
+   dist_version  => '3.14159265',
+   dist_author   => [ 'Simple Simon <ss\@somewhere.priv>' ],
+   dist_abstract => 'Something interesting',
+   license       => 'perl',
+   meta_add => {
+               keywords  => [qw(super duper something)],
+               resources => {homepage => 'http://foo.example.com'},
+              },
+  );
 
 
 use DistGen;
 my $dist = DistGen->new( dir => $tmp );
-$dist->change_file( 'Build.PL', <<"---" );
-
-my \$builder = Module::Build->new(
-    module_name   => '@{[$dist->name]}',
-    dist_version  => '3.14159265',
-    dist_author   => [ 'Simple Simon <ss\@somewhere.priv>' ],
-    dist_abstract => 'Something interesting',
-    license       => 'perl',
-);
-
-\$builder->create_build_script();
----
+$dist->change_build_pl( \%metadata );
 $dist->regen;
 
 my $simple_file = 'lib/Simple.pm';
@@ -53,28 +54,22 @@ my $mb = Module::Build->new_from_context;
 #
 # Test for valid META.yml
 
-SKIP: {
-  skip( 'YAML_support feature is not enabled', 8 ) unless $has_YAML;
-
-  require YAML;
-  require YAML::Node;
-  my $node = YAML::Node->new({});
-  $node = $mb->prepare_metadata( $node );
+{
+  my $node = $mb->prepare_metadata( {} );
 
   # exists() doesn't seem to work here
-  ok defined( $node->{name} ),     "'name' field present in META.yml";
-  ok defined( $node->{version} ),  "'version' field present in META.yml";
-  ok defined( $node->{abstract} ), "'abstract' field present in META.yml";
-  ok defined( $node->{author} ),   "'author' field present in META.yml";
-  ok defined( $node->{license} ),  "'license' field present in META.yml";
-  ok defined( $node->{generated_by} ),
-      "'generated_by' field present in META.yml";
+  is $node->{name}, $metadata{module_name};
+  is $node->{version}, $metadata{dist_version};
+  is $node->{abstract}, $metadata{dist_abstract};
+  is_deeply $node->{author}, $metadata{dist_author};
+  is $node->{license}, $metadata{license};
+  like $node->{generated_by}, qr{Module::Build};
   ok defined( $node->{'meta-spec'}{version} ),
       "'meta-spec' -> 'version' field present in META.yml";
   ok defined( $node->{'meta-spec'}{url} ),
       "'meta-spec' -> 'url' field present in META.yml";
-
-  # TODO : find a way to test for failure when above fields are not present
+  is_deeply $node->{keywords}, $metadata{meta_add}{keywords};
+  is_deeply $node->{resources}, $metadata{meta_add}{resources};
 }
 
 $dist->clean;
index ecb0161..1ca4508 100644 (file)
@@ -6,7 +6,7 @@ use MBTest tests => 18;
 
 use Cwd ();
 my $cwd = Cwd::cwd;
-my $tmp = File::Spec->catdir( $cwd, 't', '_tmp' );
+my $tmp = MBTest->tmpdir;
 
 use Module::Build;
 use Module::Build::ConfigData;
@@ -65,17 +65,13 @@ Simple Simon <simon@simple.sim>
 
 my $dist = DistGen->new( dir => $tmp );
 
-$dist->change_file( 'Build.PL', <<"---" );
-use Module::Build;
-my \$builder = Module::Build->new(
-    module_name         => '@{[$dist->name]}',
+$dist->change_build_pl
+({
+    module_name         => $dist->name,
     dist_version        => '3.14159265',
     license             => 'perl',
     create_readme       => 1,
-);
-
-\$builder->create_build_script();
----
+});
 $dist->regen;
 
 chdir( $dist->dirname ) or die "Can't chdir to '@{[$dist->dirname]}': $!";
index a97cac5..56838e4 100644 (file)
@@ -6,7 +6,7 @@ use MBTest tests => 81;
 
 use Cwd ();
 my $cwd = Cwd::cwd;
-my $tmp = File::Spec->catdir( $cwd, 't', '_tmp' );
+my $tmp = MBTest->tmpdir;
 
 use DistGen;
 my $dist = DistGen->new( dir => $tmp );
index b623e1f..abdc079 100644 (file)
@@ -6,7 +6,7 @@ use MBTest tests => 2;
 
 use Cwd ();
 my $cwd = Cwd::cwd;
-my $tmp = File::Spec->catdir( $cwd, 't', '_tmp' );
+my $tmp = MBTest->tmpdir;
 
 use DistGen;
 my $dist = DistGen->new( dir => $tmp );
index dd32464..94958cb 100644 (file)
@@ -6,7 +6,7 @@ use MBTest tests => 11;
 
 use Cwd ();
 my $cwd = Cwd::cwd;
-my $tmp = File::Spec->catdir( $cwd, 't', '_tmp' );
+my $tmp = MBTest->tmpdir;
 
 use DistGen;
 my $dist = DistGen->new( dir => $tmp );
index 09d06ff..afc11e1 100644 (file)
@@ -28,7 +28,7 @@ my $HTML_support = Module::Build::ConfigData->feature('HTML_support');
 
 use Cwd ();
 my $cwd = Cwd::cwd;
-my $tmp = File::Spec->catdir( $cwd, 't', '_tmp' );
+my $tmp = MBTest->tmpdir;
 
 
 use DistGen;
@@ -50,16 +50,12 @@ Says "Hello"
 
 =cut
 ---
-$dist->change_file( 'Build.PL', <<"---" );
-
-my \$build = new Module::Build(
-  module_name => @{[$dist->name]},
+$dist->change_build_pl
+({
+  module_name => $dist->name,
   license     => 'perl',
   scripts     => [ 'hello' ],
-);
-
-\$build->create_build_script;
----
+});
 $dist->regen;
 
 chdir( $dist->dirname ) or die "Can't chdir to '@{[$dist->dirname]}': $!";
index a1756dd..3fa09d5 100644 (file)
@@ -12,22 +12,19 @@ my $have_yaml = Module::Build::ConfigData->feature('YAML_support');
 
 use Cwd ();
 my $cwd = Cwd::cwd;
-my $tmp = File::Spec->catdir( $cwd, 't', '_tmp' );
+my $tmp = MBTest->tmpdir;
 
 use DistGen;
 my $dist = DistGen->new( dir => $tmp );
 $dist->remove_file( 't/basic.t' );
-$dist->change_file( 'Build.PL', <<'---' );
-use Module::Build;
-
-my $build = new Module::Build(
+$dist->change_build_pl
+({
   module_name => 'Simple',
   scripts     => [ 'script' ],
   license     => 'perl',
   requires    => { 'File::Spec' => 0 },
-);
-$build->create_build_script;
----
+});
+
 $dist->add_file( 'script', <<'---' );
 #!perl -w
 print "Hello, World!\n";
@@ -171,11 +168,11 @@ SKIP: {
   my $blib_script = File::Spec->catfile( qw( blib script script ) );
   ok -e $blib_script;
   
-  SKIP: {
+ SKIP: {
     skip("We do not rewrite shebang on VMS", 1) if $^O eq 'VMS';
-  my $fh = IO::File->new($blib_script);
-  my $first_line = <$fh>;
-  isnt $first_line, "#!perl -w\n", "should rewrite the shebang line";
+    my $fh = IO::File->new($blib_script);
+    my $first_line = <$fh>;
+    isnt $first_line, "#!perl -w\n", "should rewrite the shebang line";
   }
 }
 
@@ -221,15 +218,12 @@ echo Hello, World!
 ---
 
   $dist = DistGen->new( dir => $tmp );
-  $dist->change_file( 'Build.PL', <<'---' );
-use Module::Build;
-my $build = new Module::Build(
-  module_name => 'Simple',
-  scripts     => [ 'bin/script.bat' ],
-  license     => 'perl',
-);
-$build->create_build_script;
----
+  $dist->change_build_pl({
+                         module_name => 'Simple',
+                         scripts     => [ 'bin/script.bat' ],
+                         license     => 'perl',
+                        });
+
   $dist->add_file( 'bin/script.bat', $script_data );
 
   $dist->regen;
index 5608d6e..dcc2ef9 100644 (file)
@@ -6,7 +6,7 @@ use MBTest tests => 8;
 
 use Cwd ();
 my $cwd = Cwd::cwd;
-my $tmp = File::Spec->catdir( $cwd, 't', '_tmp' );
+my $tmp = MBTest->tmpdir;
 
 use DistGen;
 
index 86bb0df..143efdd 100644 (file)
@@ -6,7 +6,7 @@ use MBTest tests => 14 + 12;
 
 use Cwd ();
 my $cwd = Cwd::cwd();
-my $tmp = File::Spec->catdir($cwd, 't', '_tmp');
+my $tmp = MBTest->tmpdir;
 
 use DistGen;
 
index 95ebe98..bf16152 100644 (file)
@@ -4,11 +4,11 @@
 
 use strict;
 use lib $ENV{PERL_CORE} ? '../lib/Module/Build/t/lib' : 't/lib';
-use MBTest tests => 14;
+use MBTest tests => 15;
 
 use Cwd ();
 my $cwd = Cwd::cwd;
-my $tmp = File::Spec->catdir( $cwd, 't', '_tmp' );
+my $tmp = MBTest->tmpdir;
 
 use DistGen;
 my $dist = DistGen->new( dir => $tmp );
@@ -35,56 +35,58 @@ sub run_sample {
 }
 
 
-{
-    local $ENV{HOME} = 'home';
+my $p = 'install_base';
 
-    my $mb;
-
-    $mb = run_sample( install_base => '~' );
-    is( $mb->install_base,      $ENV{HOME} );
-
-    $mb = run_sample( install_base => '~/foo' );
-    is( $mb->install_base,      "$ENV{HOME}/foo" );
+SKIP: {
+    my $home = $ENV{HOME} ? $ENV{HOME} : undef;
+    unless (defined $home) {
+      my @info = eval { getpwuid $> };
+      skip "No home directory for tilde-expansion tests", 14 if $@;
+      $home = $info[7];
+    }
 
-    $mb = run_sample( install_base => '~~' );
-    is( $mb->install_base,      '~~' );
+    is( run_sample( $p => '~'     )->$p(),  $home );
 
-  TODO: {
-    local $TODO = "Not handling spaces in _detildefy() properly yet";
+    is( run_sample( $p => '~/foo' )->$p(),  "$home/foo" );
 
-    $mb = run_sample( install_base => '~ foo' );
-    is( $mb->install_base,      '~ foo' );
+    is( run_sample( $p => '~~'    )->$p(),  '~~' );
 
-    # glob() doesn't work on non-existent paths with spaces
-    $mb = run_sample( install_base => '~/ foo' );
-    is( $mb->install_base,      "$ENV{HOME}/ foo" );
+    is( run_sample( $p => '~ foo' )->$p(),  '~ foo' );
 
-    $mb = run_sample( install_base => '~/fo o' );
-    is( $mb->install_base,      "$ENV{HOME}/fo o" );
-  }
+    is( run_sample( $p => '~/ foo')->$p(),  "$home/ foo" );
+      
+    is( run_sample( $p => '~/fo o')->$p(),  "$home/fo o" );
 
-    $mb = run_sample( install_base => 'foo~' );
-    is( $mb->install_base,      'foo~' );
+    is( run_sample( $p => 'foo~'  )->$p(),  'foo~' );
 
-    $mb = run_sample( prefix => '~' );
-    is( $mb->prefix,            $ENV{HOME} );
+    is( run_sample( prefix => '~' )->prefix,
+       $home );
 
-    $mb = run_sample( install_path => { html => '~/html',
-                                       lib  => '~/lib'   }
-                    );
-    is( $mb->install_destination('lib'),  "$ENV{HOME}/lib" );
+    my $mb = run_sample( install_path => { html => '~/html',
+                                          lib  => '~/lib'   }
+                      );
+    is( $mb->install_destination('lib'),  "$home/lib" );
     # 'html' is translated to 'binhtml' & 'libhtml'
-    is( $mb->install_destination('binhtml'), "$ENV{HOME}/html" );
-    is( $mb->install_destination('libhtml'), "$ENV{HOME}/html" );
+    is( $mb->install_destination('binhtml'), "$home/html" );
+    is( $mb->install_destination('libhtml'), "$home/html" );
 
     $mb = run_sample( install_path => { lib => '~/lib' } );
-    is( $mb->install_destination('lib'),  "$ENV{HOME}/lib" );
+    is( $mb->install_destination('lib'),  "$home/lib" );
 
     $mb = run_sample( destdir => '~' );
-    is( $mb->destdir,           $ENV{HOME} );
+    is( $mb->destdir,           $home );
+
+    $mb->$p('~');
+    is( $mb->$p(),      '~', 'API does not expand tildes' );
+}
 
-    $mb->install_base('~');
-    is( $mb->install_base,      '~', 'API does not expand tildes' );
+# Again, with named users
+SKIP: {
+    my @info = eval { getpwuid $> };
+    skip "No home directory for tilde-expansion tests", 1 if $@;
+    my ($me, $home) = @info[0,7];
+    
+    is( run_sample( $p => "~$me/foo")->$p(),  "$home/foo" );
 }
 
 
index 3c269c5..e2d66a9 100644 (file)
@@ -6,7 +6,7 @@ use MBTest tests => 2;
 
 use Cwd ();
 my $cwd = Cwd::cwd;
-my $tmp = File::Spec->catdir( $cwd, 't', '_tmp' );
+my $tmp = MBTest->tmpdir;
 
 use DistGen;
 my $dist = DistGen->new( dir => $tmp );
index 9c34b17..2eb0595 100644 (file)
@@ -22,7 +22,7 @@ use Module::Build;
 
 use Cwd ();
 my $cwd = Cwd::cwd;
-my $tmp = File::Spec->catdir( $cwd, 't', '_tmp' );
+my $tmp = MBTest->tmpdir;
 
 use DistGen;
 my $dist = DistGen->new( dir => $tmp, xs => 1 );
@@ -109,7 +109,7 @@ $dist->remove;
 
 # Try a XS distro with a deep namespace
 
-$dist = DistGen->new( name => 'Simple::With::Deep::Name',
+$dist = DistGen->new( name => 'Simple::With::Deep::Namespace',
                      dir => $tmp, xs => 1 );
 $dist->regen;
 chdir( $dist->dirname ) or die "Can't chdir to '@{[$dist->dirname]}': $!";
@@ -141,19 +141,14 @@ $dist = DistGen->new( name => 'Dist-Name', dir => $tmp, xs => 1 );
 $dist->remove_file('lib/Dist-Name.pm');
 $dist->remove_file('lib/Dist-Name.xs');
 
-$dist->change_file('Build.PL', <<"---");
-use strict;
-use Module::Build;
-
-my \$builder = Module::Build->new(
+$dist->change_build_pl
+  ({
     dist_name         => 'Dist-Name',
     dist_version_from => 'Simple.pm',
     pm_files => { 'Simple.pm' => 'lib/Simple.pm' },
     xs_files => { 'Simple.xs' => 'lib/Simple.xs' },
-);
+  });
 
-\$builder->create_build_script();
----
 $dist->add_file('Simple.xs', <<"---");
 #include "EXTERN.h"
 #include "perl.h"