App-Fetchware

 view release on metacpan or  search on metacpan

bin/fetchware  view on Meta::CPAN

        cmd_clean
        run
    )]
);
our @EXPORT_OK = @{$EXPORT_TAGS{TESTING}};

our $verbose = 0;
our $quiet = 0;
our $dry_run = 0;

# Be a modulino, so I can "use fetchware" in my test suite, so I can test
# bin/fetchware normally like any other perl module.
###BUGALERT## Add a test suite for run(), and also one that directly calls
#bin/fetchware to test its command line options.
run() unless caller();

sub run {
    # Set up a %SIG handler for CTRL-C or CTRL-Z on Windows.
    # And a %SIG handler for QUIT, which is CTRL-\
    #
    # Define a $parent_pid, so I can compare it to $$ (the current pid) to
    # see if I'm the child or the parent inside the sig handler to act
    # accordingly.
    my $parent_pid = $$;
    #
    # Be sure to prepend the first message that's printed with a newline to
    # ensure that it's printed on a brand new fresh line.
    @SIG{qw(INT TERM QUIT)} = sub {
        my $sig = shift;
        # Avoid a silly race condition where both the parent and the child both
        # try to run this code at the same time resulting in the one closing the
        # file and deleting the tempdir() before the other one resulting in
        # strange undefined warnings.
        #
        if ($parent_pid == $$) {
            msg <<EOM;
\nSignal [$sig] received. Cleaning up Fetchware.
EOM
            vmsg <<EOM;
Any temporary files that fetchware may have created will be deleted by
File::Temp's END block.
EOM

            cleanup_tempdir();
        }

        # Exit failure, because fetchware failed to properly install your
        # software while it was running, because the signal it received forced
        # it to exit prematurely making it questionable if fetchware succeeded
        # in properly and completely completing the actions you specified on the
        # command line and/or in a Fetchwarefile.
        exit 1;
    };

    vmsg 'Parsing command line options using Getopt::Long';

    GetOptions(
        # $VERSION is managed by dzil; therefore, I use eval to access it at
        # run time instead of compile time, so that I can test fetchware without
        # running dzil test.
        'version|V' => sub { eval 'say "Fetchware version $fetchware::VERSION"; '; exit 0},
        'help|h|?' => \&cmd_help,
        'verbose|v' => \$verbose,
        'quiet|q' => \$quiet,
        # Expose File::Temp's KEEP_ALL flag, and an easy feature to implement
        # that lets users easily ensure the tempdir stays around when needed.
        'keep-temp|K' => \$File::Temp::KEEP_ALL,
        ###BUGALERT### dry-run functionality is *not* implemented!!!
        #'dry-run|d' => \$dry_run,
    );


    # Getopt::Long is *only* used to determine dash and double dash style options
    # such as -v, --verbose, --help, -h, -?, etc....
    #
    # Below the first argument to fetchware is used to determine what fetchware
    # does.  If nothing is specified then help is printed.
    ###BUGALERT### Add a loop around @ARGV to support multiple Fetchwarefiles
    #or fetchware packages ending in .fpkg.
    eval { # Trap any fatal errors.
        vmsg 'Entering main eval{} block to trap errors.';
        ###BUGALERT### Should trapped exceptions with this eval cause fetchware
        #to cd to $original_cwd and then exit, so that the File::Temp's END
        #block can delete fetchware's source dir???
        # Or fetchware could print the path of this source dir and close, and
        # tell the user that they can clean it up with fetchware clean??
        # Also, add cmdline options to control what to do when this happens???
        vmsg 'Determining which command to run based on command line options.';
        my $command;
        @ARGV ? ($command = shift @ARGV) : ($command = '');
        if ($command eq 'install') {
            cmd_install(@ARGV);
        } elsif ($command eq 'uninstall') {
            cmd_uninstall(@ARGV);
        } elsif ($command eq 'new') {
            cmd_new(@ARGV);
        } elsif ($command eq 'upgrade') {
            cmd_upgrade(@ARGV);
        } elsif ($command eq 'upgrade-all') {
            cmd_upgrade_all(@ARGV);
        } elsif ($command eq 'list') {
            cmd_list(@ARGV);
        } elsif ($command eq 'look') {
            cmd_look(@ARGV);
        } elsif ($command eq 'clean') {
            cmd_clean(@ARGV);
        } elsif ($command eq 'help') {
            cmd_help(@ARGV);
        } else {
            cmd_help(@ARGV);
        }
        # Exit success, because if any of the main subroutines run into any
        # problems they die() exceptions, which get caught in eval above, and
        # warn()ed below, and fetchware exits 1 for failure.
        vmsg 'Fetchware ran successfully! Exiting with status of 0 for success!';
        exit 0;
    };
    # If a fatal error was thrown print it to STDERR and exit indicating failure.
    if ($@) {
        # Set File::Temp's $KEEP_ALL so user can troubleshoot what happend
        # without having to bother to use --keep-all.

bin/fetchware  view on Meta::CPAN

=item *

L<App::Fetchware/"USING YOUR App::Fetchwarefile WITH FETCHWARE"> - Shows how to
use your newly created fetchwarefile with fetchware.

=item *

L<App::Fetchware/"App::Fetcwhare'S FETCHWAREFILE CONFIGURATION OPTIONS"> - Details
all of fetchware's configuration options that you can use to further customize
your Fetchwarefile.

=item *

L<App::Fetchware/"FURTHER CUSTOMIZING YOUR FETCHWAREFILE"> - Shows you how to use
embed Perl inside your Fetchwarefile to change fetchware's behavior as needed
to make fetchware work with programs that use different conventions and
assumptions that fetchware makes.

=item *

L<App::Fetchware/"EXAMPLE FETCHWAREFILES"> - Details how to customize a
Fetchwarefile for popular programs such as Apache, Nginx, PHP, MariaDB, and
Postgres.

=item *

L<App::Fetchware/"CREATING A FETCHWARE EXTENSION"> - Details how to replace the
module that implements fetchware's behavior, App::Fetchware, with a completely
different module implementing completely different behavior. These fetchware
extensions can even be shared with everyone else on CPAN. See
L<App::FetchwareX::HTMLPageSync> for an example.

=back

=head1 COMMANDS

Each command maps to one operation a package manager can do. C<install>,
C<upgrade>, and C<uninstall>. There is also C<new> to create new Fetchwarefiles
without bothering with a text editor. And fetchware's way of upgrading all
packages with C<upgrade-all>. Fetchware can also list its installed packages
with C<list>. And C<look> is similar to Perl's original CPAN client's look
command that downloads and unarchives the package, so you can "look" at it.
The C<clean> command deletes any unused, leftover temporary files and
directories Fetchware has unintentionally left in your system's temporary
directory.

=head2 new

    fetchware new <name of program>

C<new> asks you a bunch of questions, and uses the answers you provide in
addition to the contents of the directory listing fetchware downloads based on
the C<lookup_url> you give fetchware, to create a Fetchwarefile for you with all
the mandatory options filled in. It also gives you the opportunity to add any
additional options that you may want to use. C<new> also gives you a chance to
edit the Fetchwarefile it created for you manually in your editor. Set the
C<EDITOR> environment variable to pick which editor to use, or leave it empty,
and fetchware will ask you what editor you would like to use.

C<new> finishes by asking if you would like fetchware to go ahead and install
the Fetchwarefile it has just created for you. If you say yes, then fetchware
will install it, or if you say no, fetchware will skip installing it for you,
and print out the path to the Fetchwarefile it just created for you.

You can install that Fetchwarefile later with:

    fetchware install path/to/your/some-program.Fetchwarefile

For more details about fetchware's configuration files Fetchwarefiles see
L<App::Fetchware/CREATING A App::Fetchware FETCHWAREFILE>

=head2 install

    fetchware install <path to program.Fetchwarefile>

    fetchware install <path to program.fpkg>

C<install> parses the given Fetchwarefile or uses the embeded Fetchwarefile
inside the fetchware package you specify. Then C<install> I<install>s your
program as you specified in your Fetchwarefile. 

By default executes the commands:

=over

=item 1. C<./configure>

=item 2. C<make>

=item 3. C<make install>

=back

You can use the Fetchwarefile configuration options C<make_options> and
C<configure_options> to customize how your program is build and installed.
C<make_options> specifies command line options that are added before C<make> is
run each time by Fetchware. And C<configure_options> specifies options to the
first AutoTools command, C<./configure> that customizes how your program is
built and installed.

    ...
    prefix '/usr/local';
    make_options '-j 4';
    configure_options '--enable-mpm --enable-so';

Or, you can use Fetchwarefile's more generic configuraton options. You cannot
use both C<build_options> and any of C<prefix>, C<make_options>,
C<configure_options> at the same time.  C<build_commands> specifies alternate
commands to build the program replacing C<./configure> and C<make>, and you can
also specify the C<install_commands> to replace C<make install> with some other
command or commands that install your program.

    ...
    # build_commands and install_commands Fetchwarefile example.
    build_commands './Configure', 'make';

    install_commands 'make test', 'make install';

    ...

See L<App::Fetchware/"App::Fetchware'S FETCHWAREFILE CONFIGURATION OPTIONS> for
more details on these configuration options.

bin/fetchware  view on Meta::CPAN



###BUGALERT###Should I implement dryrun functionality???
#=head2 -d or --dryrun
#
#Just prints out what fetchware will do when you run fetchware. No external
#commands are run, and fetchware itself doesn't read or create any files
#including any temporary directories.
#
####BUGALERT### dryrun functionality is not implemnted.
## Should be easy to implement in run_prog(), and create a sub like
## skip_all_unless_release_testing() to test for -d.

###BUGALERT###What about -f and --force too??????
#=head2 -f or --force
#
####BUGALERT### Do I want or need --force???
#



###BUGALERT###Actually add better examples of these awesome features and more
#details.
##TODO##These unique qualities give fetchware unique abilites that other package
##TODO##managers don't have.
##TODO##
##TODO##=head2 Deploying with Fetchware Packages
##TODO##
##TODO##Just like how you can create a repository for custom rpms or C<.deb>s, you can
##TODO##do the same with fetchware packages, which brings with it the full power of your
##TODO##software's build environment, and fetchware's Fetchwarefile's support for
##TODO##embeding Perl giving you great flexibility.
##TODO##
##TODO#####BUGALERT### Actually give a useful example of this!
##TODO##
##TODO##=head2 Cross-platform Deployment with Fetchware Packages
##TODO##
##TODO##Unlike other package formats, fetchware's is cross-platform, and supports the
##TODO##same platforms, the software's build environment does. You can take advantage of
##TODO##this to deploy your software as a fetchware package across whatever number of
##TODO##architectures your software's build system supports.
##TODO##
##TODO##Note, it will have to be built on each platform when the package is installed.
##TODO##
##TODO#####BUGALERT### Give more details about this!
##TODO##
##TODO##=head2 Deploying to Systems without a Build Environment
##TODO##
##TODO#####BUGALERT### This doesn't actually work now!!!
##TODO##
##TODO##Fetchware is flexible enough, using the C<no_rebuild> and C<no_lookup>
##TODO##configuration options, to be configured and compiled on one computer, and then
##TODO##B<only> installed on any additional servers that install that fetchware package.
##TODO##
##TODO##So, instead of needing gcc, devel versions of libraries, and make, the servers
##TODO##you deploy your fetchware package on compile using these options will only need
##TODO##make installed instead of an entire build environment (Actually, they'll need
##TODO##whatever commands your Fetchwarefile's C<install_commands> uses, which is
##TODO##C<make install> by default.
##TODO##
##TODO#####BUGALERT### Actually implemente this cool idea, and fix docs to say that to
##TODO###actually lookup and actually build the package use the --force option, which
##TODO###also needs to be implemented.









###BUGALERT### Actually implement croak or more likely confess() support!!!






( run in 0.501 second using v1.01-cache-2.11-cpan-d7a12ab2c7f )