File Coverage

blib/lib/App/Cmd/Simple.pm
Criterion Covered Total %
statement 48 49 97.9
branch 7 10 70.0
condition 4 6 66.6
subroutine 16 17 94.1
pod 1 1 100.0
total 76 83 91.5


line stmt bran cond sub pod time code
1 4     4   8207 use strict;
  4         10  
  4         117  
2 4     4   21 use warnings;
  4         7  
  4         150  
3              
4             package App::Cmd::Simple 0.335;
5              
6 4     4   1684 use App::Cmd::Command;
  4         13  
  4         150  
7 4     4   148 BEGIN { our @ISA = 'App::Cmd::Command' }
8              
9             # ABSTRACT: a helper for building one-command App::Cmd applications
10              
11 4     4   1900 use App::Cmd;
  4         15  
  4         24  
12 4     4   880 use Sub::Install;
  4         12  
  4         32  
13              
14             #pod =head1 SYNOPSIS
15             #pod
16             #pod in F:
17             #pod
18             #pod use YourApp::Cmd;
19             #pod Your::Cmd->run;
20             #pod
21             #pod in F:
22             #pod
23             #pod package YourApp::Cmd;
24             #pod use parent qw(App::Cmd::Simple);
25             #pod
26             #pod sub opt_spec {
27             #pod return (
28             #pod [ "blortex|X", "use the blortex algorithm" ],
29             #pod [ "recheck|r", "recheck all results" ],
30             #pod );
31             #pod }
32             #pod
33             #pod sub validate_args {
34             #pod my ($self, $opt, $args) = @_;
35             #pod
36             #pod # no args allowed but options!
37             #pod $self->usage_error("No args allowed") if @$args;
38             #pod }
39             #pod
40             #pod sub execute {
41             #pod my ($self, $opt, $args) = @_;
42             #pod
43             #pod my $result = $opt->{blortex} ? blortex() : blort();
44             #pod
45             #pod recheck($result) if $opt->{recheck};
46             #pod
47             #pod print $result;
48             #pod }
49             #pod
50             #pod and, finally, at the command line:
51             #pod
52             #pod knight!rjbs$ simplecmd --recheck
53             #pod
54             #pod All blorts successful.
55             #pod
56             #pod =head1 SUBCLASSING
57             #pod
58             #pod When writing a subclass of App::Cmd:Simple, there are only a few methods that
59             #pod you might want to implement. They behave just like the same-named methods in
60             #pod App::Cmd.
61             #pod
62             #pod =head2 opt_spec
63             #pod
64             #pod This method should be overridden to provide option specifications. (This is
65             #pod list of arguments passed to C from Getopt::Long::Descriptive,
66             #pod after the first.)
67             #pod
68             #pod If not overridden, it returns an empty list.
69             #pod
70             #pod =head2 usage_desc
71             #pod
72             #pod This method should be overridden to provide the top level usage line.
73             #pod It's a one-line summary of how the command is to be invoked, and
74             #pod should be given in the format used for the C<$usage_desc> parameter to
75             #pod C in Getopt::Long::Descriptive.
76             #pod
77             #pod If not overridden, it returns something that prints out like:
78             #pod
79             #pod yourapp [-?h] [long options...]
80             #pod
81             #pod =head2 validate_args
82             #pod
83             #pod $cmd->validate_args(\%opt, \@args);
84             #pod
85             #pod This method is passed a hashref of command line options (as processed by
86             #pod Getopt::Long::Descriptive) and an arrayref of leftover arguments. It may throw
87             #pod an exception (preferably by calling C) if they are invalid, or it
88             #pod may do nothing to allow processing to continue.
89             #pod
90             #pod =head2 execute
91             #pod
92             #pod Your::App::Cmd::Simple->execute(\%opt, \@args);
93             #pod
94             #pod This method does whatever it is the command should do! It is passed a hash
95             #pod reference of the parsed command-line options and an array reference of left
96             #pod over arguments.
97             #pod
98             #pod =cut
99              
100             # The idea here is that the user will someday replace "Simple" in his ISA with
101             # "Command" and then write a standard App::Cmd package. To make that possible,
102             # we produce a behind-the-scenes App::Cmd object when the user says 'use
103             # MyApp::Simple' and redirect MyApp::Simple->run to that.
104             my $i;
105 4     4   577 BEGIN { $i = 0 }
106              
107             sub import {
108 4     4   30255 my ($class) = @_;
109 4 50       20 return if $class eq __PACKAGE__;
110              
111             # This signals that something has already set the target up.
112 4 50       28 return $class if $class->_cmd_pkg;
113              
114 4         44 my $core_execute = App::Cmd::Command->can('execute');
115 4         25 my $our_execute = $class->can('execute');
116 4 50 33     61 Carp::confess(
117             "App::Cmd::Simple subclasses must implement ->execute, not ->run"
118             ) unless $our_execute and $our_execute != $core_execute;
119              
120             # I doubt the $i will ever be needed, but let's start paranoid.
121 4         20 my $generated_name = join('::', $class, '_App_Cmd', $i++);
122              
123             {
124 4     4   27 no strict 'refs';
  4         10  
  4         1321  
  4         9  
125 4         11 *{$generated_name . '::ISA'} = [ 'App::Cmd' ];
  4         64  
126             }
127              
128             Sub::Install::install_sub({
129             into => $class,
130             as => '_cmd_pkg',
131 0     0   0 code => sub { $generated_name },
132 4         38 });
133              
134             Sub::Install::install_sub({
135             into => $class,
136             as => 'command_names',
137 4     4   12 code => sub { 'only' },
138 4         259 });
139              
140             Sub::Install::install_sub({
141             into => $generated_name,
142             as => '_plugins',
143 4     4   15 code => sub { $class },
144 4         189 });
145              
146             Sub::Install::install_sub({
147             into => $generated_name,
148             as => 'default_command',
149 5     5   22 code => sub { 'only' },
150 4         181 });
151              
152             Sub::Install::install_sub({
153             into => $generated_name,
154             as => '_cmd_from_args',
155             code => sub {
156 5     5   19 my ($self, $args) = @_;
157 5 100       23 if (defined(my $command = $args->[0])) {
158 4         32 my $plugin = $self->plugin_for($command);
159             # If help was requested, show the help for the command, not the
160             # main help. Because the main help would talk about subcommands,
161             # and a "Simple" app has no subcommands.
162 4 100 100     30 if ($plugin and $plugin eq $self->plugin_for("help")) {
163 1         6 return ($command, [ $self->default_command ]);
164             }
165             # Any other value for "command" isn't really a command at all --
166             # it's the first argument. So call the default command instead.
167             }
168 4         17 return ($self->default_command, $args);
169             },
170 4         179 });
171              
172             Sub::Install::install_sub({
173             into => $class,
174             as => 'run',
175             code => sub {
176 4     4   56 $generated_name->new({
177             no_help_plugin => 0,
178             no_commands_plugin => 1,
179             })->run(@_);
180             }
181 4         182 });
182              
183 4         4890 return $class;
184             }
185              
186             sub usage_desc {
187 4     4 1 29 return "%c %o"
188             }
189              
190       4     sub _cmd_pkg { }
191              
192             #pod =head1 WARNINGS
193             #pod
194             #pod B Although it is probably not going
195             #pod to change much, don't build your business model around it yet, okay?
196             #pod
197             #pod App::Cmd::Simple is not rich in black magic, but it does do some somewhat
198             #pod gnarly things to make an App::Cmd::Simple look as much like an
199             #pod App::Cmd::Command as possible. This means that you can't deviate too much from
200             #pod the sort of thing shown in the synopsis as you might like. If you're doing
201             #pod something other than writing a fairly simple command, and you want to screw
202             #pod around with the App::Cmd-iness of your program, Simple might not be the best
203             #pod choice.
204             #pod
205             #pod B if you are writing a program with the
206             #pod App::Cmd::Simple class embedded in it, you B call import on the class.
207             #pod That's how things work. You can just do this:
208             #pod
209             #pod YourApp::Cmd->import->run;
210             #pod
211             #pod =cut
212              
213             1;
214              
215             __END__