#!/usr/bin/perl

# Copyright (c) 2018, cPanel, L.L.C.
# All rights reserved.
# http://cpanel.net/
#
# This is free software; you can redistribute it and/or modify it under the same
# terms as Perl itself.  See the LICENSE file for further details.

use strict;
use warnings;

use App::PPK ();

=head1 NAME

ppk - Perl Packager

=head1 SYNOPSIS

    ~$ ppk main.pl --dists Filesys-POSIX/ -o script
    ~$ ppk main.pl --dists Filesys-POSIX-0.9.tar.gz -o script
    ~$ ppk main.pl --modules lib/Foo/Bar.pm=Foo::Bar -o script
    ~$ ppk main.pl --dists Filesys-POSIX/ -c

=head1 DESCRIPTION

ppk provides a means of packaging a main Perl script, along with any number
of dependencies in the form of modules explicitly specified by path and their
equivalent Perl names; or, entire Perl dists in the form of tarballs or paths
to unarchived dists, which contain a MANIFEST in either case.

=head1 ARGUMENTS

=over

=item I<main>

The main entry point script around which a standalone wrapper script will be
constructed.  All arguments passed to the wrapper script will be passed to this
main script.

=item B<--dists> I<dists ...>

=item B<-d> I<dists ...>

A single instance of the C<--dists> flag, followed by the paths of any number
of Perl dists (tarballs or directories) can be passed.  All files in the
C<lib/> directory listed in C<MANIFEST> will be copied into the standalone
script.

=item B<--modules> I<file=module::name ...>

A single instance of the C<--modules> flag, followed by the paths and Perl
module names as pairs separated by an equals (=) sign allow the user to archive
only specific modules in disparate locations, into the standalone script.

=item B<--deps-from> I<depsfile>

Specifies a file from which dependencies are read.  If I<depsfile> is listed as
a single dash ('-') character, then standard input will be read from.

The format of the file is simple; either dists or modules can be listed, along
with empty lines, lines containing whitespace, or comments denoted with the '#'
character.  Dependencies assume the following syntax:

=over

=item B<module> I<module::name> I<file>

The file named for I<file> should be packaged as I<module::name> in the static
script built.

=item B<dist> I<dist>

The file or directory referred to by I<dist> will be included in the static
script built.

=back

Example:

    #
    # Script build dependencies
    #
    dist Filesys-POSIX-0.9.1.tar.gz
    dist Mail-Alias-Reader-0.02.tar.gz
    module Foo::Bar::Baz arbitrary/location/Foo/Bar/Baz.pm
    module Foo::Bar::Baz/Boo arbitrary/location/Foo/Bar/Baz/Boo.pm

=item B<--output> I<script>

=item B<-o> I<script>

This flag specifies the name of the output standalone script file to be created
or overwritten.

=item B<--check>

=item B<-c>

This flag causes the given main entry point script to be checked against any
extracted dists, or modules specified, in a temporary directory.

=item B<--header> I<file>

=item B<-H> I<file>

Allows the specification of a header file to be inserted at the top of the
output file directly after the Perl shebang.

=item B<--desc> I<string>

=item B<-D> I<string>

Specifies a value to insert into any instance of the C<$Desc$> template that
may occur in a header.  Requires B<--header> or B<-h> to be passed.

=back

=head1 RATIONALE

This tool does NOT perform automatic dependency calculation in the form of
either runtime or static analysis; rather, by design, it is meant to allow
for the granular selection of dependencies to target specific environments,
creating standalone Perl scripts in the smallest footprint feasible.

=head1 MECHANISM

The standalone scripts generated by C<ppk> are composed of a standard
bootstrapping wrapper, and a C<__DATA__> section containing the main entry
point script, and all dependencies, in a base64-encoded tarball created by
tar(1) and gzip(1).  The Perl interpreter used to execute the standalone
script will be used to execute the main entry point script, passing all
arguments from the standalone script's C<@ARGV> array directly to the
main entry point script.

Upon initial execution of a generated standalone script, the main entry point
script, as well as its dependencies, are extracted into a temporary directory
that is to be removed upon natural or forced program termination.

=cut

exit App::PPK->run();

__END__

=head1 COPYRIGHT

Copyright (c) 2018, cPanel, L.L.C.  All rights reserved.  This is free software;
you can redistribute it and/or modify it under the same terms as Perl itself.
See L<perlartistic> for further details.
