1 package MooseX::Runnable::Invocation;
3 use MooseX::Types -declare => ['RunnableClass'];
4 use MooseX::Types::Moose qw(Str ClassName);
8 # we can't load the class until plugins are loaded,
9 # so we have to handle this outside of coerce
11 subtype RunnableClass,
13 where { $_ =~ /^[:A-Za-z_]+$/ };
15 use namespace::clean -except => 'meta';
17 # this class is just as runnable as any other, so I guess we should tag it
18 with 'MooseX::Runnable', 'MooseX::Object::Pluggable';
20 has '+_plugin_ns' => ( default => 'MooseX::Runnable::Invocation::Plugin' );
30 isa => 'ArrayRef[Str]',
31 default => sub { [] },
38 $self->load_plugin($_) for $self->plugins;
43 my $class = $self->class;
45 Class::MOP::load_class( $class );
47 confess 'We can only work with Moose classes with "meta" methods'
48 if !$class->can('meta');
50 my $meta = $class->meta;
52 confess "The metaclass of $class is not a Moose::Meta::Class, it's $meta"
53 unless $meta->isa('Moose::Meta::Class');
55 confess 'MooseX::Runnable can only run classes tagged with '.
56 'the MooseX::Runnable role'
57 unless $meta->does_role('MooseX::Runnable');
63 my ($self, $class) = @_;
65 my @schemes = grep { defined } map {
66 $self->_convert_role_to_scheme($_)
67 } $class->calculate_all_roles;
69 foreach my $scheme (@schemes) {
70 $scheme->apply($self);
75 my ($self, $class) = @_;
77 my @bad_attributes = map { $_->name } grep {
78 $_->is_required && $_->has_default || $_->has_builder
79 } $class->compute_all_applicable_attributes;
82 'By default, MooseX::Runnable calls the constructor with no'.
83 ' args, but that will result in an error for your class. You'.
84 ' need to provide a MooseX::Runnable::Invocation::Plugin or'.
85 ' ::Scheme for this class that will satisfy the requirements.'.
87 "The class is @{[$class->name]}, and the required attributes are ".
88 join ', ', map { "'$_'" } @bad_attributes
91 return; # return value is meaningless
94 sub _convert_role_to_scheme {
95 my ($self, $role) = @_;
102 sub create_instance {
103 my ($self, $class, @args) = @_;
104 return ($class->name->new, @args);
107 sub start_application {
109 my $instance = shift;
112 return $instance->run(@args);
119 my $class = $self->load_class;
120 $self->apply_scheme($class);
121 $self->validate_class($class);
122 my ($instance, @more_args) = $self->create_instance($class, @args);
123 my $exit_code = $self->start_application($instance, @more_args);