App-Build
view release on metacpan or search on metacpan
lib/App/Build.pm view on Meta::CPAN
The following are additional standards of all App::Build
installations.
* TBD
=head1 App::Build CONFIGURABILITY
Since App::Build uses App::Options, App::Options makes all the
of the --var=value options available via the global %App::options hash.
App::Build however does not remove the --var=value options from @ARGV.
This will be put to good use sometime in the future.
=head1 FIX-UPS
Module::Build complains if the PREFIX environment variable is
set. App::Build doesn't. It just ignores it.
The CPAN shell (for some reason I don't understand) runs Build.PL
as "perl Build.PL Build" and this fails.
App::Build just throws away the "Build" so that the default "build"
action is invoked.
Module::Build deprecated the PREFIX option to Makefile.PL
(i.e. "perl Makefile.PL PREFIX=/usr/foo"). App::Build just makes
the PREFIX option a synonym for "install_base", which does
essentially the same thing.
=cut
delete $ENV{PREFIX}; # Module::Build protests if this var is set
# Enable the continued use of the PREFIX=$PREFIX option
# (from Makefile.PL and ExtUtils::MakeMaker) by making it
# an alias for the "install_base" option of Module::Build.
######################################################################
# BUILD: enhancements to "perl Build.PL"
######################################################################
=head1 METHODS
The documentation of the methods below is not for users of the
App::Build module (who are writing Build.PL scripts), but for people
interested in the internals of how App::Build extends Module::Build.
It is also so that I can remember what I was doing so that if the
internals of Module::Build change, I can maintain this code.
=head2 new()
We override the new() method in order to enhance the install paths.
In the future, we may also download and unpack external perl
distributions.
=cut
sub new {
my ($class, %args) = @_;
my $obj = $class->SUPER::new(%args);
$obj->_enhance_install_paths() if $obj->_prefix;
$obj->_get_supporting_software();
return($obj);
}
=head2 read_config()
Overridden to transparently call C<_enhance_install_paths()>.
=cut
sub read_config {
my ($self) = @_;
$self->SUPER::read_config();
$self->_enhance_install_paths() if $self->_prefix;
}
=head2 install_base()
Overridden to transparently call C<_enhance_install_paths()>.
=cut
sub install_base {
my ($self, @args) = @_;
my $ret = $self->SUPER::install_base(@args);
$self->_enhance_install_paths() if $self->_prefix;
return $ret;
}
=head2 _get_supporting_software()
Downloads supporting software (if necessary), unpacks it, compiles it,
and installs it.
=cut
sub _get_supporting_software {
my ($self) = @_;
my $tag = $self->_app_tag();
my $url = $App::options{"$tag.url"}; # check to see if there was software to download
if ($url) {
my $file = $App::options{"$tag.file"};
if (!$file) {
$file = $url;
$file =~ s!.*/!!;
}
($file) || die "File [$tag.file] does not exist";
my $subdir = $App::options{"$tag.subdir"};
if (!$subdir) {
$subdir = $file;
$subdir =~ s!\.tar.gz$!!;
$subdir =~ s!\.tgz$!!;
}
($subdir) || die "Subdir [$tag.subdir] does not exist";
my $archive_dir = $App::options{archive_dir} || "archive";
mkdir($archive_dir) if (! -d $archive_dir);
my $archive = "$archive_dir/$file";
(-d $archive_dir) || die "Archive Directory [$archive_dir] does not exist";
(-w $archive_dir) || die "Archive Directory [$archive_dir] not writeable";
$self->mirror($url, $archive);
$self->unpack($archive, "unpack", $subdir);
}
}
=head2 _app_tag()
This lowercase-ifies the dist_name, removes "app-build-" from the front,
and returns it as the "application tag".
Therefore, a distribution called "App-Build-Kwiki" would have an
"app_tag" of "kwiki". An "app_tag" is used for looking up configuration
settings in the %App::options hash produced by App::Options.
=cut
sub _app_tag {
my ($self) = @_;
my $dist_name = $self->dist_name();
lib/App/Build.pm view on Meta::CPAN
or (synonymously) ...
perl Build.PL PREFIX=/usr/mycompany/prod
If the install_base was not supplied, the "prefix" out of perl's own
Config.pm is returned. So if perl is installed in "/usr/local/bin", then
"/usr/local" is returned.
If perl is installed in "/usr/bin", then "/usr" is returned.
=cut
sub _prefix {
my ($self) = @_;
my $prefix = $self->{properties}{install_base} || $self->{config}{prefix};
return($prefix);
}
=head2 _enhance_install_paths()
The install_sets (core, site, vendor) as set from values in perl's own
Config.pm are enhanced to include the absolute directories in which
the extra_dirs will be installed.
=cut
sub _enhance_install_paths {
my ($self) = @_;
my $properties = $self->{properties};
my $install_sets = $properties->{install_sets};
my @extra_dirs = $self->_get_extra_dirs();
my $prefix = $self->_prefix();
my $tag = $self->_app_tag();
my ($path);
foreach my $dir (@extra_dirs) {
$path = $App::options{"$tag.$dir.dir"} || File::Spec->catdir($prefix, $dir);
$install_sets->{core}{$dir} = $path;
$install_sets->{site}{$dir} = $path;
$install_sets->{vendor}{$dir} = $path;
}
}
######################################################################
# BUILD: enhancements to "./Build"
######################################################################
=head2 ACTION_code()
We override ACTION_code() to copy additional directories of files
needed to install the application.
When you invoke "./Build", the method $self->ACTION_build() gets
called on this object. This, in turn, calls $self->ACTION_code()
and $self->ACTION_docs(). Each of these methods copies files into
the "blib" subdirectory in preparation for installation.
=cut
sub ACTION_code {
my ($self) = @_;
$self->SUPER::ACTION_code(); # call this first (creates "blib" dir if necessary)
$self->process_app_files(); # NEW. call this to copy "extra_dirs" to "blib"
}
=head2 _added_to_INC()
We override this method to ensure that "lib" (libraries to be installed)
is added to the front of @INC.
This is because we often want to use the (latest) enclosed module as
the installing module, even if it has already been installed.
=cut
sub _added_to_INC {
my $self = shift;
my %seen;
$seen{$_}++ foreach $self->_default_INC;
unshift(@INC,"lib");
return grep !$seen{$_}++, @INC;
}
=head2 _get_extra_dirs()
Gets the list of extra_dirs to be installed.
The extra_dirs may be specified in the Build.PL in
a variety of ways.
It can be a scalar (comma-separated list of directories),
an array ref of directories, or a hash ref where the
keys are the directories.
If extra_dirs is specified with a hash ref, the hash values
are hashrefs of attributes. i.e.
extra_dirs => {
var => {
dest_dir => "var",
},
htdocs => {
dest_dir => "htdocs",
},
"cgi-bin" => { # any dir ending in "bin" contains executable scripts
dest_dir => "cgi-bin",
},
support => {
dest_dir => "support",
executable => 1, # treat contents as executable scripts
},
},
So far, only the "dest_dir" attribute is defined. The "dest_dir" attribute
can be overridden using the "--install_path" parameter.
=cut
sub _get_extra_dirs {
my ($self) = @_;
my $properties = $self->{properties};
my @extra_dirs = ();
if ($properties->{extra_dirs}) {
if (ref($properties->{extra_dirs}) eq "ARRAY") {
lib/App/Build.pm view on Meta::CPAN
my $extra_dirs = $self->_get_extra_dirs_attributes();
my $blib = $self->blib;
my ($contains_executables, $result, $target_file);
foreach my $dir (@extra_dirs) {
if (-d $dir) {
$contains_executables = $extra_dirs->{$dir}{executable};
$contains_executables = ($dir =~ /bin$/) ? 1 : 0 if (!defined $contains_executables);
$path = File::Spec->catfile($blib, $dir),
File::Path::mkpath($path);
$files = $self->_find_all_files($dir);
my ($should_be_executable);
while (my ($file, $dest) = each %$files) {
$target_file = File::Spec->catfile($blib, $dest);
$result = $self->copy_if_modified(from => $file, to => $target_file) || "";
if ($result && $contains_executables) {
$self->fix_shebang_line($result);
$self->make_executable($result)
if $self->_should_be_executable($result);
}
}
}
}
}
sub _should_be_executable {
my ($self, $file) = @_;
# copied from Module::Build::Base::fix_shebang_line
my $FIXIN = IO::File->new($file) or die "Can't process '$file': $!";
local $/ = "\n";
chomp(my $line = <$FIXIN>);
if ($line =~ /^\s*\#!\s*/) {
return 1;
} else {
return 0;
}
}
=head2 _find_all_files()
This is used by process_app_files() to get the list of files under "extra_dirs"
to copy to "blib".
=cut
sub _find_all_files {
my ($self, $dir) = @_;
return {} unless -d $dir;
return { map { $_, $_ } @{ $self->rscan_dir($dir, sub { -f $_ }) } };
}
=head2 rscan_dir()
Don't include CVS, RCS, and SVN (*/.svn/*) files.
=cut
sub rscan_dir {
my ($self, $dir, $pattern) = @_;
my $files = $self->SUPER::rscan_dir($dir, $pattern);
my @files = grep(!/[\/\\](CVS|RCS|\.svn)[\/\\]/, @$files);
return \@files;
}
######################################################################
# INSTALL: enhancements to "./Build install"
######################################################################
=head2 packlist()
This creates the name of the "packlist" file that needs to be
written with the list of all of the files that get installed.
=cut
sub packlist {
my ($self) = @_;
# Write the packlist into the same place as ExtUtils::MakeMaker.
my $archdir = $self->install_destination('arch');
my @ext = $self->module_name ? split /::/, $self->module_name :
$self->dist_name;
my $packlist = File::Spec->catfile($archdir, 'auto', @ext, '.packlist');
return($packlist);
}
=head2 install_map()
This method is only overridden in order to put in the fix so
that it creates a .packlist based on dist_name if the module_name
is not specified.
=cut
sub install_map {
my ($self, $blib) = @_;
$blib ||= $self->blib;
my %map;
foreach my $type ($self->install_types) {
my $localdir = File::Spec->catdir( $blib, $type );
next unless -e $localdir;
if (my $dest = $self->install_destination($type)) {
# thins alters the behavious of Module::Build, and
# looks into the implementation
if ( $self->install_path($type)
&& !File::Spec->file_name_is_absolute($dest)) {
$dest = File::Spec->catdir( $self->_prefix, $dest );
}
$map{$localdir} = $dest;
} else {
# Platforms like Win32, MacOS, etc. may not build man pages
die "Can't figure out where to install things of type '$type'"
unless $type =~ /^(lib|bin)doc$/;
}
}
my $extra_dirs_attrs = $self->_get_extra_dirs_attributes();
foreach my $dir ( $self->_get_extra_dirs() ) {
my $dest = $extra_dirs_attrs->{$dir}{dest_dir};
( run in 0.736 second using v1.01-cache-2.11-cpan-0bb4e1dffa6 )