ensure, better scripting infrastructure
Matt S Trout [Fri, 11 Nov 2011 07:02:43 +0000 (07:02 +0000)]
lib/Tak/Client/RemoteRouter.pm [new file with mode: 0644]
lib/Tak/Client/Router.pm [new file with mode: 0644]
lib/Tak/MetaService.pm
lib/Tak/MyScript.pm
lib/Tak/STDIOSetup.pm
lib/Tak/Script.pm
lib/Tak/Takfile.pm [new file with mode: 0644]

diff --git a/lib/Tak/Client/RemoteRouter.pm b/lib/Tak/Client/RemoteRouter.pm
new file mode 100644 (file)
index 0000000..c357560
--- /dev/null
@@ -0,0 +1,9 @@
+package Tak::Client::RemoteRouter;
+
+use Moo;
+
+extends 'Tak::Client::Router';
+
+has host => (is => 'ro', required => 1);
+
+1;
diff --git a/lib/Tak/Client/Router.pm b/lib/Tak/Client/Router.pm
new file mode 100644 (file)
index 0000000..3672ab6
--- /dev/null
@@ -0,0 +1,11 @@
+package Tak::Client::Router;
+
+use Moo;
+
+extends 'Tak::Client';
+
+sub ensure {
+  shift->do(meta => ensure => @_);
+}
+
+1;
index 62bafa8..9706160 100644 (file)
@@ -11,6 +11,13 @@ sub handle_pid {
   return $$;
 }
 
+sub handle_ensure {
+  my $self = shift;
+  my ($name) = @_;
+  return "Already have ${name}" if $self->router->services->{$name};
+  $self->handle_register(@_);
+}
+
 sub handle_register {
   my ($self, $name, $class, %args) = @_;
   (my $file = $class) =~ s/::/\//g;
index 149e910..46fd4bc 100644 (file)
@@ -6,6 +6,11 @@ extends 'Tak::Script';
 
 sub _my_script_package { 'Tak::MyScript' }
 
+sub BUILD {
+  my ($self) = @_;
+  $self->_load_file('Takfile') if -e 'Takfile';
+}
+
 sub _load_file_in_my_script {
   require $_[1];
 }
index dcf0dc4..53185d8 100644 (file)
@@ -1,5 +1,7 @@
 package Tak::STDIOSetup;
 
+BEGIN { require MRO::Compat; }
+
 use Tak::ConnectionService;
 use Tak::Router;
 use Tak;
index 6868fe4..52ec0f1 100644 (file)
@@ -3,6 +3,9 @@ package Tak::Script;
 use Getopt::Long qw(GetOptionsFromArray :config posix_defaults bundling);
 use Config::Settings;
 use IO::Handle;
+use Tak::Client::Router;
+use Tak::Client::RemoteRouter;
+use Tak::Router;
 use Moo;
 
 has options => (is => 'ro', required => 1);
@@ -20,9 +23,19 @@ has config => (is => 'lazy');
 
 sub _build_config {
   my ($self) = @_;
-  Config::Settings->new->parse_file(
-    $self->options->{config} || '.tak/default.conf'
-  );
+  my $file = $self->options->{config} || '.tak/default.conf';
+  if (-e $file) {
+    Config::Settings->new->parse_file($file);
+  } else {
+    {};
+  }
+}
+
+has local_client => (is => 'lazy');
+
+sub _build_local_client {
+  my ($self) = @_;
+  Tak::Client::Router->new(service => Tak::Router->new);
 }
 
 sub BUILD {
@@ -32,8 +45,12 @@ sub BUILD {
 sub setup_logger { }
 
 sub _parse_options {
-  my ($self, $string, \@argv) = @_;
+  my ($self, $string, $argv) = @_;
   my @spec = split ';', $string;
+  my %opt;
+  GetOptionsFromArray($argv, \%opt, @spec);
+  return \%opt;
+}
 
 sub run {
   my ($self) = @_;
@@ -61,16 +78,59 @@ sub local_help {
   $self->stderr->print("Help unimplemented\n");
 }
 
+sub _maybe_parse_options {
+  my ($self, $code, $argv) = @_;
+  if (my $proto = prototype($code)) {
+    $self->_parse_options($proto, $argv);
+  } else {
+    {};
+  }
+}
+
 sub _run_local {
   my ($self, $cmd, $code, @argv) = @_;
-  my $opt = do {
-    if (my $proto = prototype($code)) {
-      $self->_parse_options($proto, \@argv);
-    } else {
-      {};
-    }
-  };
+  my $opt = $self->_maybe_parse_options($code, \@argv);
   $self->$code($opt, @argv);
 }
 
+sub _run_each {
+  my ($self, $cmd, $code, @argv) = @_;
+  my @targets = $self->_host_list_for($cmd);
+  unless (@targets) {
+    $self->stderr->print("No targets for ${cmd}\n");
+    return;
+  }
+  my $opt = $self->_maybe_parse_options($code, \@argv);
+  if (my $prepare = $self->can("prepare_$cmd")) {
+    $self->$prepare($opt, @argv);
+  }
+  $self->local_client->ensure(connector => 'Tak::ConnectorService');
+  foreach my $target (@targets) {
+    my $remote = $self->_connection_to($target);
+    $self->$code($remote, $opt, @argv);
+  }
+}
+
+sub _host_list_for {
+  my ($self, $command) = @_;
+  my @host_spec = map split(' ', $_), @{$self->options->{host}};
+}
+
+sub _connection_to {
+  my ($self, $target) = @_;
+  my @path = $self->local_client->do(connector => create => $target);
+  my ($local, $remote) =
+    map $self->local_client->curry(connector => connection => @path => $_),
+      qw(local remote);
+  $local->ensure(module_sender => 'Tak::ModuleSender');
+  $remote->ensure(
+    module_loader => 'Tak::ModuleLoader',
+    expose => { module_sender => [ 'remote', 'module_sender' ] }
+  );
+  $remote->do(module_loader => 'enable');
+  Tak::Client::RemoteRouter->new(
+    %$remote, host => $target
+  );
+}
+
 1;
diff --git a/lib/Tak/Takfile.pm b/lib/Tak/Takfile.pm
new file mode 100644 (file)
index 0000000..8827ece
--- /dev/null
@@ -0,0 +1,11 @@
+package Tak::Takfile;
+
+use strictures 1;
+use warnings::illegalproto ();
+
+sub import {
+  strictures->import;
+  warnings::illegalproto->unimport;
+}
+
+1;