Tag plugins that can take cmdline args with Role::CmdlineArgs; add test
[gitmo/MooseX-Runnable.git] / lib / MooseX / Runnable / Invocation.pm
index 16db55b..644d246 100644 (file)
@@ -14,8 +14,8 @@ subtype RunnableClass,
   where { $_ =~ /^[:A-Za-z_]+$/ };
 
 
-# this class is just as runnable as any other, so I guess we should tag it
-with 'MooseX::Runnable', 'MooseX::Object::Pluggable';
+with 'MooseX::Runnable'; # this class technically follows
+                         # MX::Runnable's protocol
 
 has 'class' => (
     is       => 'ro',
@@ -26,14 +26,43 @@ has 'class' => (
 has 'plugins' => (
     is         => 'ro',
     isa        => HashRef[ArrayRef[Str]],
-    default    => sub { [] },
+    default    => sub { +{} },
     required   => 1,
     auto_deref => 1,
 );
 
 sub BUILD {
     my $self = shift;
-    $self->load_plugin($_) for keys %{$self->plugins};
+
+    # it would be nice to use MX::Object::Pluggable, but our plugins
+    # are too configurable
+
+    my $plugin_ns = 'MooseX::Runnable::Invocation::Plugin::';
+    for my $plugin (keys %{$self->plugins}){
+        my $orig = $plugin;
+        $plugin = "$plugin_ns$plugin" unless $plugin =~ /^[+]/;
+        $plugin =~ s/^[+]//g;
+
+        Class::MOP::load_class( $plugin );
+
+        my $args;
+        if($plugin->meta->does_role('MooseX::Runnable::Invocation::Plugin::Role::CmdlineArgs')){
+            $args = eval {
+                $plugin->_build_initargs_from_cmdline(
+                    @{$self->plugins->{$orig}},
+                );
+            };
+
+            if($@) {
+                confess "Error building initargs for $plugin: $@";
+            }
+        }
+
+        $plugin->meta->apply(
+            $self,
+            defined $args ? (rebless_params => $args) : (),
+        );
+    }
 }
 
 sub load_class {
@@ -87,12 +116,11 @@ sub _convert_role_to_scheme {
     };
 }
 
-
 sub validate_class {
     my ($self, $class) = @_;
 
     my @bad_attributes = map { $_->name } grep {
-        $_->is_required && $_->has_default || $_->has_builder
+        $_->is_required && !($_->has_default || $_->has_builder)
     } $class->get_all_attributes;
 
     confess