App-Multigit
view release on metacpan or search on metacpan
lib/App/Multigit.pm view on Meta::CPAN
L<report|App::Multigit::Repo/"report(%data)"> in App::Multigit::Repo implements
a sensible directory-plus-output transformation for common usage.
use curry;
my $future = App::Multigit::each(sub {
my $repo = shift;
$repo
->run(\&do_a_thing)
->then($repo->curry::run(\&do_another_thing))
->then($repo->curry::report)
;
});
The subref given to C<run> is passed the C<%data> hash from the previous
command. C<%data> is pre-prepared with blank values, so you don't have to check
for definedness to avoid warnings, keeping your subrefs nice and clean.
sub do_a_thing {
my ($repo_obj, %data) = @_;
...
}
Thus you can chain them in any order.
use curry;
my $future = App::Multigit::each(sub {
my $repo = shift;
$repo
->run(\&do_another_thing)
->then($repo->curry::run(\&do_a_thing))
->then($repo->curry::report)
;
});
Observe also that the interface to C<run> allows for the arrayref form as well:
use curry;
my $future = App::Multigit::each(sub {
my $repo = shift;
$repo
->run([qw/git checkout master/])
->then($repo->curry::run(\&do_another_thing))
;
});
A command may fail. In this case, the Future will fail, and if not handled, the
script will die - which is the default behaviour of Future. You can use
L<else|Future/else> to catch this and continue.
use curry;
my $future = App::Multigit::each(sub {
my $repo = shift;
$repo
->run([qw{git rebase origin/master}])
->else([qw{git rebase --abort])
->then($repo->curry::report)
;
});
The failure is thrown in a manner that conforms to the expected Future fail
interface, i.e. there is an error message and an error code in there. Following
these is the C<%data> hash that is consistent to all invocations of C<run>. That
means that when you do C<else>, you should be aware that there will be two extra
parameters at the start of the argument list.
use curry;
my $future = App::Multigit::each(sub {
my $repo = shift;
$repo
->run([qw{git rebase origin/master}])
->else(sub {
my ($message, $error, %data) = @_;
...
})
->then($repo->curry::report)
;
});
In the case that you don't care whether the command succeeds or fails, you can
use L<finally|App::Multigit::Repo/finally> to catch the failure and pretend it
wasn't actually a failure.
use curry;
my $future = App::Multigit::each(sub {
my $repo = shift;
$repo
->run([qw{git rebase origin/master}])
->finally($repo->curry::report)
;
});
Despite the name, C<finally> does not have to be the final thing. Think
"finally" as in "try/catch/finally". In the following code, C<finally> simply
returns the C<%data> hash, because C<finally> transforms a failure into a
success and discards the error information.
use curry;
my $future = App::Multigit::each(sub {
my $repo = shift;
$repo
->run([qw{git rebase origin/master}])
->finally(sub { @_ })
->then(\&carry_on_camping)
->then($repo->curry::report)
;
});
=head4 Arrayref form
In the arrayref form, the C<$command> is passed directly to C<run> in
L<App::Multigit::Repo|App::Multigit::Repo/"run($command, [%data])">. The
Futures returned thus are collated and the list of return values is thus
collated.
Because L<run|App::Multigit::Repo/"run($command, [%data])"> completes a Future
with a hash-shaped list, the convergent Future that C<each> returns will be a
useless list of all flattened hashes. For this reason it is not actually very
much use to do this - but it is not completely useless, because all hashes are
the same size:
( run in 1.058 second using v1.01-cache-2.11-cpan-39bf76dae61 )