--- /dev/null
+package Tak::Role::ScriptActions;
+
+use Moo::Role;
+no warnings::illegalproto;
+
+sub every_exec (stream|s) {
+ my ($self, $remotes, $options, @command) = @_;
+
+ my @requests;
+
+ $_->ensure(command_service => 'Tak::CommandService') for @$remotes;
+
+ foreach my $remote (@$remotes) {
+ if ($options->{stream}) {
+ my $stdout = $self->stdout;
+ my $host = $remote->host;
+ push @requests, $remote->start(
+ {
+ on_result => sub { $self->print_exec_result($remote, @_) },
+ on_progress => sub {
+ $stdout->print($host.' '.$_[0].': '.$_[1]);
+ $stdout->print("\n") unless $_[1] =~ /\n\Z/;
+ }
+ },
+ command_service => stream_exec => \@command
+ );
+ } else {
+ push @requests, $remote->start(
+ { on_result => sub { $self->print_exec_result($remote, @_) } },
+ command_service => exec => \@command
+ );
+ }
+ }
+ Tak->await_all(@requests);
+}
+
+sub print_exec_result {
+ my ($self, $remote, $result) = @_;
+
+ my $res = eval { $result->get }
+ or do {
+ $self->stderr->print("Host ${\$remote->host}: Error: $@\n");
+ return;
+ };
+
+ my $code = $res->{exit_code};
+ $self->stdout->print(
+ "Host ${\$remote->host}: ".($code ? "NOT OK ${code}" : "OK")."\n"
+ );
+ if ($res->{stderr}) {
+ $self->stdout->print("Stderr:\n${\$res->{stderr}}\n");
+ }
+ if ($res->{stdout}) {
+ $self->stdout->print("Stdout:\n${\$res->{stdout}}\n");
+ }
+}
+
+sub each_repl {
+ my ($self, $remote) = @_;
+ require Tak::REPL;
+ $remote->ensure(eval_service => 'Tak::EvalService');
+ Tak::REPL->new(client => $remote->curry('eval_service'))->run;
+}
+
+1;