exec and repl as standard actions
Matt S Trout [Fri, 11 Nov 2011 13:53:10 +0000 (13:53 +0000)]
lib/Tak/Role/ScriptActions.pm [new file with mode: 0644]

diff --git a/lib/Tak/Role/ScriptActions.pm b/lib/Tak/Role/ScriptActions.pm
new file mode 100644 (file)
index 0000000..bde1cb7
--- /dev/null
@@ -0,0 +1,65 @@
+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;