#!/usr/bin/perl

use strict;
use warnings;

use App::eachperl;
use Getopt::Long qw( :config no_ignore_case pass_through );

STDOUT->autoflush;

GetOptions(
   'no-system-perl' => \( my $NO_SYSTEM_PERL ),
   'no-test'        => \( my $NO_TEST ),
   'since=s'        => \( my $SINCE_VERSION ),
   'until=s'        => \( my $UNTIL_VERSION ),
   'reverse|r'      => \( my $REVERSE ),
   'stop-on-fail|s' => \( my $STOP_ON_FAIL ),
) or exit 1;

exit App::eachperl->new(
   no_system_perl => $NO_SYSTEM_PERL || $ENV{NO_SYSTEM_PERL},
   no_test        => $NO_TEST,
   since_version  => $SINCE_VERSION,
   until_version  => $UNTIL_VERSION,
   reverse        => $REVERSE,
   stop_on_fail   => $STOP_ON_FAIL,
)->run( @ARGV );

__END__

=head1 NAME

F<eachperl> - a wrapper script for iterating multiple F<perl> binaries

=head1 SYNOPSIS

   $ eachperl exec -E 'say "Hello"'

     --- perl5.30.0 --- 
   Hello

     --- bleadperl --- 
   Hello

   ----------
   perl5.30.0          : 0
   bleadperl           : 0

=head1 DESCRIPTION

This script iterates over a collection of multiple F<perl> installations,
allowing the same command to be invoked across each of them. The list of
available perl binaries is given by a config file (see L</CONFIG>). The main
mode of operation is that each perl binary in turn is executed with supplied
commandline arguments; though several other convenience commands are provided
for common actions.

=head1 COMMANDS

=head2 list

Prints a list of each configured F<perl> binary and the detected version.

All configured versions are printed; the selected versions are prefixed by an
asterisk.

   $ eachperl --since 5.31 list
     perl5.30.0: /usr/bin/perl5.30.0 (v5.30.0)
   * bleadperl: /home/user/bin/bleadperl (v5.32.0)

=head2 exec

The default command. Invokes each F<perl> binary with the given arguments.

Afterwards a table of exit codes is printed, to summarize the run in case the
output was long and scrolled away.

   $ eachperl exec -E 'say $]'

     --- perl5.30.0 --- 
   5.030000

     --- bleadperl --- 
   5.032000

   ----------
   perl5.30.0          : 0
   bleadperl           : 0

The word C<exec> is optional if the commandline otherwise begins with a
hyphenated option name - which it usually does for short one-line scripts
with C<-M> or C<-E>

   $ eachperl -E 'say 1+2'

   $ eachperl -MConfig -E 'say $Config{nvsize}'

=head2 install

A convenient wrapper for installing a module using L<CPAN>.

   $ eachperl install A::CPAN::Module

When the module name is exactly C<.> this command is an alias for
C<install-local>.

=head2 install-local

Install the distribution in the current working directory by directly invoking
the build script.

This command implies the C<--no-system-perl> option.

=head2 test

A convenient wrapper for testing a module using L<CPAN>.

   $ eachperl test A::CPAN::Module

When the module name is exactly C<.> this command is an alias for
C<test-local>.

=head2 test-local

Install the distribution in the current working directory by directly invoking
the build script.

=head2 build-then-perl

Builds and tests the distribution in the current working directory, then
invokes perl on the remaining commandline. Remember to include C<-Mblib> to
instruct the perl to use the newly-built code

   $ eachperl build-then-perl -Mblib -MMy::Module -E'say My::Module::func()'

=head2 modversion

Prints the version of the named module.

   $ eachperl modversion CPAN
   perl5.30.0: 2.22
   bleadperl: 2.27

=head2 modpath

Prints the path to the named module.

   $ eachperl modpath CPAN
   perl5.30.0: /usr/share/perl/5.30/CPAN.pm
   bleadperl: /home/user/perl5/perlbrew/perls/bleadperl/lib/5.32.0/CPAN.pm

=head1 OPTIONS

=head2 --since VER

Selects only perl versions that are at least as new as the requested version.
Any perl binaries older than this will be skipped.

=head2 --until VER

Selects only perl versions that are at least as old as the requested version.
Any perl binaries newer than this will be skipped.

=head2 --reverse, -r

Reverses the order in which perl versions are invoked.

=head2 --stop-on-fail, -s

Stops running after the first failure. Without this option, every version is
attempted even if some fail.

Useful when combined with C<--reverse> to test a module to see how far back in
earlier perl versions it will support.

=head2 --no-system-perl

Deselects the system perl version. The perl version matching the system
version (or rather, the version running this script) is skipped.

=head2 --no-test

Skip the C<Build test> or C<make test> step when building a local
distribution.

=head1 CONFIG

The list of available perls is given by a config file, which is found in the
user's home directory at F<$HOME/.eachperlrc>. This should be a file in INI
format.

In addition, a file of the same name can be placed at the current working
directory (presumably the root directory of a project) to override any
settings in the main file.

The following keys are recognised

=head2 perls

A space-separated list of command names. Each should be searchable using
C<$PATH> but need not be specified as a fully-qualified path.

   perls = perl5.30.0 bleadperl

=head2 Default Commandline Options

Default values for the following commandline options can also be supplied:

   since_version = 5.16
   until_version = 5.30

=head1 AUTHOR

Paul Evans <leonerd@leonerd.org.uk>
