NAME

App::Build - extends Module::Build to build/install/configure entire applications, not just modules and programs

SYNOPSIS

This module is used within a Build.PL script directly or
it can be subclassed to provide extra capabilities.

use App::Build;

shift(@ARGV) if ($#ARGV > -1 && $ARGV[0] eq "Build");

my $build = App::Build->new (
    dist_name         => "App-Build",
    dist_version_from => "lib/App/Build.pm",
    dist_author       => "stephen.adkins\@officevision.com",
    extra_dirs        => [ "htdocs", "cgi-bin", "etc", "var" ],
    license           => "perl",
    build_requires => {
        "App::Build"  => 0,  # needed for installing the software
    },
);

$build->create_build_script;

DESCRIPTION

The vision of App::Build is to make installing entirely functional perl applications (particularly web applications) as easy as installing individual models from CPAN.

An ISP customer (or other unprivileged user) who has shell access should be able to install any number of available applications from CPAN simply by typing the usual

perl -MCPAN -e "install App-Build-Foo"

and the "Foo" application is installed on his account.

The goal is to make installing entire perl applications as easy as installing a simple set of modules. App::Build is a subclass of Module::Build.

App::Build does this by implementing the following features.

1. Distributions that use App::Build instead of Module::Build can easily install files to other places, besides just "lib" and "bin". e.g. "htdocs", "cgi-bin", "etc". (see the "extra_dirs" argument in the example in the Synopsis above)

2. App::Build also adds a hook into the "install" action to call the "configure()" method. If you are subclassing App::Build, you can override this method and perform customized configuration tasks.

INCLUDED APPLICATIONS AND EXTERNAL APPLICATIONS

Although the distribution primarily supports the deployment of an application whose files are included in the distribution, it also supports deployment of applications which are not included or are not on CPAN at all.

Anyone who finds a useful perl application somewhere (i.e. "Foo") can write a small perl distribution called App-Build-Foo and upload it to CPAN. When someone uses the CPAN shell, they can install the application simply by typing

install App-Build-Foo

Within the App-Build-Foo distribution would be a module, App::Build::Foo, which would be a subclass of App::Build. It would contain any specific logic necessary to download and install the Foo application.

All applications installed with App::Build (and its derivatives) should conform to a set of standards (see below) so that when multiple applications are installed, they are integrated seamlessly and work side by side.

APPLICATION INSTALLATION REQUIREMENTS

The following are the requirements of all App::Build installations.

* The installation MUST be useful to ISP's (internet
  service providers) and ASP's (application service
  providers) such that the software is installed
  in such a way that each customer of theirs may use
  it without any interactions with other customers.

* The installation SHOULD allow for multiple versions
  even for an unprivileged user (an ISP/ASP customer).
  This allows a user to install a new version of an
  application and evaluate it and run it in parallel
  with an existing version of the application.

APPLICATION INSTALLATION STANDARDS

The following are additional standards of all App::Build installations.

* TBD

App::Build CONFIGURABILITY

Since App::Build uses App::Options, App::Options strips off all of the --var=value options out of @ARGV and makes them available via the global %App::options hash.

This will be put to good use sometime in the future.

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.

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.

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.

_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.

_prefix()

This returns the "install_base" property if it was supplied on the command line. i.e.

perl Build.PL install_base=/usr/mycompany/prod

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.

_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.

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.

_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.

_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.

_get_extra_dirs_attributes()

Gets the hash of all extra_dirs attributes.

process_app_files()

During "./Build" (which calls ACTION_code()), the process_app_files() method copies files from the extra_dirs to their appropriate locations under "blib".

_find_all_files()

This is used by process_app_files() to get the list of files under "extra_dirs" to copy to "blib".

rscan_dir()

Don't include CVS and RCS files.

install_base_relative()

This method is overridden to indicate that the relative directory of an "extra_dir" is the same as the dir/type itself.

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.

perllocal_pod()

This creates the name of the "perllocal.pod" file that needs to be written with the version information of the distribution being installed.

fix_shebang_line()

This method is only overridden in order to return the level of fixes performed.

0 = no #! line
1 = found #! line, but not a perl script
2 = found #! line, fixed to current perl interpreter

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.

has_config_data()

No. We're not using config data. Always return FALSE.

ACTION_install()

This method is overridden to put in the configure() hook so that a module which extends App::Build can implement the configure() method. Then the configure() method will run when "./Build install" is invoked.

perllocal_install()

This method should be modelled after ExtUtils::Command::MM::perllocal_install so that it writes the same information at MakeMaker does.

It currently is a stub, waiting to be implemented

configure()

Do nothing. This method is a hook that can be overridden by a subclass of App::Build. The idea is that after installing files, you might need to run additional code to configure the application.

ACKNOWLEDGEMENTS

* Author:  Stephen Adkins <stephen.adkins@officevision.com>
* License: This is free software. It is licensed under the same terms as Perl itself.

SEE ALSO