App-Multigit

 view release on metacpan or  search on metacpan

lib/App/Multigit.pm  view on Meta::CPAN

    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:

    my $future = App::Multigit::each([qw/git reset --hard HEAD/]);
    my @result = $future->get;

    my $natatime = List::MoreUtils::natatime(10, @result);

    while (my %data = $natatime->()) {
        say $data{stdout};
    }

However, the C<%data> hashes do not contain repository information; just the
output. It is expected that if repository information is required, the closure
form is used.

=cut

sub each {
    my $command = shift;
    my $ia_config = shift;
    my $repos = selected_repositories;

    my $f = fmap { _run_in_repo($command, $_[0], $repos->{$_[0]}, $ia_config) }
        foreach => [ keys %$repos ],
        concurrent => $BEHAVIOUR{concurrent_processes},
    ;

    bless $f, 'App::Multigit::Future';
}

=head2 mg_each

This is the exported name of C<each>

    use App::Multigit qw/mg_each/;

=cut

*mg_each = \&each;

sub _run_in_repo {
    my ($cmd, $repo, $config, $ia_config) = @_;

    return App::Multigit::Future->done
        if $BEHAVIOUR{skip_readonly} and $config->{readonly};

    if (ref $cmd eq 'ARRAY') {
        App::Multigit::Repo->new(
            name => $repo,
            config => $config
        )->run($cmd, ia_config => $ia_config);
    }
    else {
        App::Multigit::Repo->new(
            name => $repo,
            config => $config
        )->$cmd;
    }
}

=head2 mkconfig($workdir)

Scans C<$workdir> for git directories and registers each in C<.mgconfig>. If the
config file already exists it will be appended to; existing config will be
preserved where possible.

=cut

sub mkconfig {



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