lib/Module/Build/Cookbook.pm Module::Build
lib/Module/Build/ModuleInfo.pm Module::Build
lib/Module/Build/Notes.pm Module::Build
+lib/Module/Build/YAML.pm Module::Build
lib/Module/Build/Platform/aix.pm Module::Build
lib/Module/Build/Platform/Amiga.pm Module::Build
lib/Module/Build/Platform/cygwin.pm Module::Build
lib/Module/Build/t/lib/DistGen.pm Module::Build
lib/Module/Build/t/lib/MBTest.pm Module::Build
lib/Module/Build/t/manifypods.t Module::Build
+lib/Module/Build/t/mbyaml.t Module::Build
lib/Module/Build/t/metadata.t Module::Build
lib/Module/Build/t/metadata2.t Module::Build
lib/Module/Build/t/moduleinfo.t Module::Build
use File::Basename ();
use vars qw($VERSION @ISA);
-$VERSION = '0.17';
+$VERSION = '0.18';
$VERSION = eval $VERSION;
# Okay, this is the brute-force method of finding out what kind of
Revision history for Perl extension ExtUtils::CBuilder.
+0.18 Sat Mar 25 13:35:47 CST 2006
+
+ - Yet more fixes for arg_defines() on VMS. [Craig A. Berry and John
+ E. Malmberg]
+
0.17 Wed Mar 15 22:46:15 CST 2006
- When we're being run from an uninstalled perl distribution
s/"/""/g foreach values %args;
- my $config_defines;
+ my @config_defines;
# VMS can only have one define qualifier; add the one from config, if any.
- if ($self->{config}{ccflags} =~ s{/def[^=]+(?:=)+(?:\()?([^\/\)]*)} {}i) {
- $config_defines = $1;
+ if ($self->{config}{ccflags} =~ s{/ def[^=]+ =+ \(? ([^\/\)]*) } {}ix) {
+ push @config_defines, $1;
}
- return unless (scalar keys %args) || $config_defines;
+ return '' unless keys(%args) || @config_defines;
return ('/define=('
- . (defined $config_defines ? "$config_defines," : '')
. join(',',
+ @config_defines,
map "\"$_" . ( length($args{$_}) ? "=$args{$_}" : '') . "\"",
keys %args)
. ')');
use vars qw($VERSION @ISA);
@ISA = qw(Module::Build::Base);
-$VERSION = '0.27_09';
+$VERSION = '0.27_10';
$VERSION = eval $VERSION;
# Okay, this is the brute-force method of finding out what kind of
=item build
+[version 0.01]
+
If you run the C<Build> script without any arguments, it runs the
C<build> action, which in turn runs the C<code> and C<docs> actions.
This is analogous to the MakeMaker 'make all' target.
-=item testpodcoverage
-
-This checks the pod coverage of the distribution and
-produces C<Test::Harness>-style output. If you are a module author,
-this is useful to run before creating a new release.
-
=item clean
+[version 0.01]
+
This action will clean up any files that the build process may have
created, including the C<blib/> directory (but not including the
C<_build/> directory and the C<Build> script itself).
=item code
+[version 0.20]
+
This action builds your codebase.
By default it just creates a C<blib/> directory and copies any C<.pm>
=item config_data
+[version 0.26]
+
...
=item diff
+[version 0.14]
+
This action will compare the files about to be installed with their
installed counterparts. For .pm and .pod files, a diff will be shown
(this currently requires a 'diff' program to be in your PATH). For
=item dist
+[version 0.02]
+
This action is helpful for module authors who want to package up their
module for source distribution through a medium like CPAN. It will create a
tarball of the files listed in F<MANIFEST> and compress the tarball using
=item distcheck
+[version 0.05]
+
Reports which files are in the build directory but not in the
F<MANIFEST> file, and vice versa. (See L<manifest> for details.)
=item distclean
+[version 0.05]
+
Performs the 'realclean' action and then the 'distcheck' action.
=item distdir
+[version 0.05]
+
Creates a "distribution directory" named C<$dist_name-$dist_version>
(if that directory already exists, it will be removed first), then
copies all the files listed in the F<MANIFEST> file to that directory.
=item distmeta
+[version 0.21]
+
Creates the F<META.yml> file that describes the distribution.
F<META.yml> is a file containing various bits of "metadata" about the
distribution. The metadata includes the distribution name, version,
abstract, prerequisites, license, and various other data about the
-distribution. This file is created as F<META.yml> in YAML format, so
-the C<YAML> module must be installed in order to create it. The
+distribution. This file is created as F<META.yml> in YAML format.
+It is recommended that the C<YAML> module be installed to create it.
+If the C<YAML> module is not installed, an internal module supplied
+with Module::Build will be used to write the META.yml file, and this
+will most likely be fine.
+
F<META.yml> file must also be listed in F<MANIFEST> - if it's not, a
warning will be issued.
=item distsign
+[version 0.16]
+
Uses C<Module::Signature> to create a SIGNATURE file for your
distribution, and adds the SIGNATURE file to the distribution's
MANIFEST.
=item disttest
+[version 0.05]
+
Performs the 'distdir' action, then switches into that directory and
runs a C<perl Build.PL>, followed by the 'build' and 'test' actions in
that directory.
=item docs
+[version 0.20]
+
This will generate documentation (e.g. Unix man pages and html
documents) for any installable items under B<blib/> that
contain POD. If there are no C<bindoc> or C<libdoc> installation
=item fakeinstall
+[version 0.02]
+
This is just like the C<install> action, but it won't actually do
anything, it will just report what it I<would> have done if you had
actually run the C<install> action.
=item help
+[version 0.03]
+
This action will simply print out a message that is meant to help you
use the build process. It will show you a list of available build
actions too.
=item html
+[version 0.26]
+
This will generate HTML documentation for any binary or library files
under B<blib/> that contain POD. The HTML documentation will only be
installed if the install paths can be determined from values in
=item install
+[version 0.01]
+
This action will use C<ExtUtils::Install> to install the files from
C<blib/> into the system. See L<INSTALL PATHS>
for details about how Module::Build determines where to install
=item manifest
+[version 0.05]
+
This is an action intended for use by module authors, not people
installing modules. It will bring the F<MANIFEST> up to date with the
files currently present in the distribution. You may use a
=item manpages
+[version 0.28]
+
This will generate man pages for any binary or library files under
B<blib/> that contain POD. The man pages will only be installed if the
install paths can be determined from values in C<Config.pm>. You can
=item ppd
+[version 0.20]
+
Build a PPD file for your distribution.
This action takes an optional argument C<codebase> which is used in
=item ppmdist
+[version 0.23]
+
Generates a PPM binary distribution and a PPD description file. This
action also invokes the 'ppd' action, so it can accept the same
C<codebase> argument described under that action.
=item prereq_report
+[version 0.28]
+
This action prints out a list of all prerequisites, the versions required, and
the versions actually installed. This can be useful for reviewing the
configuration of your system prior to a build, or when compiling data to send
=item pure_install
+[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
F<$(INSTALLARCHLIB)/perllocal.pod>, C<pure_install> won't, and that
=item realclean
+[version 0.01]
+
This action is just like the C<clean> action, but also removes the
C<_build> directory and the C<Build> script. If you run the
C<realclean> action, you are essentially starting over, so you will
=item skipcheck
+[version 0.05]
+
Reports which files are skipped due to the entries in the
F<MANIFEST.SKIP> file (See L<manifest> for details)
=item test
+[version 0.01]
+
This will use C<Test::Harness> to run any regression tests and report
their results. Tests can be defined in the standard places: a file
called C<test.pl> in the top-level directory, or several files ending
=item testcover
+[version 0.26]
+
Runs the C<test> action using C<Devel::Cover>, generating a
code-coverage report showing which parts of the code were actually
exercised during the tests.
=item testdb
+[version 0.05]
+
This is a synonym for the 'test' action with the C<debugger=1>
argument.
=item testpod
+[version 0.25]
+
This checks all the files described in the C<docs> action and
produces C<Test::Harness>-style output. If you are a module author,
this is useful to run before creating a new release.
+=item testpodcoverage
+
+[version 0.28]
+
+This checks the pod coverage of the distribution and
+produces C<Test::Harness>-style output. If you are a module author,
+this is useful to run before creating a new release.
+
=item versioninstall
+[version 0.16]
+
** Note: since C<only.pm> is so new, and since we just recently added
support for it here too, this feature is to be considered
experimental. **
=head2 Default Options File (F<.modulebuildrc>)
+[version 0.28]
+
When Module::Build starts up, it will look for a file,
F<$ENV{HOME}/.modulebuildrc>. If the file exists, the options
specified there will be used as defaults, as if they were typed on the
=head1 INSTALL PATHS
+[version 0.19]
+
When you invoke Module::Build's C<build> action, it needs to figure
out where to install things. The nutshell version of how this works
is that default installation locations are determined from
=head2 About PREFIX Support
+[version 0.28]
+
First, it is necessary to understand the original idea behind
C<PREFIX>. If, for example, the default installation locations for
your machine are F</usr/local/lib/perl5/5.8.5> for modules,
=item current()
+[version 0.20]
+
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
=item new()
+[version 0.03]
+
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
=item add_to_cleanup
+[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.
=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
instance, for a module that could optionally use either MySQL or
=item autosplit
+[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
=item build_class
+[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
=item build_requires
+[version 0.07]
+
Modules listed in this section are necessary to build and install the
given module, but are not necessary for regular usage of it. This is
actually an important distinction - it allows for tighter control over
See the documentation for L<"PREREQUISITES"> for the details of how
requirements can be specified.
+=item create_packlist
+
+If true, this parameter tells Module::Build to create a F<.packlist>
+file during the C<install> action, just like ExtUtils::MakeMaker does.
+The file is created in a subdirectory of the C<arch> installation
+location. It is used by some other tools (CPAN, CPANPLUS, etc.) for
+determining what files are part of an install.
+
+The default value is true. This parameter was introduced in
+Module::Build version 0.2609; previously no packlists were ever
+created by Module::Build.
+
=item c_source
+[version 0.04]
+
An optional C<c_source> argument specifies a directory which contains
C source files that the rest of the build may depend on. Any C<.c>
files in the directory will be compiled to object files. The
=item conflicts
+[version 0.07]
+
Modules listed in this section conflict in some serious way with the
given module. C<Module::Build> (or some higher-level tool) will
refuse to install the given module if the given module/version is also
=item create_makefile_pl
+[version 0.19]
+
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
=item create_readme
+[version 0.22]
+
This parameter tells Module::Build to automatically create a F<README>
file at the top level of your distribution. Currently it will simply
use C<Pod::Text> (or C<Pod::Readme> if it's installed) on the file
=item dist_abstract
+[version 0.20]
+
This should be a short description of the distribution. This is used
when generating metadata for F<META.yml> and PPD files. If it is not
given then C<Module::Build> looks in the POD of the module from which
=item dist_author
+[version 0.20]
+
This should be something like "John Doe <jdoe@example.com>", or if
there are multiple authors, an anonymous array of strings may be
specified. This is used when generating metadata for F<META.yml> and
=item dist_name
+[version 0.11]
+
Specifies the name for this distribution. Most authors won't need to
set this directly, they can use C<module_name> to set C<dist_name> to
a reasonable default. However, some agglomerative distributions like
=item dist_version
+[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
C<$VERSION> variable in a module. One way or another, a version
=item dist_version_from
+[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>
to set it to a reasonable default.
=item dynamic_config
+[version 0.07]
+
A boolean flag indicating whether the F<Build.PL> file must be
executed, or whether this module can be built, tested and installed
solely from consulting its metadata file. The main reason to set this
=item extra_linker_flags
+[version 0.19]
+
These parameters can contain array references (or strings, in which
case they will be split into arrays) to pass through to the compiler
and linker phases when compiling/linking C code. For example, to tell
=item get_options
+[version 0.26]
+
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
=item include_dirs
+[version 0.24]
+
Specifies any additional directories in which to search for C header
files. May be given as a string indicating a single directory, or as
a list reference indicating multiple directories.
=item install_path
+[version 0.19]
+
You can set paths for individual installable elements by using the
C<install_path> parameter:
=item installdirs
+[version 0.19]
+
Determines where files are installed within the normal perl hierarchy
as determined by F<Config.pm>. Valid values are: C<core>, C<site>,
C<vendor>. The default is C<site>. See
=item license
+[version 0.07]
+
Specifies the licensing terms of your distribution. Valid options include:
=item meta_add
+[version 0.28]
+
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.
=item meta_merge
+[version 0.28]
+
A hash of key/value pairs that should be merged into the F<META.yml>
file during the C<distmeta> action. Any existing entries with the
same names will be overridden.
=item module_name
+[version 0.03]
+
The C<module_name> is a shortcut for setting default values of
C<dist_name> and C<dist_version_from>, reflecting the fact that the
majority of CPAN distributions are centered around one "main" module.
=item PL_files
+[version 0.06]
+
An optional parameter specifying a set of C<.PL> files in your
distribution. These will be run as Perl scripts prior to processing
the rest of the files in your distribution. They are usually used as
=item pm_files
+[version 0.19]
+
An optional parameter specifying the set of C<.pm> files in this
distribution, specified as a hash reference whose keys are the files'
locations in the distributions, and whose values are their logical
=item pod_files
+[version 0.19]
+
Just like C<pm_files>, but used for specifying the set of C<.pod>
files in your distribution.
=item recommends
+[version 0.08]
+
This is just like the C<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
See the documentation for L<"PREREQUISITES"> for the details of how
requirements can be specified.
+=item recursive_test_files
+
+[version 0.28]
+
+Normally, C<Module::Build> does not search subdirectories when looking
+for tests to run. When this options is set it will search recursively
+in all subdirectories of the standard 't' test directory.
+
=item requires
+[version 0.07]
+
An optional C<requires> argument specifies any module prerequisites
that the current module depends on.
=item script_files
+[version 0.18]
+
An optional parameter specifying a set of files that should be
installed as executable perl scripts when the module is installed.
May be given as an array reference of the files, or as a hash
=item sign
+[version 0.16]
+
If a true value is specified for this parameter, C<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
=item test_files
+[version 0.23]
+
An optional parameter specifying a set of files that should be used as
C<Test::Harness>-style regression tests to be run during the C<test>
action. May be given as an array reference of the files, or as a hash
=item xs_files
+[version 0.19]
+
Just like C<pm_files>, but used for specifying the set of C<.xs>
files in your distribution.
=item new_from_context(%args)
+[version 0.28]
+
When called from a directory containing a F<Build.PL> script and a
F<META.yml> file (in other words, the base directory of a
distribution), this method will run the F<Build.PL> and return the
=item resume()
+[version 0.03]
+
You'll probably never call this method directly, it's only called from
the auto-generated C<Build> script. The C<new()> method is only
called once, when the user runs C<perl Build.PL>. Thereafter, when
=item subclass()
+[version 0.06]
+
This creates a new C<Module::Build> subclass on the fly, as described
in the L<"SUBCLASSING"> section. The caller must provide either a
C<class> or C<code> parameter, or both. The C<class> parameter
=item add_build_element($type)
+[version 0.26]
+
Adds a new type of entry to the build process. Accepts a single
string specifying its type-name. There must also be a method defined
to process things of that type, e.g. if you add a build element called
=item add_to_cleanup(@files)
+[version 0.03]
+
You may call C<< $self->add_to_cleanup(@patterns) >> to tell
C<Module::Build> that certain files should be removed when the user
performs the C<Build clean> action. The arguments to the method are
=item args()
+[version 0.26]
+
my $args_href = $build->args;
my %args = $build->args;
my $arg_value = $build->args($key);
=item autosplit_file($from, $to)
+[version 0.28]
+
Invokes the C<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.
=item base_dir()
+[version 0.14]
+
Returns a string containing the root-level directory of this build,
i.e. where the C<Build.PL> script and the C<lib> directory can be
found. This is usually the same as the current working directory,
=item build_requires()
+[version 0.21]
+
Returns a hash reference indicating the C<build_requires>
prerequisites that were passed to the C<new()> method.
=item check_installed_status($module, $version)
+[version 0.11]
+
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
=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>.
=item compare_versions($v1, $op, $v2)
+[version 0.28]
+
Compares two module versions C<$v1> and C<$v2> using the operator
C<$op>, which should be one of Perl's numeric operators like C<!=> or
C<< >= >> or the like. We do at least a halfway-decent job of
=item config()
+[version 0.22]
+
Returns a hash reference containing the C<Config.pm> hash, including
any changes the author or user has specified. This is a reference to
the actual internal hash we use, so you probably shouldn't modify
=item config_data($name => $value)
+[version 0.26]
+
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
=item conflicts()
+[version 0.21]
+
Returns a hash reference indicating the C<conflicts> prerequisites
that were passed to the C<new()> method.
=item contains_pod($file)
+[version 0.20]
+
[Deprecated] Please see L<Module::Build::ModuleInfo> instead.
Returns true if the given file appears to contain POD documentation.
=item copy_if_modified(%parameters)
+[version 0.19]
+
Takes the file in the C<from> parameter and copies it to the file in
the C<to> parameter, or the directory in the C<to_dir> parameter, if
the file has changed since it was last copied (or if it doesn't exist
=item create_build_script()
+[version 0.05]
+
Creates an executable script called C<Build> in the current directory
that will be used to execute further user actions. This script is
roughly analogous (in function, not in form) to the Makefile created
=item current_action()
+[version 0.28]
+
Returns the name of the currently-running action, such as "build" or
"test". This action is not necessarily the action that was originally
invoked by the user. For example, if the user invoked the "test"
=item depends_on(@actions)
+[version 0.28]
+
Invokes the named action or list of actions in sequence. Using this
method is preferred to calling the action explicitly because it
performs some internal record-keeping, and it ensures that the same
=item dir_contains($first_dir, $second_dir)
+[version 0.28]
+
Returns true if the first directory logically contains the second
directory. This is just a convenience function because C<File::Spec>
doesn't really provide an easy way to figure this out (but
=item dispatch($action, %args)
+[version 0.03]
+
Invokes the build action C<$action>. Optionally, a list of options
and their values can be passed in. This is equivalent to invoking an
action at the command line, passing in a list of options.
=item dist_dir()
+[version 0.28]
+
Returns the name of the directory that will be created during the
C<dist> action. The name is derived from the C<dist_name> and
C<dist_version> properties.
=item dist_name()
+[version 0.21]
+
Returns the name of the current distribution, as passed to the
C<new()> method in a C<dist_name> or modified C<module_name>
parameter.
=item dist_version()
+[version 0.21]
+
Returns the version of the current distribution, as determined by the
C<new()> method from a C<dist_version>, C<dist_version_from>, or
C<module_name> parameter.
=item do_system($cmd, @args)
+[version 0.21]
+
This is a fairly simple wrapper around Perl's C<system()> built-in
command. Given a command and an array of optional arguments, this
method will print the command to C<STDOUT>, and then execute it using
=item feature($name => $value)
+[version 0.26]
+
With a single argument, returns true if the given feature is set.
With two arguments, sets the given feature to the given boolean value.
In this context, a "feature" is any optional functionality of an
=item have_c_compiler()
+[version 0.21]
+
Returns true if the current system seems to have a working C compiler.
We currently determine this by attempting to compile a simple C source
file and reporting whether the attempt was successful.
=item install_destination($type)
+[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()>
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.
+=item install_path()
+
+=item install_path($type)
+
+=item install_path($type => $path)
+
+[version 0.28]
+
+Set or retrieve paths for specific installable elements. This is
+useful when you want to examine any explicit install paths specified
+by the user on the command line, or if you want to set the install
+path for a specific installable element based on another attribute
+like C<install_base()>.
+
+With no argument, it returns a reference to a hash containing all
+elements and their respective values. This hash should not be modified
+directly; use the multi-argument below form to change values.
+
+The single argument form returns the value associated with the
+element C<$type>.
+
+The multi-argument form allows you to set the paths for one or more
+element types. The return value is undefined.
+
=item install_types()
+[version 0.28]
+
Returns a list of installable types that this build knows about.
These types each correspond to the name of a directory in F<blib/>,
and the list usually includes items such as C<lib>, C<arch>, C<bin>,
=item invoked_action()
+[version 0.28]
+
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
=item notes($key => $value)
+[version 0.20]
+
The C<notes()> value allows you to store your own persistent
information about the build, and to share that information among
different entities involved in the build. See the example in the
=item orig_dir()
+[version 0.28]
+
Returns a string containing the working directory that was in effect
before the F<Build> script chdir()-ed into the C<base_dir>. This
might be useful for writing wrapper tools that might need to chdir()
back out.
-=item rscan_dir($dir, $pattern)
-
-Uses C<File::Find> to traverse the directory C<$dir>, returning a
-reference to an array of entries matching C<$pattern>. C<$pattern>
-may either be a regular expression (using C<qr//> or just a plain
-string), or a reference to a subroutine that will return true for
-wanted entries. If C<$pattern> is not given, all entries will be
-returned.
-
-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$/});
-
- # All the files in t/
- $m->rscan_dir('t');
-
-=item runtime_params()
-
-=item runtime_params($key)
-
-The C<runtime_params()> method stores the values passed on the command line
-for valid properties (that is, any command line options for which
-C<valid_property()> returns a true value). The value on the command line may
-override the default value for a property, as well as any value specified in a
-call to C<new()>. This allows you to programmatically tell if C<perl Build.PL>
-or any execution of C<./Build> had command line options specified that
-override valid properties.
-
-The C<runtime_params()> method is essentally a glorified read-only hash. With
-no arguments, C<runtime_params()> returns the entire hash of properties
-specified on the command line. With one argument, C<runtime_params($key)>
-returns the value associated with the given key.
-
-The lifetime of the C<runtime_params> data is for "a build" - that is, the
-C<runtime_params> hash is created when C<perl Build.PL> is run (or when the
-C<new()> method is called, if the Module::Build Perl API is being used instead
-of called from a shell), and lasts until C<perl Build.PL> is run again or the
-C<clean> action is run.
-
=item os_type()
+[version 0.04]
+
If you're subclassing Module::Build and some code needs to alter its
behavior based on the current platform, you may only need to know
whether you're running on Windows, Unix, MacOS, VMS, etc., and not the
=item prepare_metadata()
+[version 0.28]
+
This method is provided for authors to override to customize the
fields of F<META.yml>. It is passed a YAML::Node node object which can
be modified as desired and then returned. E.g.
=item prereq_failures()
+[version 0.11]
+
Returns a data structure containing information about any failed
prerequisites (of any of the types described above), or C<undef> if
all prerequisites are met.
=item prereq_report()
+[version 0.28]
+
Returns a human-readable (table-form) string showing all
prerequisites, the versions required, and the versions actually
installed. This can be useful for reviewing the configuration of your
=item prompt($message, $default)
+[version 0.12]
+
Asks the user a question and returns their response as a string. The
first argument specifies the message to display to the user (for
example, C<"Where do you keep your money?">). The second argument,
=item recommends()
+[version 0.21]
+
Returns a hash reference indicating the C<recommends> prerequisites
that were passed to the C<new()> method.
=item requires()
+[version 0.21]
+
Returns a hash reference indicating the C<requires> prerequisites that
were passed to the C<new()> method.
+=item rscan_dir($dir, $pattern)
+
+[version 0.28]
+
+Uses C<File::Find> to traverse the directory C<$dir>, returning a
+reference to an array of entries matching C<$pattern>. C<$pattern>
+may either be a regular expression (using C<qr//> or just a plain
+string), or a reference to a subroutine that will return true for
+wanted entries. If C<$pattern> is not given, all entries will be
+returned.
+
+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$/});
+
+ # All the files in t/
+ $m->rscan_dir('t');
+
+=item runtime_params()
+
+=item runtime_params($key)
+
+[version 0.28]
+
+The C<runtime_params()> method stores the values passed on the command line
+for valid properties (that is, any command line options for which
+C<valid_property()> returns a true value). The value on the command line may
+override the default value for a property, as well as any value specified in a
+call to C<new()>. This allows you to programmatically tell if C<perl Build.PL>
+or any execution of C<./Build> had command line options specified that
+override valid properties.
+
+The C<runtime_params()> method is essentally a glorified read-only hash. With
+no arguments, C<runtime_params()> returns the entire hash of properties
+specified on the command line. With one argument, C<runtime_params($key)>
+returns the value associated with the given key.
+
+The lifetime of the C<runtime_params> data is for "a build" - that is, the
+C<runtime_params> hash is created when C<perl Build.PL> is run (or when the
+C<new()> method is called, if the Module::Build Perl API is being used instead
+of called from a shell), and lasts until C<perl Build.PL> is run again or the
+C<clean> action is run.
+
=item script_files()
+[version 0.18]
+
Returns a hash reference whose keys are the perl script files to be
installed, if any. This corresponds to the C<script_files> parameter to the
C<new()> method. With an optional argument, this parameter may be set
=item up_to_date(\@source_files, \@derived_files)
+[version 0.20]
+
This method can be used to compare a set of source files to a set of
derived files. If any of the source files are newer than any of the
derived files, it returns false. Additionally, if any of the derived
=item y_n($message, $default)
+[version 0.12]
+
Asks the user a yes/no question using C<prompt()> and returns true or
false accordingly. The user will be asked the question repeatedly
until they give an answer that looks like "yes" or "no".
=item create_makefile_pl()
+=item create_packlist()
+
=item create_readme()
=item debugger()
use Data::Dumper ();
use IO::File ();
use Text::ParseWords ();
-use Carp ();
use Module::Build::ModuleInfo;
use Module::Build::Notes;
return Cwd::cwd();
}
+sub _quote_args {
+ # Returns a string that can become [part of] a command line with
+ # proper quoting so that the subprocess sees this same list of args.
+ my ($self, @args) = @_;
+
+ my $return_args = '';
+ my @quoted;
+
+ for (@args) {
+ if ( /^[^\s*?!$<>;\\|'"\[\]\{\}]+$/ ) {
+ # Looks pretty safe
+ push @quoted, $_;
+ } else {
+ # XXX this will obviously have to improve - is there already a
+ # core module lying around that does proper quoting?
+ s/"/"'"'"/g;
+ push @quoted, qq("$_");
+ }
+ }
+
+ return join " ", @quoted;
+}
+
+sub _backticks {
+ # Tries to avoid using true backticks, when possible, so that we
+ # don't have to worry about shell args.
+
+ my ($self, @cmd) = @_;
+ if ($self->have_multiarg_pipeopen) {
+ local *FH;
+ open FH, "-|", @cmd or die "Can't run @cmd: $!";
+ return wantarray ? <FH> : join '', <FH>;
+ } else {
+ my $cmd = $self->_quote_args(@cmd);
+ return `$cmd`;
+ }
+}
+
+sub have_multiarg_pipeopen { $] >= 5.008 }
+
+# Determine whether a given binary is the same as the perl
+# (configuration) that started this process.
sub _perl_is_same {
my ($self, $perl) = @_;
- return `$perl -MConfig=myconfig -e print -e myconfig` eq Config->myconfig;
+
+ my @cmd = ($perl);
+
+ # When run from the perl core, @INC will include the directories
+ # where perl is yet to be installed. We need to reference the
+ # absolute path within the source distribution where it can find
+ # it's Config.pm This also prevents us from picking up a Config.pm
+ # from a different configuration that happens to be already
+ # installed in @INC.
+ if ($ENV{PERL_CORE}) {
+ push @cmd, '-I' . File::Spec->catdir(File::Basename::dirname($perl), 'lib');
+ }
+
+ push @cmd, qw(-MConfig=myconfig -e print -e myconfig);
+ return $self->_backticks(@cmd) eq Config->myconfig;
}
+# 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
+# interpreter, on other it may contain a relative path, or simply
+# 'perl'. This can also vary depending on whether a path was supplied
+# when perl was invoked. Additionally, the value in $^X may omit the
+# 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 {
- return $^X if File::Spec->file_name_is_absolute($^X);
my $proto = shift;
- my $c = ref($proto) ? $proto->config : \%Config::Config;
- my $exe = $c->{exe_ext};
+ my $c = ref($proto) ? $proto->config : \%Config::Config;
- my $thisperl = $^X;
- if ($proto->os_type eq 'VMS') {
- # VMS might have a file version at the end
- $thisperl .= $exe unless $thisperl =~ m/$exe(;\d+)?$/i;
- } elsif (defined $exe) {
- $thisperl .= $exe unless $thisperl =~ m/$exe$/i;
- }
+ my $perl = $^X;
+ my $perl_basename = File::Basename::basename($perl);
+
+ my @potential_perls;
+
+ # Try 1, Check $^X for absolute path
+ push( @potential_perls, $perl )
+ if File::Spec->file_name_is_absolute($perl);
- my $uninstperl;
+ # Try 2, Check $^X for a valid relative path
+ my $abs_perl = File::Spec->rel2abs($perl);
+ push( @potential_perls, $abs_perl );
+
+ # Try 3, Last ditch effort: These two option use hackery to try to locate
+ # a suitable perl. The hack varies depending on whether we are running
+ # from an installed perl or an uninstalled perl in the perl source dist.
if ($ENV{PERL_CORE}) {
+
+ # Try 3.A, If we are in a perl source tree, running an uninstalled
+ # perl, we can keep moving up the directory tree until we find our
+ # binary. We wouldn't do this under any other circumstances.
+
# CBuilder is also in the core, so it should be available here
require ExtUtils::CBuilder;
- $uninstperl = File::Spec->catfile(ExtUtils::CBuilder::->perl_src, $thisperl);
+ my $perl_src = ExtUtils::CBuilder->perl_src;
+ if ( defined($perl_src) && length($perl_src) ) {
+ my $uninstperl =
+ File::Spec->rel2abs(File::Spec->catfile( $perl_src, $perl_basename ));
+ push( @potential_perls, $uninstperl );
+ }
+
+ } else {
+
+ # Try 3.B, First look in $Config{perlpath}, then search the users
+ # PATH. We do not want to do either if we are running from an
+ # uninstalled perl in a perl source tree.
+
+ push( @potential_perls, $c->{perlpath} );
+
+ push( @potential_perls,
+ map File::Spec->catfile($_, $perl_basename), File::Spec->path() );
}
- foreach my $perl ( $uninstperl || (),
- $c->{perlpath},
- map File::Spec->catfile($_, $thisperl), File::Spec->path()
- ) {
- return $perl if -f $perl and $proto->_perl_is_same($perl);
+ # Now that we've enumerated the potential perls, it's time to test
+ # them to see if any of them match our configuration, returning the
+ # absolute path of the first successful match.
+ my $exe = $c->{exe_ext};
+ foreach my $thisperl ( @potential_perls ) {
+
+ if ($proto->os_type eq 'VMS') {
+ # VMS might have a file version at the end
+ $thisperl .= $exe unless $thisperl =~ m/$exe(;\d+)?$/i;
+ } elsif (defined $exe) {
+ $thisperl .= $exe unless $thisperl =~ m/$exe$/i;
+ }
+
+ if ( -f $thisperl && $proto->_perl_is_same($thisperl) ) {
+ return $thisperl;
+ }
}
- return;
+
+ # We've tried all alternatives, and didn't find a perl that matches
+ # our configuration. Throw an exception, and list alternatives we tried.
+ my @paths = map File::Basename::dirname($_), @potential_perls;
+ die "Can't locate the perl binary used to run this script " .
+ "in (@paths)\n";
}
sub _is_interactive {
__PACKAGE__->add_property(metafile => 'META.yml');
__PACKAGE__->add_property(recurse_into => []);
__PACKAGE__->add_property(use_rcfile => 1);
+__PACKAGE__->add_property(create_packlist => 1);
{
my $Is_ActivePerl = eval {require ActivePerl::DocTools};
my $perl = ref($self) ? $self->perl : $self->find_perl_interpreter;
- my @inc = `$perl -le "print for \@INC"`;
+ my @inc = $self->_backticks($perl, '-le', 'print for @INC');
chomp @inc;
return @default_inc = @inc;
use $build_package;
# Some platforms have problems setting \$^X in shebang contexts, fix it up here
-\$^X = Module::Build->find_perl_interpreter
- unless File::Spec->file_name_is_absolute(\$^X);
+\$^X = Module::Build->find_perl_interpreter;
if (-e 'Build.PL' and not $build_package->up_to_date('Build.PL', \$progname)) {
warn "Warning: Build.PL has been altered. You may need to run 'perl Build.PL' again.\\n";
foreach my $file (keys %$files) {
my $result = $self->copy_if_modified($file, $script_dir, 'flatten') or next;
- $self->fix_shebang_line($result);
+ $self->fix_shebang_line($result) unless $self->os_type eq 'VMS';
$self->make_executable($result);
}
}
sub localize_file_path {
my ($self, $path) = @_;
+ $path =~ s/\.\z// if $self->os_type eq 'VMS';
return File::Spec->catfile( split m{/}, $path );
}
sub ACTION_distcheck {
my ($self) = @_;
-
+
require ExtUtils::Manifest;
local $^W; # ExtUtils::Manifest is not warnings clean.
my ($missing, $extra) = ExtUtils::Manifest::fullcheck();
- die "MANIFEST appears to be out of sync with the distribution\n"
- if @$missing || @$extra;
+
+ return unless @$missing || @$extra;
+
+ my $msg = "MANIFEST appears to be out of sync with the distribution\n";
+ if ( $self->invoked_action eq 'distcheck' ) {
+ die $msg;
+ } else {
+ warn $msg;
+ }
}
sub _add_to_manifest {
# Avoid Module::Build generated and utility files.
\bBuild$
+\bBuild.bat$
\b_build
# Avoid Devel::Cover generated files
}
}
-sub _yaml_quote_string {
- # XXX doesn't handle embedded newlines
-
- my ($self, $string) = @_;
- if ($string !~ /\"/) {
- $string =~ s{\\}{\\\\}g;
- return qq{"$string"};
- } else {
- $string =~ s{([\\'])}{\\$1}g;
- return qq{'$string'};
- }
-}
-
-sub _write_minimal_metadata {
- my $self = shift;
- my $p = $self->{properties};
-
- my $file = $self->metafile;
- my $fh = IO::File->new("> $file")
- or die "Can't open $file: $!";
-
- my @author = map $self->_yaml_quote_string($_), @{$self->dist_author};
- my $abstract = $self->_yaml_quote_string($self->dist_abstract);
-
- # XXX Add the meta_add & meta_merge stuff
-
- print $fh <<"EOF";
---- #YAML:1.0
-name: $p->{dist_name}
-version: $p->{dist_version}
-author:
-@{[ join "\n", map " - $_", @author ]}
-abstract: $abstract
-license: $p->{license}
-generated_by: Module::Build version $Module::Build::VERSION, without YAML.pm
-EOF
-}
-
sub ACTION_distmeta {
my ($self) = @_;
$self->{wrote_metadata} = $yaml_sub->($metafile, $node );
} else {
- $self->log_warn(<<EOF);
-
-Couldn't load YAML.pm, generating a minimal META.yml without it.
-Please check and edit the generated metadata, or consider installing YAML.pm.
-
-EOF
-
- $self->_write_minimal_metadata;
+ require Module::Build::YAML;
+ my (%node, @order_keys);
+ $self->prepare_metadata(\%node, \@order_keys);
+ $node{_order} = \@order_keys;
+ &Module::Build::YAML::DumpFile($metafile, \%node);
+ $self->{wrote_metadata} = 1;
}
$self->_add_to_manifest('MANIFEST', $metafile);
}
sub prepare_metadata {
- my ($self, $node) = @_;
+ my ($self, $node, $keys) = @_;
my $p = $self->{properties};
+ # A little helper sub
+ my $add_node = sub {
+ my ($name, $val) = @_;
+ $node->{$name} = $val;
+ push @$keys, $name if $keys;
+ };
+
foreach (qw(dist_name dist_version dist_author dist_abstract license)) {
(my $name = $_) =~ s/^dist_//;
- $node->{$name} = $self->$_();
+ $add_node->($name, $self->$_());
die "ERROR: Missing required field '$_' for META.yml\n"
unless defined($node->{$name}) && length($node->{$name});
}
}
foreach ( @{$self->prereq_action_types} ) {
- $node->{$_} = $p->{$_} if exists $p->{$_} and keys %{ $p->{$_} };
+ if (exists $p->{$_} and keys %{ $p->{$_} }) {
+ $add_node->($_, $p->{$_});
+ }
}
- $node->{dynamic_config} = $p->{dynamic_config} if exists $p->{dynamic_config};
+ if (exists $p->{dynamic_config}) {
+ $add_node->('dynamic_config', $p->{dynamic_config});
+ }
my $pkgs = eval { $self->find_dist_packages };
if ($@) {
$self->log_warn("WARNING: Possible missing or corrupt 'MANIFEST' file.\n" .
$node->{provides} = $pkgs if %$pkgs;
}
;
- $node->{no_index} = $p->{no_index} if exists $p->{no_index};
-
- $node->{generated_by} = "Module::Build version $Module::Build::VERSION";
+ if (exists $p->{no_index}) {
+ $add_node->('no_index', $p->{no_index});
+ }
- $node->{'meta-spec'} = {
- version => '1.2',
- url => 'http://module-build.sourceforge.net/META-spec-v1.2.html',
- };
+ $add_node->('generated_by', "Module::Build version $Module::Build::VERSION");
+ $add_node->('meta-spec',
+ {version => '1.2',
+ url => 'http://module-build.sourceforge.net/META-spec-v1.2.html',
+ });
while (my($k, $v) = each %{$self->meta_add}) {
- $node->{$k} = $v;
+ $add_node->($k, $v);
}
while (my($k, $v) = each %{$self->meta_merge}) {
) if @skipping;
# Write the packlist into the same place as ExtUtils::MakeMaker.
- if (my $module_name = $self->module_name) {
+ if ($self->create_packlist and my $module_name = $self->module_name) {
my $archdir = $self->install_destination('arch');
my @ext = split /::/, $module_name;
$map{write} = File::Spec->catdir($archdir, 'auto', @ext, '.packlist');
if (defined $lib_typemap and -e $lib_typemap) {
push @typemaps, 'typemap';
}
- my $typemaps = join ' ', map qq{-typemap "$_"}, @typemaps;
+ @typemaps = map {+'-typemap', $_} @typemaps;
my $cf = $self->config;
my $perl = $self->{properties}{perl};
- my $command = (qq{$perl "-I$cf->{installarchlib}" "-I$cf->{installprivlib}" "$xsubpp" -noprototypes } .
- qq{$typemaps "$file"});
+ my @command = ($perl, "-I$cf->{installarchlib}", "-I$cf->{installprivlib}", $xsubpp, '-noprototypes',
+ @typemaps, $file);
- $self->log_info("$command\n");
+ $self->log_info("@command\n");
my $fh = IO::File->new("> $args{outfile}") or die "Couldn't write $args{outfile}: $!";
- print $fh `$command`;
+ print {$fh} $self->_backticks(@command);
close $fh;
}
}
# this before documenting.
my ($self, $args) = @_;
$args = [ $self->split_like_shell($args) ] unless ref($args);
+ $args = [ split(/\s+/, $self->_quote_args($args)) ] if $self->os_type eq 'VMS';
my $perl = ref($self) ? $self->perl : $self->find_perl_interpreter;
# Make sure our local additions to @INC are propagated to the subprocess
Revision history for Perl extension Module::Build.
+0.27_11 Tue Mar 28 22:50:50 CST 2006
+
+ - Added the create_packlist property, default true, which controls
+ whether packlist files will be written during installation. This
+ was already part of Module::Build 0.2609, but for some reason we've
+ forgotten it in the 0.27_xx series. [Spotted by Steve Kirkup]
+
+ - Document the versions of Module::Build where each feature, action,
+ constructor argument, and method was first publicly documented.
+
+ - More fixes for find_perl_interpreter() to work with BSD flavored
+ UNIX: Ensure we always return absolute paths; throw an exception
+ upon failure to find correct interperter; document everything.
+
+ - We now include our own YAML.pm work-alike that we can use when the
+ real YAML isn't installed. We might soon even start using it when
+ YAML is installed, because the YAML API and dependency chain have
+ been changing in unfavorable ways lately. [Stephen Adkins]
+
+ - Fixed some shell-argument-quoting issues on VMS. In the process,
+ we have added some support for avoiding tripping over
+ shell-argument-quoting issues on other platforms too. [Initial
+ patch by Craig A. Berry]
+
0.27_09 Sat Mar 11 22:48:54 EST 2006
- Fixed find_perl_interpreter() so we can find the perl executable
use ExtUtils::Install;
+sub have_multiarg_pipeopen { 0 }
+
sub new {
my $class = shift;
my $self = $class->SUPER::new(@_);
}
+sub _quote_args {
+ # Returns a string that can become [part of] a command line with
+ # proper quoting so that the subprocess sees this same list of args.
+ my ($self, @args) = @_;
+
+ my $return_args = '';
+ for (@args) {
+ $return_args .= q( ").$_.q(") if !/^\"/ && length($_) > 0;
+ }
+ return $return_args;
+}
+
+sub have_multiarg_pipeopen { 0 }
+
=back
=head1 AUTHOR
return '.';
}
+sub have_multiarg_pipeopen { 0 }
+
sub ACTION_realclean {
my ($self) = @_;
sub manpage_separator { '.' }
+sub have_multiarg_pipeopen { 0 }
+
1;
__END__
--- /dev/null
+package Module::Build::YAML;
+
+use strict;
+use warnings;
+
+our $VERSION = "0.50";
+our @EXPORT = ();
+our @EXPORT_OK = qw(Dump Load DumpFile LoadFile);
+
+sub new {
+ my $this = shift;
+ my $class = ref($this) || $this;
+ my $self = {};
+ bless $self, $class;
+ return($self);
+}
+
+sub Dump {
+ shift if ($_[0] eq __PACKAGE__ || ref($_[0]) eq __PACKAGE__);
+ my $yaml = "";
+ foreach my $item (@_) {
+ $yaml .= "---\n";
+ $yaml .= &_yaml_chunk("", $item);
+ }
+ return $yaml;
+}
+
+sub Load {
+ shift if ($_[0] eq __PACKAGE__ || ref($_[0]) eq __PACKAGE__);
+ die "not yet implemented";
+}
+
+# This is basically copied out of YAML.pm and simplified a little.
+sub DumpFile {
+ shift if ($_[0] eq __PACKAGE__ || ref($_[0]) eq __PACKAGE__);
+ my $filename = shift;
+ local $/ = "\n"; # reset special to "sane"
+ my $mode = '>';
+ if ($filename =~ /^\s*(>{1,2})\s*(.*)$/) {
+ ($mode, $filename) = ($1, $2);
+ }
+ open my $OUT, $mode, $filename
+ or die "Can't open $filename for writing: $!";
+ print $OUT Dump(@_);
+ close $OUT;
+}
+
+# This is basically copied out of YAML.pm and simplified a little.
+sub LoadFile {
+ shift if ($_[0] eq __PACKAGE__ || ref($_[0]) eq __PACKAGE__);
+ my $filename = shift;
+ open my $IN, $filename
+ or die "Can't open $filename for reading: $!";
+ return Load(do { local $/; <$IN> });
+ close $IN;
+}
+
+sub _yaml_chunk {
+ my ($indent, $values) = @_;
+ my $yaml_chunk = "";
+ my $ref = ref($values);
+ my ($value, @allkeys, %keyseen);
+ if (!$ref) { # a scalar
+ $yaml_chunk .= &_yaml_value($values) . "\n";
+ }
+ elsif ($ref eq "ARRAY") {
+ foreach $value (@$values) {
+ $yaml_chunk .= "$indent-";
+ $ref = ref($value);
+ if (!$ref) {
+ $yaml_chunk .= " " . &_yaml_value($value) . "\n";
+ }
+ else {
+ $yaml_chunk .= "\n";
+ $yaml_chunk .= &_yaml_chunk("$indent ", $value);
+ }
+ }
+ }
+ else { # assume "HASH"
+ if ($values->{_order} && ref($values->{_order}) eq "ARRAY") {
+ @allkeys = @{$values->{_order}};
+ $values = { %$values };
+ delete $values->{_order};
+ }
+ push(@allkeys, sort keys %$values);
+ foreach my $key (@allkeys) {
+ next if (!defined $key || $key eq "" || $keyseen{$key});
+ $keyseen{$key} = 1;
+ $yaml_chunk .= "$indent$key:";
+ $value = $values->{$key};
+ $ref = ref($value);
+ if (!$ref) {
+ $yaml_chunk .= " " . &_yaml_value($value) . "\n";
+ }
+ else {
+ $yaml_chunk .= "\n";
+ $yaml_chunk .= &_yaml_chunk("$indent ", $value);
+ }
+ }
+ }
+ return($yaml_chunk);
+}
+
+sub _yaml_value {
+ # XXX doesn't handle embedded newlines
+ my ($value) = @_;
+ # undefs and empty strings will become empty strings
+ if (! defined $value || $value eq "") {
+ return('""');
+ }
+ # allow simple scalars (without embedded quote chars) to be unquoted
+ elsif ($value !~ /["'\\]/) {
+ return($value);
+ }
+ # strings without double-quotes get double-quoted
+ elsif ($value !~ /\"/) {
+ $value =~ s{\\}{\\\\}g;
+ return qq{"$value"};
+ }
+ # other strings get single-quoted
+ else {
+ $value =~ s{([\\'])}{\\$1}g;
+ return qq{'$value'};
+ }
+}
+
+1;
+
+__END__
+
+=head1 NAME
+
+Module::Build::YAML - Provides just enough YAML support so that Module::Build works even if YAML.pm is not installed
+
+=head1 SYNOPSIS
+
+ use Module::Build::YAML;
+
+ ...
+
+=head1 DESCRIPTION
+
+Provides just enough YAML support so that Module::Build works even if YAML.pm is not installed.
+
+Currently, this amounts to the ability to write META.yml files when "perl Build distmeta"
+is executed via the Dump() and DumpFile() functions/methods.
+
+=head1 AUTHOR
+
+Stephen Adkins <spadkins@gmail.com>
+
+=head1 COPYRIGHT
+
+Copyright (c) 2006. Stephen Adkins. All rights reserved.
+
+This program is free software; you can redistribute it and/or modify it
+under the same terms as Perl itself.
+
+See L<http://www.perl.com/perl/misc/Artistic.html>
+
+=cut
+
#
# Copyright 1997 Christopher J. Madsen
#
-# Author: Christopher J. Madsen <chris_madsen@geocities.com>
+# Author: Christopher J. Madsen <cjm@pobox.com>
# Created: 08 Nov 1997
-# Version: 1.001 (25-Oct-1998)
+# $Revision: 1.2 $ $Date: 2006/03/21 13:27:29 $
#
# This program is free software; you can redistribute it and/or modify
# it under the same terms as Perl itself.
#=====================================================================
# Package Global Variables:
-BEGIN
-{
- # Convert RCS revision number to d.ddd format:
- $VERSION = sprintf('%d.%03d', '1.001 ' =~ /(\d+)\.(\d+)/);
-} # end BEGIN
+$VERSION = '1.02';
#=====================================================================
# Tied Methods:
} # end NEXTKEY
#---------------------------------------------------------------------
+# SCALAR this
+# Return bucket usage information for the hash (0 if empty).
+
+sub SCALAR
+{
+ scalar %{$_[0]};
+} # end SCALAR
+
+#---------------------------------------------------------------------
# EXISTS this, key
# Verify that *key* exists with the tied hash *this*.
=head1 DESCRIPTION
-The B<Tie::CPHash> provides a hash table that is case preserving but
-case insensitive. This means that
+The B<Tie::CPHash> module provides a hash table that is case
+preserving but case insensitive. This means that
$cphash{KEY} $cphash{key}
$cphash{Key} $cphash{keY}
=head1 AUTHOR
-Christopher J. Madsen E<lt>F<chris_madsen@geocities.com>E<gt>
+Christopher J. Madsen E<lt>F<cjm@pobox.com>E<gt>
=cut
use IO::File ();
use Tie::CPHash;
+BEGIN {
+ if( $^O eq 'VMS' ) {
+ # For things like vmsify()
+ require VMS::Filespec;
+ VMS::Filespec->import;
+ }
+}
+
sub new {
my $package = shift;
my %options = @_;
File::Find::finddepth( sub {
my $name = File::Spec->canonpath( $File::Find::name );
- $name =~ s/\.\z// if $^O eq 'VMS';
+ if ($^O eq 'VMS') {
+ $name =~ s/\.\z//;
+ $name = vmspath($name) if -d $name;
+ $name = File::Spec->rel2abs($name) if $name eq File::Spec->curdir();
+ }
if ( not exists $names{$name} ) {
print "Removing '$name'\n" if $VERBOSE;
sub remove {
my $self = shift;
- File::Path::rmtree( $self->dirname );
+ File::Path::rmtree( File::Spec->canonpath($self->dirname) );
}
sub revert {
--- /dev/null
+#!/usr/local/bin/perl -w
+
+use Test::More qw(no_plan);
+use lib "lib";
+use lib "../lib";
+
+my ($dir);
+$dir = ".";
+$dir = "t" if (-d "t");
+
+{
+ use_ok("Module::Build::YAML");
+ my ($expected, $got, $var);
+ $var = {
+ 'resources' => {
+ 'license' => 'http://opensource.org/licenses/artistic-license.php'
+ },
+ 'meta-spec' => {
+ 'version' => '1.2',
+ 'url' => 'http://module-build.sourceforge.net/META-spec-v1.2.html'
+ },
+ 'generated_by' => 'Module::Build version 0.2709',
+ 'version' => '0.13',
+ 'name' => 'js-app',
+ 'dynamic_config' => '1',
+ 'author' => [
+ '"Stephen Adkins" <spadkins@gmail.com>'
+ ],
+ 'license' => 'lgpl',
+ 'build_requires' => {
+ 'App::Build' => '0',
+ 'File::Spec' => '0',
+ 'Module::Build' => '0'
+ },
+ 'provides' => {
+ 'JavaScript::App' => {
+ 'version' => '0',
+ 'file' => 'lib/JavaScript/App.pm'
+ }
+ },
+ 'requires' => {
+ 'App::Options' => '0'
+ },
+ 'abstract' => 'A framework for building dynamic widgets or full applications in Javascript'
+ };
+ $expected = <<EOF;
+---
+abstract: A framework for building dynamic widgets or full applications in Javascript
+author:
+ - '"Stephen Adkins" <spadkins\@gmail.com>'
+build_requires:
+ App::Build: 0
+ File::Spec: 0
+ Module::Build: 0
+dynamic_config: 1
+generated_by: Module::Build version 0.2709
+license: lgpl
+meta-spec:
+ url: http://module-build.sourceforge.net/META-spec-v1.2.html
+ version: 1.2
+name: js-app
+provides:
+ JavaScript::App:
+ file: lib/JavaScript/App.pm
+ version: 0
+requires:
+ App::Options: 0
+resources:
+ license: http://opensource.org/licenses/artistic-license.php
+version: 0.13
+EOF
+ $got = &Module::Build::YAML::Dump($var);
+ is($got, $expected, "Dump(): single deep hash");
+
+ $expected = <<EOF;
+---
+name: js-app
+version: 0.13
+author:
+ - '"Stephen Adkins" <spadkins\@gmail.com>'
+abstract: A framework for building dynamic widgets or full applications in Javascript
+license: lgpl
+resources:
+ license: http://opensource.org/licenses/artistic-license.php
+requires:
+ App::Options: 0
+build_requires:
+ App::Build: 0
+ File::Spec: 0
+ Module::Build: 0
+dynamic_config: 1
+provides:
+ JavaScript::App:
+ file: lib/JavaScript/App.pm
+ version: 0
+generated_by: Module::Build version 0.2709
+meta-spec:
+ url: http://module-build.sourceforge.net/META-spec-v1.2.html
+ version: 1.2
+EOF
+ $var->{_order} = [qw(name version author abstract license resources requires build_requires dynamic_config provides)];
+ $got = &Module::Build::YAML::Dump($var);
+ is($got, $expected, "Dump(): single deep hash, ordered");
+
+ $var = [
+ "e",
+ 2.71828,
+ [ "pi", "is", 3.1416 ],
+ { fun => "under_sun", 6 => undef, "more", undef },
+ ];
+ $expected = <<EOF;
+---
+e
+---
+2.71828
+---
+- pi
+- is
+- 3.1416
+---
+6: ""
+fun: under_sun
+more: ""
+EOF
+ $got = &Module::Build::YAML::Dump(@$var);
+ is($got, $expected, "Dump(): multiple, various");
+
+ $expected = <<EOF;
+---
+- e
+- 2.71828
+-
+ - pi
+ - is
+ - 3.1416
+-
+ 6: ""
+ fun: under_sun
+ more: ""
+EOF
+ $got = &Module::Build::YAML::Dump($var);
+ is($got, $expected, "Dump(): single array of various");
+
+ my $y = Module::Build::YAML->new();
+ $got = $y->Dump($var);
+ is($got, $expected, "Dump(): single array of various (OO)");
+}
+
+
use strict;
use lib $ENV{PERL_CORE} ? '../lib/Module/Build/t/lib' : 't/lib';
-use MBTest tests => 46;
+use MBTest tests => 43;
use Cwd ();
my $cwd = Cwd::cwd;
$mb = new_build();
is_deeply($mb->find_dist_packages, {});
-
-{
- # Put our YAML escaper through a few tests. This isn't part of the M::B API.
- my $yq = sub {Module::Build->_yaml_quote_string(@_)};
- like $yq->(''), qr{^ (['"]) \1 $}x;
- is $yq->('Foo "bar" baz'), q{'Foo "bar" baz'};
- is $yq->("Foo 'bar' baz"), q{"Foo 'bar' baz"};
-}
-
############################################################
# cleanup
chdir( $cwd ) or die "Can't chdir to '$cwd': $!";