File Coverage

blib/lib/Form/Factory/Interface/CLI.pm
Criterion Covered Total %
statement 42 43 97.6
branch 22 24 91.6
condition 1 2 50.0
subroutine 5 5 100.0
pod 2 2 100.0
total 72 76 94.7


line stmt bran cond sub pod time code
1             package Form::Factory::Interface::CLI;
2             $Form::Factory::Interface::CLI::VERSION = '0.022';
3 1     1   876 use Moose;
  1         2  
  1         7  
4              
5             with qw( Form::Factory::Interface );
6              
7 1     1   5403 use Carp ();
  1         2  
  1         908  
8              
9             # ABSTRACT: Command-line interface builder for form factory
10              
11              
12             has renderer => (
13             is => 'ro',
14             isa => 'CodeRef',
15             required => 1,
16             default => sub { sub { print @_ } },
17             );
18              
19              
20             has get_args => (
21             is => 'ro',
22             isa => 'CodeRef',
23             required => 1,
24             default => sub { sub { \@ARGV } },
25             );
26              
27              
28             has get_file => (
29             is => 'ro',
30             isa => 'CodeRef',
31             required => 1,
32             default => sub {
33             sub {
34             my ($interface, $name) = @_;
35             my $fh;
36              
37             if ($name eq '-') {
38             $fh = \*STDIN;
39             }
40             else {
41             open $fh, '<', $name or Carp::croak("cannot read $name: $!\n");
42             }
43              
44             do { local $/; <$fh> };
45             }
46             },
47             );
48              
49              
50             sub render_control {
51 8     8 1 13 my ($self, $control, %options) = @_;
52              
53 8 100       31 return if $control->does('Form::Factory::Control::Role::HiddenValue');
54              
55 7         223 my $arg;
56 7 100       12 if ($control->does('Form::Factory::Control::Role::AvailableChoices')) {
    100          
    50          
    100          
57 2         41 my @values = map { $_->value } @{ $control->available_choices };
  10         411  
  2         85  
58 2         11 $arg = '[ ' . join(' | ', @values) . ' ]';
59             }
60             elsif ($control->does('Form::Factory::Control::Role::BooleanValue')) {
61 2         78 $arg = ''
62             }
63             elsif ($control->does('Form::Factory::Control::Role::PresetValue')) {
64 0         0 $arg = '';
65             }
66             elsif ($control->does('Form::Factory::Control::Role::MultiLine')) {
67 1         82 $arg = 'FILE';
68             }
69             else {
70 2         152 $arg = 'TEXT';
71             }
72              
73 7   50     273 my $description = $control->documentation || '';
74              
75 7         217 $self->renderer->($self,
76             sprintf(" --%-20s %s\n", $control->name . ' '. $arg, $description)
77             );
78             }
79              
80              
81             sub consume_control {
82 8     8 1 17 my ($self, $control, %options) = @_;
83              
84 8         8 my @argv = @{ $self->get_args->($self) };
  8         239  
85 8         257 my ($fetch, @values);
86 8         13 for my $argv (@argv) {
87 128 100       3461 if ($fetch) {
    100          
88 7         9 push @values, $argv;
89 7         10 undef $fetch;
90             }
91              
92             elsif ($argv eq '--' . $control->name) {
93 9 100       64 if ($control->does('Form::Factory::Control::Role::BooleanValue')) {
94 2         982 push @values, $control->true_value;
95             }
96             else {
97 7         1631 $fetch++;
98             }
99             }
100             }
101              
102 8 100       42 return {} unless @values > 0;
103              
104             my $get_value = sub {
105 9     9   10 my $value = shift;
106 9 100       30 if ($control->does('Form::Factory::Control::Role::MultiLine')) {
107 1         47 return $self->get_file->($self, $value);
108             }
109             else {
110 8         185 return $value;
111             }
112 7         30 };
113              
114 7 100       16 if ($control->does('Form::Factory::Control::Role::ListValue')) {
115 1         30 my @result;
116 1         3 push @result, $get_value->($_) for @values;
117 1         5 $control->current_values(\@result);
118             }
119              
120             else {
121 6 50       168 Carp::croak(sprintf("the --%s option should be used only once\n", $control->name))
122             if @values > 1;
123            
124 6         13 $control->current_value($get_value->($values[0]));
125             }
126             }
127              
128             __PACKAGE__->meta->make_immutable;
129              
130             __END__
131              
132             =pod
133              
134             =encoding UTF-8
135              
136             =head1 NAME
137              
138             Form::Factory::Interface::CLI - Command-line interface builder for form factory
139              
140             =head1 VERSION
141              
142             version 0.022
143              
144             =head1 SYNOPSIS
145              
146             #/usr/bin/perl
147             use strict;
148             use warnings;
149              
150             use Form::Factory;
151              
152             my $cli = Form::Factory->new_interface('CLI');
153             my $action = $cli->new_action(shift @ARGV);
154            
155             $action->consume_and_clean_and_check_and_process;
156              
157             if ($action->is_valid and $action->is_success) {
158             print "done.\n";
159             }
160             else {
161             my $messages = $action->results->all_messages;
162             print $messages;
163             print "usage: $0 OPTIONS\n\n";
164             print "Options:\n";
165             $action->render;
166             }
167              
168             =head1 DESCRIPTION
169              
170             Provides a simple interface for building command-line tools that manipulate actions.
171              
172             =head1 ATTRIBUTES
173              
174             =head2 renderer
175              
176             This is a subroutine responsible for returning the usage parameters back to the user. The default prints to C<STDOUT>.
177              
178             =head2 get_args
179              
180             This is a subroutine responsible for return a list of command-line arguments. The default implementation returns a reference to C<@ARGV>.
181              
182             =head2 get_file
183              
184             This is a subroutine responsible for returning the contents of files used on the command-line. It is passed the interface object and then the name of the file to load. The default implementation slurps up the named file or, in the case of the name begin "-", returns the contents of C<STDIN>.
185              
186             =head1 METHODS
187              
188             =head2 render_control
189              
190             Prints a usage line for each control.
191              
192             =head2 consume_control
193              
194             Consumes the command-line arguments and files specified on the command-line to fill in the action.
195              
196             =head1 AUTHOR
197              
198             Andrew Sterling Hanenkamp <hanenkamp@cpan.org>
199              
200             =head1 COPYRIGHT AND LICENSE
201              
202             This software is copyright (c) 2015 by Qubling Software LLC.
203              
204             This is free software; you can redistribute it and/or modify it under
205             the same terms as the Perl 5 programming language system itself.
206              
207             =cut