use File::Spec::Functions qw/catfile path/;
use List::Util qw/first/;
+use App::Rgit::Utils qw/:codes/;
use App::Rgit;
our $VERSION = '0.03';
+BEGIN {
+ if (-t && eval { use Term::ReadKey; 1 }) {
+ *policy = sub {
+ my ($cmd, $conf, $repo, $status) = @_;
+ return NEXT unless $status;
+ print STDERR "git returned $status\n";
+ print STDERR "[a]bort, [i]gnore, [I]gnore all, [r]etry, open [s]hell ?";
+ ReadMode 4;
+ my $key = ReadKey 0;
+ ReadMode 1;
+ print STDERR "\n";
+ my %codes = (
+ 'a' => LAST,
+ 'i' => NEXT,
+ 'I' => NEXT | SAVE,
+ 'r' => REDO,
+ 's' => LAST,
+ );
+ $key = 'a' unless defined $key;
+ my $code = $codes{$key};
+ $code = $codes{a} unless defined $code;
+ return $code;
+ };
+ } else {
+ *policy = sub {
+ my ($cmd, $conf, $repo, $status) = @_;
+ return NEXT unless $status;
+ print STDERR "git returned $status, aborting\n";
+ return LAST;
+ };
+ }
+}
+
my $cmd = first { !/^-/ } @ARGV;
$cmd = ' ' unless defined $cmd;
$root = cwd unless defined $root;
exit App::Rgit->new(
- git => $git,
- root => $root,
- cmd => $cmd,
- args => \@ARGV
+ git => $git,
+ root => $root,
+ cmd => $cmd,
+ args => \@ARGV,
+ policy => \&policy,
)->run;
__END__
);
return unless defined $config;
my $command = App::Rgit::Command->new(
- cmd => $args{cmd},
- args => $args{args},
+ cmd => $args{cmd},
+ args => $args{args},
+ policy => $args{policy},
);
return unless defined $command;
$class->SUPER::new(
use Carp qw/croak/;
-use Object::Tiny qw/cmd args/;
+use Object::Tiny qw/cmd args policy/;
-use App::Rgit::Utils qw/validate/;
+use App::Rgit::Utils qw/validate :codes/;
=head1 NAME
}
eval "require $action; 1" or croak "Couldn't load $action: $@";
$class->SUPER::new(
- cmd => $cmd,
- args => $args{args} || [ ],
+ cmd => $cmd,
+ args => $args{args} || [ ],
+ policy => $args{policy},
);
}
$commands{$cmd} = $pkg;
}
+=head2 C<report $conf, $repo, $status>
+
+=cut
+
+sub report {
+ my ($self) = @_;
+ my $cb = $self->policy;
+ return NEXT | SAVE unless $cb;
+ my $code = $cb->(@_);
+ return defined $code ? $code : NEXT;
+}
+
=head2 C<cmd>
=head2 C<args>
+=head2 C<policy>
+
Accessors.
=head2 C<run $conf>
use base qw/App::Rgit::Command/;
+use App::Rgit::Utils qw/:codes/;
+
=head1 NAME
App::Rgit::Command::Each - Class for commands to execute for each repository.
my $self = shift;
my $conf = shift;
my $status = 0;
+ my $code;
for (@{$conf->repos}) {
$_->chdir or next;
$status = $_->run($conf, @{$self->args});
- last if $status;
+ $code = $self->report($conf, $_, $status) unless defined $code;
+ if ($code & REDO) {
+ undef $code; # Don't save it, that would be very dumb
+ redo;
+ }
+ last if $code & LAST;
+ undef $code unless $code & SAVE;
}
$conf->cwd_repo->chdir;
- return $status;
+ return wantarray ? ($status, $code) : $status;
}
=head1 SEE ALSO
This is an internal module to L<rgit>.
+=head1 CONSTANTS
+
+=head2 C<NEXT>, C<REDO>, C<LAST>, C<SAVE>
+
+Codes to return from the C<report> callback to respectively proceed to the next repository, retry the current one, end it all, and save the return code.
+
+=cut
+
+use constant {
+ SAVE => 0x1,
+ NEXT => 0x2,
+ REDO => 0x4,
+ LAST => 0x8,
+};
+
=head1 FUNCTIONS
=head2 C<validate @method_args>
=head1 EXPORT
-C<validate> is only exported on request.
+C<validate> is only exported on request, either by its name or by the C<'funcs'> tag.
+
+C<NEXT> C<REDO>, C<LAST> and C<SAVE> are only exported on request, either by their name or by the C<'codes'> tags.
=cut
our @EXPORT = ();
our %EXPORT_TAGS = (
- funcs => [ qw/validate/ ]
+ funcs => [ qw/validate/ ],
+ codes => [ qw/SAVE NEXT REDO LAST/ ],
);
our @EXPORT_OK = map { @$_ } values %EXPORT_TAGS;
$EXPORT_TAGS{'all'} = [ @EXPORT_OK ];