| Distribution-Guess-BuildSystem documentation | Contained in the Distribution-Guess-BuildSystem distribution. |
Distribution::Guess::BuildSystem - This is the description
use Distribution::Guess::BuildSystem;
chdir $dist_dir;
my $guesser = Distribution::Guess::BuildSystem->new(
dist_dir => $dir
);
my $build_files = $guesser->build_files; # Hash ref
my $build_pl = $guesser->has_build_pl;
my $makefile_pl = $guesser->has_makefile_pl;
my $both = $guesser->has_build_and_makefile;
my $build_command = $guesser->build_commands; # Hash ref
if( $guesser->uses_module_install )
{
my $version = $guesser->module_install_version;
my $pita = $guesser->uses_auto_install;
}
if( $guesser->uses_makemaker )
{
my $version = $guesser->makemaker_version;
my $make = $guesser->make_command;
}
There are three major build system for Perl distributions:
Uses Makefile.PL and make.
Uses Build.PL and perl, although it might have a Makefile.PL that is
a wrapper.
Uses Makefile.PL and calls to an embedded Module::Install. It might
use auto_install to call CPAN.pm at build time.
The trick is to figure out which one you are supposed to use. This module has several methods to look at a distribution and guess what its build system is. The main object is simply some settings. Every time you want to ask a question about the distribution, the object looks at the distribution. That is, it doesn't capture the information when you create the object.
Creates a new guesser object. You can set:
dist_dir - the distribution directory (where the build file is) perl_binary - the path to the perl you want to use prefer_module_build - some methods will return the preferred builder prefer_makemaker - some methods will return the preferred builder
If you prefer The defaults are:
dist_dir - current working directory perl_binary - $^X (may be relative and no longer in path!) prefer_module_build - true prefer_makemaker - false
Returns or sets the distribution directory.
Returns or sets the perl binary path. This is either the one that you set
or the value of $^X. There's no check to verify that this is actually
a perl binary.
Returns or sets the Module::Build preference. If this is true, some of
the methods preferentially return answers for Module::Build over
MakeMaker when a distribution can use both systems. If both
prefer_makemaker and prefer_module_build are true, then
MakeMaker wins.
=cut
Returns or sets the Module::Build preference. If this is true, some of
the methods preferentially return answers for Module::Build over
MakeMaker when a distribution can use both systems. If both
prefer_makemaker and prefer_module_build are true, then
MakeMaker wins.
Returns an hash reference of build files found in the distribution. The keys are the filenames of the build files. The values
Returns the build file that you should use, even if there is more than one. Right now this is simple:
1. In the single build file distributions, return that build file
2. If you've specified a preference with prefer_module_build or
prefer_makemaker, use that.
3. If there is no preference (both are false), prefer Module::Build.
4. If no of those work, return nothing.
Returns the build command that you should use. This uses the logic of
preferred_build_file. It returns the result of either perl_command
or make_command.
Returns an anonymous hash to the paths to the build files, based on
the dist_dir argument to new and the return value of
build_files. The keys are the file names and the values are
the paths.
Has the file name returned by build_pl.
Has the file name returned by makefile_pl.
Has both the files returned by makefile_pl and build_pl.
Looks in %Config to see what perl discovered when someone built it if you
can use a make variant to build the distribution.
Returns ./Build, the script that Build.PL should have created, if
the distribution has a Build.PL. Otherwise it returns nothing.
Returns the perl currently running. This is the perl that you would use to run the Makefile.PL or Build.PL.
Returns a hash reference of the commands you can use to build the
distribution. The keys are the commands, such as make or perl Build.PL.
Returns true if the distro uses ExtUtils::Makemaker.
Returns true if MakeMaker is the only build system. Knowing that can cut down on the logic quite a bit since you don't have to choose between possibilities or preferences.
Returns the version of Makemaker installed for the perl running this code.
Returns true if this distribution uses Module::Build. This means that it
has a Build.PL and that the Build.PL actually uses Module::Build.
Returns true if Module::Build is the only build system. Knowing that can cut
down on the logic quite a bit since you don't have to choose between
possibilities or preferences.
Returns the version of Module::Build install for perl running this code.
Returns true if this distribution uses Module::Install.
Returns true if this distribution uses Module::Install and will
use the auto_install feature.
This is a very simple test right now. If it finds the string
auto_install in the build file, it returns true.
Returns the version of Module::Install.
Returns true if this distribution uses Module::Install::Compat and will
use the create_makefile_pl feature.
This is a very simple test right now. If it finds the string
create_makefile_pl in the build file, it returns true.
Returns true if Build.PL is a wrapper around Makefile.PL.
You may want to override or extend these, so they are methods.
Returns the string used for the Makefile.PL filename. Seems stupid until you want to change it in a subclass, which you can do now that it's a method. :)
Returns the string used for the Build.PL filename. Seems stupid until you want to change it in a subclass, which you can do now that it's a method. :)
Returns the module name of Makemaker, which is ExtUtils::MakeMaker.
Return the string representing the name for Module::Build.
Return the string representing the name for Module::Install. By default
this is inc::Module::Install.
Returns the directory that contains Module::Install. This is the distribution
directory because the module name is actually inc::Module::Install.
The name of the module that can get a list of used modules from a Perl file. By default this is Module::Extract::Use.
This source is in Github:
git://github.com/briandfoy/distribution-guess-buildsystem.git
brian d foy, <bdfoy@cpan.org>
Copyright (c) 2008-2010, brian d foy, All Rights Reserved.
You may redistribute this under the same terms as Perl itself.
| Distribution-Guess-BuildSystem documentation | Contained in the Distribution-Guess-BuildSystem distribution. |
# $Id$ package Distribution::Guess::BuildSystem; use strict; use warnings; no warnings; use subs qw(); use vars qw($VERSION); use Carp qw(carp); use Config qw(%Config); use Cwd qw(cwd); use File::Spec::Functions qw(catfile); use Module::Extract::VERSION; $VERSION = '0.12';
sub new { my %defaults = ( dist_dir => cwd(), prefer_module_build => 1, prefer_makemaker => 0, perl_binary => $^X, ); my( $class, %args ) = @_; bless { %defaults, %args }, $class; }
sub dist_dir { my( $self ) = shift; $self->_setting( 'dist_dir', @_ ); }
sub perl_binary { my( $self ) = shift; $self->_setting( 'perl_binary', @_ ); }
sub prefer_makemaker { my( $self ) = shift; $self->_setting( 'prefer_makemaker', @_ ); }
sub prefer_module_build { my( $self ) = shift; $self->_setting( 'prefer_module_build', @_ ); } sub _setting { my( $self, $key, $value ) = @_; if( @_ == 3 ) { $self->{$key} = $value; } return $self->{$key}; }
{ my @files = ( [ qw( has_makefile_pl makefile_pl ) ], [ qw( has_build_pl build_pl ) ], ); sub build_files { my %found; foreach my $pairs ( @files ) { my( $check, $file ) = @$pairs; $found{ $_[0]->$file() } = $_[0]->$file() if $_[0]->$check() } return \%found; } }
sub preferred_build_file { # preference doesn't matter in single build system cases return $_[0]->makefile_pl if $_[0]->uses_makemaker_only; return $_[0]->build_pl if $_[0]->uses_module_build_only; # preference now matter return $_[0]->build_pl if( $_[0]->prefer_module_build and $_[0]->uses_module_build ); return $_[0]->makefile_pl if( $_[0]->prefer_makemaker and $_[0]->uses_makemaker ); # absence of preference return $_[0]->build_pl if $_[0]->uses_module_build; return $_[0]->makefile_pl if $_[0]->uses_makemaker; # no build system? return; }
sub preferred_build_command { return $_[0]->build_command if $_[0]->preferred_build_file eq $_[0]->build_pl; return $_[0]->make_command if $_[0]->preferred_build_file eq $_[0]->makefile_pl; return; }
sub build_file_paths { my %paths; foreach my $file ( keys %{ $_[0]->build_files } ) { $paths{$file} = File::Spec->catfile( $_[0]->dist_dir, $file ); } return \%paths; }
sub makefile_pl_path { return unless $_[0]->has_makefile_pl; File::Spec->catfile( $_[0]->dist_dir, $_[0]->makefile_pl ); }
sub build_pl_path { return unless $_[0]->has_build_pl; File::Spec->catfile( $_[0]->dist_dir, $_[0]->build_pl ); }
sub _has_file { my( $self, $file ) = @_; my $path = File::Spec->catfile( $self->dist_dir, $file ); $self->{has}{$file} = $path if -e $path; $self->{has}{$file}; } sub has_build_pl { $_[0]->_has_file( $_[0]->build_pl ) }
sub has_makefile_pl { $_[0]->_has_file( $_[0]->makefile_pl ) }
sub has_build_and_makefile { $_[0]->has_build_pl && $_[0]->has_makefile_pl }
sub make_command { $_[0]->has_makefile_pl ? $Config{make} : () }
sub build_command { $_[0]->has_build_pl ? './Build' : () }
sub perl_command { $_[0]->has_build_pl ? $_[0]->perl_binary : () }
sub build_commands { my %commands; $commands{ $_[0]->make_command } = 1 if $_[0]->has_makefile_pl; $commands{ $_[0]->perl_command . " " . $_[0]->build_pl } = 1 if $_[0]->has_build_pl; return \%commands; }
sub _get_modules { my( $self, $path ) = @_; my $extractor = $self->module_extractor_class->new; $extractor->get_modules( $path ); } sub uses_makemaker { return unless $_[0]->has_makefile_pl; scalar grep { $_ eq $_[0]->makemaker_name } $_[0]->_get_modules( $_[0]->makefile_pl_path ) }
sub uses_makemaker_only { return unless $_[0]->has_makefile_pl; return if $_[0]->has_build_pl; return 1; }
sub makemaker_version { return unless $_[0]->uses_makemaker; my $version = $_[0]->_get_version( $_[0]->makemaker_name ); } sub _get_version { require Module::Extract::VERSION; my( $self, $module, @dirs ) = @_; @dirs = @INC unless @dirs; my $file = catfile( split /::/, $module ) . ".pm"; foreach my $dir ( @dirs ) { my $module = catfile( $dir, $file ); next unless -e $module; return Module::Extract::VERSION->parse_version_safely( $module ); } }
sub uses_module_build { return unless $_[0]->has_build_pl; scalar grep { $_ eq $_[0]->module_build_name } $_[0]->_get_modules( $_[0]->build_pl_path ); }
sub uses_module_build_only { return unless $_[0]->has_build_pl; return if $_[0]->has_makefile_pl; return 1; }
sub module_build_version { return unless $_[0]->uses_module_build; my $version = $_[0]->_get_version( $_[0]->module_build_name ); }
sub uses_module_install { return unless $_[0]->has_makefile_pl; scalar grep { $_ eq $_[0]->module_install_name } $_[0]->_get_modules( $_[0]->makefile_pl_path ) }
sub uses_auto_install { return unless $_[0]->has_makefile_pl && $_[0]->uses_module_install; $_[0]->_file_has_string( $_[0]->makefile_pl_path, 'auto_install' ); }
sub module_install_version { return unless $_[0]->uses_module_install; my $version = $_[0]->_get_version( $_[0]->module_install_name, $_[0]->module_install_dir ); }
sub uses_module_build_compat { return unless $_[0]->has_build_pl && $_[0]->uses_module_build; $_[0]->_file_has_string( $_[0]->build_pl_path, 'create_makefile_pl' ); }
sub build_pl_wraps_makefile_pl { return unless $_[0]->has_build_pl && $_[0]->has_makefile_pl; $_[0]->_file_has_string( $_[0]->build_pl_path, "Makefile.PL" ); } sub _file_has_string { my $fh; unless( open $fh, "<", $_[1] ) { carp "Could not open $_[1]: $!"; return; } while( <$fh> ) { return 1 if /\Q$_[2]/ } return; }
{ my @methods = qw( dist_dir build_files build_file_paths makefile_pl_path build_pl_path has_build_pl has_makefile_pl has_build_and_makefile make_command perl_command build_commands uses_makemaker makemaker_version uses_module_build module_build_version uses_module_install uses_auto_install module_install_version uses_module_build_compat build_pl_wraps_makefile_pl ); sub just_give_me_a_hash { my %hash = (); foreach my $method ( @methods ) { $hash{ $method } = $_[0]->$method(); } return \%hash; } }
sub makefile_pl { 'Makefile.PL' }
sub build_pl { 'Build.PL' }
sub makemaker_name { 'ExtUtils::MakeMaker' }
sub module_build_name { 'Module::Build' }
sub module_install_name { 'inc::Module::Install' }
sub module_install_dir { $_[0]->dist_dir }
sub module_extractor_class { 'Module::Extract::Use' } BEGIN { require Module::Extract::Use }
1;