File Coverage

blib/lib/App/Cmd/Command.pm
Criterion Covered Total %
statement 73 75 97.3
branch 14 24 58.3
condition 7 8 87.5
subroutine 20 20 100.0
pod 12 12 100.0
total 126 139 90.6


line stmt bran cond sub pod time code
1 16     16   5187 use strict;
  16         30  
  16         423  
2 16     16   69 use warnings;
  16         26  
  16         567  
3              
4             package App::Cmd::Command 0.334;
5              
6 16     16   1476 use App::Cmd::ArgProcessor;
  16         29  
  16         536  
7 16     16   571 BEGIN { our @ISA = 'App::Cmd::ArgProcessor' };
8              
9             # ABSTRACT: a base class for App::Cmd commands
10              
11 16     16   87 use Carp ();
  16         24  
  16         14495  
12              
13             #pod =method prepare
14             #pod
15             #pod my ($cmd, $opt, $args) = $class->prepare($app, @args);
16             #pod
17             #pod This method is the primary way in which App::Cmd::Command objects are built.
18             #pod Given the remaining command line arguments meant for the command, it returns
19             #pod the Command object, parsed options (as a hashref), and remaining arguments (as
20             #pod an arrayref).
21             #pod
22             #pod In the usage above, C<$app> is the App::Cmd object that is invoking the
23             #pod command.
24             #pod
25             #pod =cut
26              
27             sub prepare {
28 29     29 1 78 my ($class, $app, @args) = @_;
29              
30 29         128 my ($opt, $args, %fields)
31             = $class->_process_args(\@args, $class->_option_processing_params($app));
32              
33             return (
34 28         197 $class->new({ app => $app, %fields }),
35             $opt,
36             @$args,
37             );
38             }
39              
40             sub _option_processing_params {
41 29     29   65 my ($class, @args) = @_;
42              
43             return (
44 29         144 $class->usage_desc(@args),
45             $class->opt_spec(@args),
46             );
47             }
48              
49             #pod =method new
50             #pod
51             #pod This returns a new instance of the command plugin. Probably only C
52             #pod should use this.
53             #pod
54             #pod =cut
55              
56             sub new {
57 30     30 1 82 my ($class, $arg) = @_;
58 30         189 bless $arg => $class;
59             }
60              
61             #pod =method execute
62             #pod
63             #pod $command_plugin->execute(\%opt, \@args);
64             #pod
65             #pod This method does whatever it is the command should do! It is passed a hash
66             #pod reference of the parsed command-line options and an array reference of left
67             #pod over arguments.
68             #pod
69             #pod If no C method is defined, it will try to call C -- but it will
70             #pod warn about this behavior during testing, to remind you to fix the method name!
71             #pod
72             #pod =cut
73              
74             sub execute {
75 1     1 1 3 my $class = shift;
76              
77 1 50       10 if (my $run = $class->can('run')) {
78             warn "App::Cmd::Command subclasses should implement ->execute not ->run"
79 0 0       0 if $ENV{HARNESS_ACTIVE};
80              
81 0         0 return $class->$run(@_);
82             }
83              
84 1         251 Carp::croak ref($class) . " does not implement mandatory method 'execute'\n";
85             }
86              
87             #pod =method app
88             #pod
89             #pod This method returns the App::Cmd object into which this command is plugged.
90             #pod
91             #pod =cut
92              
93 52     52 1 213 sub app { $_[0]->{app}; }
94              
95             #pod =method usage
96             #pod
97             #pod This method returns the usage object for this command. (See
98             #pod L).
99             #pod
100             #pod =cut
101              
102 10     10 1 76 sub usage { $_[0]->{usage}; }
103              
104             #pod =method command_names
105             #pod
106             #pod This method returns a list of command names handled by this plugin. The
107             #pod first item returned is the 'canonical' name of the command.
108             #pod
109             #pod If this method is not overridden by an App::Cmd::Command subclass, it will
110             #pod return the last part of the plugin's package name, converted to lowercase.
111             #pod For example, YourApp::Cmd::Command::Init will, by default, handle the command
112             #pod "init".
113             #pod
114             #pod Subclasses should generally get the superclass value of C
115             #pod and then append aliases.
116             #pod
117             #pod =cut
118              
119             sub command_names {
120             # from UNIVERSAL::moniker
121 128   66 128 1 908 (ref( $_[0] ) || $_[0]) =~ /([^:]+)$/;
122 128         461 return lc $1;
123             }
124              
125             #pod =method usage_desc
126             #pod
127             #pod This method should be overridden to provide a usage string. (This is the first
128             #pod argument passed to C from Getopt::Long::Descriptive.)
129             #pod
130             #pod If not overridden, it returns "%c COMMAND %o"; COMMAND is the first item in
131             #pod the result of the C method.
132             #pod
133             #pod =cut
134              
135             sub usage_desc {
136 22     22 1 43 my ($self) = @_;
137              
138 22         67 my ($command) = $self->command_names;
139 22         129 return "%c $command %o"
140             }
141              
142             #pod =method opt_spec
143             #pod
144             #pod This method should be overridden to provide option specifications. (This is
145             #pod list of arguments passed to C from Getopt::Long::Descriptive,
146             #pod after the first.)
147             #pod
148             #pod If not overridden, it returns an empty list.
149             #pod
150             #pod =cut
151              
152             sub opt_spec {
153 15     15 1 82 return;
154             }
155              
156             #pod =method validate_args
157             #pod
158             #pod $command_plugin->validate_args(\%opt, \@args);
159             #pod
160             #pod This method is passed a hashref of command line options (as processed by
161             #pod Getopt::Long::Descriptive) and an arrayref of leftover arguments. It may throw
162             #pod an exception (preferably by calling C, below) if they are invalid,
163             #pod or it may do nothing to allow processing to continue.
164             #pod
165             #pod =cut
166              
167       19 1   sub validate_args { }
168              
169             #pod =method usage_error
170             #pod
171             #pod $self->usage_error("This command must not be run by root!");
172             #pod
173             #pod This method should be called to die with human-friendly usage output, during
174             #pod C.
175             #pod
176             #pod =cut
177              
178             sub usage_error {
179 1     1 1 11 my ( $self, $error ) = @_;
180 1         6 die "Error: $error\nUsage: " . $self->_usage_text;
181             }
182              
183             sub _usage_text {
184 1     1   3 my ($self) = @_;
185 1         2 local $@;
186 1         2 join "\n", eval { $self->app->_usage_text }, eval { $self->usage->text };
  1         5  
  1         6  
187             }
188              
189             #pod =method abstract
190             #pod
191             #pod This method returns a short description of the command's purpose. If this
192             #pod method is not overridden, it will return the abstract from the module's Pod.
193             #pod If it can't find the abstract, it will look for a comment starting with
194             #pod "ABSTRACT:" like the ones used by L.
195             #pod
196             #pod =cut
197              
198             # stolen from ExtUtils::MakeMaker
199             sub abstract {
200 29     29 1 48 my ($class) = @_;
201 29 50       56 $class = ref $class if ref $class;
202              
203 29         39 my $result;
204             my $weaver_abstract;
205              
206             # classname to filename
207 29         136 (my $pm_file = $class) =~ s!::!/!g;
208 29         43 $pm_file .= '.pm';
209 29 50       78 $pm_file = $INC{$pm_file} or return "(unknown)";
210              
211             # if the pm file exists, open it and parse it
212 29 50       1095 open my $fh, "<", $pm_file or return "(unknown)";
213              
214 29         188 local $/ = "\n";
215 29         46 my $inpod;
216              
217 29         461 while (local $_ = <$fh>) {
218             # =cut toggles, it doesn't end :-/
219 1226 50 100     2972 $inpod = /^=cut/ ? !$inpod : $inpod || /^=(?!cut)/;
220              
221 1226 100       1923 if (/#+\s*ABSTRACT: (.*)/){
222             # takes ABSTRACT: ... if no POD defined yet
223 9         25 $weaver_abstract = $1;
224             }
225              
226 1226 100       2849 next unless $inpod;
227 99         127 chomp;
228              
229 99 100       657 next unless /^(?:$class\s-\s)(.*)/;
230              
231 21         50 $result = $1;
232 21         39 last;
233             }
234              
235 29   100     572 return $result || $weaver_abstract || "(unknown)";
236             }
237              
238             #pod =method description
239             #pod
240             #pod This method can be overridden to provide full option description. It
241             #pod is used by the built-in L command.
242             #pod
243             #pod If not overridden, it uses L to extract the description
244             #pod from the module's Pod DESCRIPTION section or the empty string.
245             #pod
246             #pod =cut
247              
248             sub description {
249 4     4 1 9 my ($class) = @_;
250 4 50       15 $class = ref $class if ref $class;
251              
252             # classname to filename
253 4         19 (my $pm_file = $class) =~ s!::!/!g;
254 4         8 $pm_file .= '.pm';
255 4 50       15 $pm_file = $INC{$pm_file} or return '';
256              
257 4 50       183 open my $input, "<", $pm_file or return '';
258              
259 4         14 my $descr = "";
260 4     2   125 open my $output, ">", \$descr;
  2         12  
  2         4  
  2         13  
261              
262 4         2464 require Pod::Usage;
263 4         86047 Pod::Usage::pod2usage( -input => $input,
264             -output => $output,
265             -exit => "NOEXIT",
266             -verbose => 99,
267             -sections => "DESCRIPTION",
268             indent => 0
269             );
270 4         26821 $descr =~ s/Description:\n//m;
271 4         11 chomp $descr;
272              
273 4         77 return $descr;
274             }
275              
276             1;
277              
278             __END__