package Sietima::CmdLine; use Moo; use Sietima::Policy; use Sietima::Types qw(SietimaObj); use Types::Standard qw(HashRef); use Sietima; use App::Spec; use Sietima::Runner; use namespace::clean; # VERSION # ABSTRACT: run Sietima as a command-line application =head1 SYNOPSIS use Sietima::CmdLine; Sietima::CmdLine->new({ traits => [qw(SubjectTag)], args => { return_path => 'list@example.net', subject_tag => 'Test', subscribers => \@addresses, })->run; =head1 DESCRIPTION This class simplifies the creation of a L<< C >> object, and uses L<< C >> to provide a command-line interface to it. =attr C Required, an instance of L<< C >>. You can either construct it yourself, or use the L. =cut has sietima => ( is => 'ro', required => 1, isa => SietimaObj, ); =attr C Optional hashref. Used inside L<< /C >>. If you're not familiar with L<< C >>, you probably don't want to touch this. =cut has extra_spec => ( is => 'ro', isa => HashRef, default => sub { +{} }, ); =method C my $cmdline = Sietima::CmdLine->new({ sietima => Sietima->with_traits(qw(SubjectTag))->new({ return_path => 'list@example.net', subject_tag => 'Test', subscribers => \@addresses, }), }); my $cmdline = Sietima::CmdLine->new({ traits => [qw(SubjectTag)], args => { return_path => 'list@example.net', subject_tag => 'Test', subscribers => \@addresses, }); The constructor. In alternative to passing a L<< C >> instance, you can pass C and C, and the instance will be built for you. The two calls above are equivalent. =for Pod::Coverage BUILDARGS =cut sub BUILDARGS($class,@args) { my $args = $class->next::method(@args); $args->{sietima} //= do { my $traits = delete $args->{traits} // []; my $constructor_args = delete $args->{args} // {}; Sietima->with_traits($traits->@*)->new($constructor_args); }; return $args; } =method C Returns an instance of L<< C >>, built from the specification returned by calling L<< C|Sietima/command_line_spec >> on the L<< /C >> object, modified by the L<< /C >>. This method, and the C attribute, are probably only interesting to people who are doing weird extensions. =cut has app_spec => ( is => 'lazy', init_arg => undef, ); sub _build_app_spec($self) { my $spec_data = $self->sietima->command_line_spec(); return App::Spec->read({ $spec_data->%*, $self->extra_spec->%*, }); } =method C Returns an instance of L<< C >>, built from the L<< /C >>. =method C Delegates to the L<< /C >>'s L<< C|App::Spec::Run/run >> method. Parser the command line arguments from C<@ARGV> and executes the appropriate action. =cut has runner => ( is => 'lazy', init_arg => undef, handles => [qw(run)], ); sub _build_runner($self) { return Sietima::Runner->new({ spec => $self->app_spec, cmd => $self->sietima, }); } 1;