File Coverage

blib/lib/Mojo/Console.pm
Criterion Covered Total %
statement 15 69 21.7
branch 0 14 0.0
condition 0 30 0.0
subroutine 5 21 23.8
pod 11 11 100.0
total 31 145 21.3


line stmt bran cond sub pod time code
1             package Mojo::Console;
2 1     1   56658 use Mojo::Base 'Mojolicious::Command';
  1         164667  
  1         6  
3              
4 1     1   47863 use Getopt::Long;
  1         3  
  1         8  
5 1     1   115 use List::Util qw(any none);
  1         2  
  1         52  
6              
7 1     1   387 use Mojo::Console::Input;
  1         2  
  1         7  
8 1     1   378 use Mojo::Console::Output;
  1         2  
  1         7  
9              
10             our $VERSION = '0.0.8';
11              
12             has 'args' => sub {
13             my $self = shift;
14              
15             my $args = $self->defaults;
16              
17             GetOptions($args, @{ $self->options });
18              
19             return $args;
20             };
21              
22             has 'defaults' => sub { {} };
23             has 'input' => sub { Mojo::Console::Input->new };
24             has 'max_attempts' => 10;
25             has 'options' => sub { [] };
26             has 'output' => sub { Mojo::Console::Output->new };
27             has '_required' => 0;
28              
29             sub arg {
30 0     0 1   my ($self, $name) = @_;
31              
32 0           return $self->args->{ $name };
33             }
34              
35             sub ask {
36 0     0 1   my ($self, $message, $default) = @_;
37              
38 0           my $attempts = $self->max_attempts;
39 0           my $answer = '';
40              
41 0   0       while ((($self->_required || $attempts == 10) && !$answer) && $attempts--) {
      0        
      0        
42 0           $self->line($message . ' ');
43            
44 0 0         if ($default) {
45 0           $self->warn(sprintf('[default=%s] ', $default));
46             }
47              
48 0   0       $answer = $self->input->ask || (!$self->_required && $default);
49             }
50              
51 0 0         if ($attempts < 0) {
52 0           $self->error("Please answer the question.\n");
53             }
54              
55 0           $self->required(0);
56              
57 0           return $answer;
58             }
59              
60             sub confirm {
61 0     0 1   my ($self, $message, $default) = @_;
62              
63 0   0 0     my $default_yes = (any { lc($default || '') eq $_ } qw/y yes/);
  0            
64 0   0 0     my $default_no = (any { lc($default || '') eq $_ } qw/n no/);
  0            
65              
66 0           my $attempts = $self->max_attempts;
67 0           my $answer = '';
68              
69 0   0 0     while ((none { lc($answer) eq $_ } qw/y yes n no/) && $attempts--) {
  0            
70 0           $self->line($message);
71              
72 0           $self->success(' [yes/no] ');
73              
74 0 0         if ($default) {
75 0           $self->warn(sprintf('[default=%s] ', $default));
76             }
77              
78 0   0       $answer = $self->input->ask || $default;
79             }
80              
81 0 0         if ($attempts < 0) {
82 0           $self->error("Please answer with [yes/no]\n");
83             }
84              
85 0 0   0     return (any { lc($answer) eq $_ } qw/y yes/) ? 1 : 0;
  0            
86             }
87              
88             sub choice {
89 0     0 1   my ($self, $message, $choices, $default) = @_;
90              
91 0           my $attempts = $self->max_attempts;
92 0           my $answer = '';
93              
94 0   0 0     while ((none { $answer eq $_ } @$choices) && $attempts--) {
  0            
95 0           $self->line($message);
96 0           $self->success(sprintf(' [%s] ', join(', ', @$choices)));
97              
98 0 0         if ($default) {
99 0           $self->warn(sprintf('[default=%s] ', $default));
100             }
101              
102 0   0       $answer = $self->input->ask || $default;
103             }
104              
105 0 0         if ($attempts < 0) {
106 0           $self->error(sprintf("Please chose one of the following options: [%s] \n", join(', ', @$choices)));
107             }
108              
109 0           return $answer;
110             }
111              
112             sub error {
113 0     0 1   return shift->output->error(@_);
114             }
115              
116             sub info {
117 0     0 1   return shift->output->info(@_);
118             }
119              
120             sub line {
121 0     0 1   return shift->output->line(@_);
122             }
123              
124             sub newline {
125 0     0 1   return shift->output->newline(@_);
126             }
127              
128             sub required {
129 0     0 1   my $self = shift;
130              
131 0   0       $self->_required(shift // 1);
132              
133 0           return $self;
134             }
135              
136             sub success {
137 0     0 1   return shift->output->success(@_);
138             }
139              
140             sub warn {
141 0     0 1   return shift->output->warn(@_);
142             }
143              
144             1;
145              
146             =encoding utf8
147              
148             =head1 NAME
149              
150             Mojo::Console - Extend Mojolicious::Command to be able to ask for things from command line
151              
152             =head1 SYNOPSIS
153              
154             package MyApp::Command::helloworld;
155             use Mojo::Base 'Mojo::Console';
156              
157             sub run {
158             my $self = shift;
159              
160             my $name = $self->ask('What is your name?');
161             my $gender = $self->choice('Are you a male or a female?', ['male', 'female']);
162             my $bool = $self->confirm("Do you have a cat?");
163              
164             $self->line("Hi $name\n");
165             $self->line("We found out that you are a $gender ");
166              
167             if ($bool) {
168             $self->line("and you have a cat");
169             } else {
170             $self->line("and you don't have a cat");
171             }
172              
173             if ($self->confirm("Would you like an icecream?")) {
174             $self->success("Thanks");
175             } else {
176             $self->error("Oh no!");
177             }
178              
179             $self->info("You got here because you took an icecream");
180             }
181              
182             1;
183              
184             =head1 DESCRIPTION
185              
186             L is an extension of L
187              
188             =head1 ATTRIBUTES
189              
190             L inherits all attributes from Land implements the
191             following new ones.
192              
193             =head2 args
194              
195             my $args = $console->args;
196              
197             Uses Getopt::Long::GetOptions to parse passed args.
198              
199             =head2 defaults
200              
201             my $defaults = $console->defaults;
202             $console = $console->defaults({ arg1 => 'value', verbose => 1 });
203              
204             Default values for args.
205              
206             =head2 input
207              
208             my $input = $console->input;
209             $console = $console->input(Mojo::Console::Input->new);
210              
211             Input collector interface.
212              
213             =head2 max_attempts
214              
215             my $max_attempts = $console->max_attempts;
216             $console = $console->max_attempts(5);
217              
218             How many times to allow a user to enter wrong value.
219              
220             =head2 options
221              
222             my $options = $console->options;
223             $console = $console->options(['arg1=s', 'confirm']);
224              
225             Args descriptor, see L, method GetOptions.
226              
227             =head2 output
228              
229             my $output = $console->output;
230             $console = $console->output(Mojo::Console::Output->new);
231              
232             Output interface.
233              
234             =head1 METHODS
235              
236             L inherits all methods from L and implements
237             the following new ones.
238              
239             =head2 arg
240              
241             my $value = $self->arg('verbose');
242              
243             Get the value of an argument.
244              
245             =head2 ask
246              
247             my $answer = $self->ask('What is your name?');
248             my $required_answer = $self->required->ask('What is your name?'); # this will ask for an answer maximum 10 times and will exit in case the answer is empty
249              
250             Ask a question.
251              
252             =head2 confirm
253              
254             my $bool = $self->confirm("Are you sure?");
255             my $bool_with_default_answer = $self->confirm("Are you sure?", 'yes');
256              
257             Ask the user to confirm something.
258              
259             =head2 choice
260              
261             my $choice = $self->choice('Are you a male or a female?', ['male', 'female']);
262             my $choice_with_default_answer = $self->choice('Are you a male or a female?', ['male', 'female'], 'male');
263              
264             Ask the user to pick a value.
265              
266             =head2 error
267              
268             $self->error("The program will stop here");
269              
270             Write a message on the output and exit.
271              
272             =head2 info
273              
274             $self->info("This is just an info message");
275              
276             Write an info message to the output.
277              
278             =head2 line
279              
280             $self->line("This message will not have a new line at the end");
281              
282             Write a line to the output.
283              
284             =head2 newline
285              
286             $self->newline("This message will have a new line at the end");
287              
288             Write a line to the output, followed by a newline.
289              
290             =head2 required
291              
292             $self->required->ask('What is your name?');
293              
294             Mark the question as being required.
295              
296             =head2 success
297              
298             $self->success("This is just a success message");
299              
300             Write a success message to the output.
301              
302             =head2 warn
303              
304             $self->success("This is just a warning message");
305              
306             Write a warn message to the output.
307              
308             =head1 SEE ALSO
309              
310             L, L, L, L.
311              
312             =cut