App-Multigit
view release on metacpan or search on metacpan
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 run is passed the %data hash from the previous
command. %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 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 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 %data hash that is consistent to all
invocations of run. That means that when you do 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 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, finally does not have to be the final thing. Think
"finally" as in "try/catch/finally". In the following code, finally
simply returns the %data hash, because 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)
;
});
Arrayref form
In the arrayref form, the $command is passed directly to run in
App::Multigit::Repo. The Futures returned thus are collated and the
list of return values is thus collated.
Because run completes a Future with a hash-shaped list, the convergent
Future that 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:
my $future = App::Multigit::each([qw/git reset --hard HEAD/]);
( run in 1.170 second using v1.01-cache-2.11-cpan-39bf76dae61 )