| line | stmt | bran | cond | sub | pod | time | code | 
| 1 |  |  |  |  |  |  | # The "experimental" below is not actually scary.  The feature went on to be | 
| 2 |  |  |  |  |  |  | # de-experimental-ized with no changes and is now on by default in perl v5.24 | 
| 3 |  |  |  |  |  |  | # and later. -- rjbs, 2021-03-14 | 
| 4 | 16 |  |  | 16 |  | 132591 | use 5.020; | 
|  | 16 |  |  |  |  | 78 |  | 
| 5 | 16 |  |  | 16 |  | 71 | use warnings; | 
|  | 16 |  |  |  |  | 25 |  | 
|  | 16 |  |  |  |  | 447 |  | 
| 6 | 16 |  |  | 16 |  | 4349 | use experimental qw(postderef postderef_qq); | 
|  | 16 |  |  |  |  | 31220 |  | 
|  | 16 |  |  |  |  | 88 |  | 
| 7 |  |  |  |  |  |  |  | 
| 8 |  |  |  |  |  |  | package App::Cmd 0.334; | 
| 9 |  |  |  |  |  |  |  | 
| 10 | 16 |  |  | 16 |  | 5264 | use parent 'App::Cmd::ArgProcessor'; | 
|  | 16 |  |  |  |  | 1661 |  | 
|  | 16 |  |  |  |  | 92 |  | 
| 11 |  |  |  |  |  |  | # ABSTRACT: write command line apps with less suffering | 
| 12 |  |  |  |  |  |  |  | 
| 13 | 16 |  |  | 16 |  | 714 | use File::Basename (); | 
|  | 16 |  |  |  |  | 28 |  | 
|  | 16 |  |  |  |  | 233 |  | 
| 14 | 16 |  |  | 16 |  | 7487 | use Module::Pluggable::Object (); | 
|  | 16 |  |  |  |  | 134210 |  | 
|  | 16 |  |  |  |  | 346 |  | 
| 15 | 16 |  |  | 16 |  | 7331 | use Class::Load (); | 
|  | 16 |  |  |  |  | 174376 |  | 
|  | 16 |  |  |  |  | 1589 |  | 
| 16 |  |  |  |  |  |  |  | 
| 17 |  |  |  |  |  |  | use Sub::Exporter -setup => { | 
| 18 |  |  |  |  |  |  | collectors => { | 
| 19 |  |  |  |  |  |  | -ignore  => \'_setup_ignore', | 
| 20 |  |  |  |  |  |  | -command => \'_setup_command', | 
| 21 |  |  |  |  |  |  | -run     => sub { | 
| 22 | 0 |  |  |  |  | 0 | warn "using -run to run your command is deprecated\n"; | 
| 23 | 0 |  |  |  |  | 0 | $_[1]->{class}->run; 1 | 
|  | 0 |  |  |  |  | 0 |  | 
| 24 |  |  |  |  |  |  | }, | 
| 25 |  |  |  |  |  |  | }, | 
| 26 | 16 |  |  | 16 |  | 3449 | }; | 
|  | 16 |  |  |  |  | 21553 |  | 
|  | 16 |  |  |  |  | 191 |  | 
| 27 |  |  |  |  |  |  |  | 
| 28 |  |  |  |  |  |  | sub _setup_command { | 
| 29 | 5 |  |  | 5 |  | 2599 | my ($self, $val, $data) = @_; | 
| 30 | 5 |  |  |  |  | 12 | my $into = $data->{into}; | 
| 31 |  |  |  |  |  |  |  | 
| 32 | 5 | 50 |  |  |  | 48 | Carp::confess "App::Cmd -command setup requested for already-setup class" | 
| 33 |  |  |  |  |  |  | if $into->isa('App::Cmd::Command'); | 
| 34 |  |  |  |  |  |  |  | 
| 35 |  |  |  |  |  |  | { | 
| 36 | 5 |  |  |  |  | 7 | my $base = $self->_default_command_base; | 
|  | 5 |  |  |  |  | 15 |  | 
| 37 | 5 |  |  |  |  | 19 | Class::Load::load_class($base); | 
| 38 | 16 |  |  | 16 |  | 8464 | no strict 'refs'; | 
|  | 16 |  |  |  |  | 28 |  | 
|  | 16 |  |  |  |  | 19633 |  | 
| 39 | 5 |  |  |  |  | 342 | push @{"$into\::ISA"}, $base; | 
|  | 5 |  |  |  |  | 59 |  | 
| 40 |  |  |  |  |  |  | } | 
| 41 |  |  |  |  |  |  |  | 
| 42 | 5 |  |  |  |  | 32 | $self->_register_command($into); | 
| 43 |  |  |  |  |  |  |  | 
| 44 | 5 |  |  |  |  | 17 | for my $plugin ($self->_plugin_plugins) { | 
| 45 | 4 |  |  |  |  | 26 | $plugin->import_from_plugin({ into => $into }); | 
| 46 |  |  |  |  |  |  | } | 
| 47 |  |  |  |  |  |  |  | 
| 48 | 5 |  |  |  |  | 294 | 1; | 
| 49 |  |  |  |  |  |  | } | 
| 50 |  |  |  |  |  |  |  | 
| 51 |  |  |  |  |  |  | sub _setup_ignore { | 
| 52 | 1 |  |  | 1 |  | 623 | my ($self, $val, $data) = @_; | 
| 53 | 1 |  |  |  |  | 2 | my $into = $data->{into}; | 
| 54 |  |  |  |  |  |  |  | 
| 55 | 1 | 50 |  |  |  | 20 | Carp::confess "App::Cmd -ignore setup requested for already-setup class" | 
| 56 |  |  |  |  |  |  | if $into->isa('App::Cmd::Command'); | 
| 57 |  |  |  |  |  |  |  | 
| 58 | 1 |  |  |  |  | 6 | $self->_register_ignore($into); | 
| 59 |  |  |  |  |  |  |  | 
| 60 | 1 |  |  |  |  | 3 | 1; | 
| 61 |  |  |  |  |  |  | } | 
| 62 |  |  |  |  |  |  |  | 
| 63 | 0 |  |  | 0 |  | 0 | sub _plugin_plugins { return } | 
| 64 |  |  |  |  |  |  |  | 
| 65 |  |  |  |  |  |  | #pod =head1 SYNOPSIS | 
| 66 |  |  |  |  |  |  | #pod | 
| 67 |  |  |  |  |  |  | #pod in F: | 
| 68 |  |  |  |  |  |  | #pod | 
| 69 |  |  |  |  |  |  | #pod   use YourApp; | 
| 70 |  |  |  |  |  |  | #pod   YourApp->run; | 
| 71 |  |  |  |  |  |  | #pod | 
| 72 |  |  |  |  |  |  | #pod in F: | 
| 73 |  |  |  |  |  |  | #pod | 
| 74 |  |  |  |  |  |  | #pod   package YourApp; | 
| 75 |  |  |  |  |  |  | #pod   use App::Cmd::Setup -app; | 
| 76 |  |  |  |  |  |  | #pod   1; | 
| 77 |  |  |  |  |  |  | #pod | 
| 78 |  |  |  |  |  |  | #pod in F: | 
| 79 |  |  |  |  |  |  | #pod | 
| 80 |  |  |  |  |  |  | #pod   package YourApp::Command::blort; | 
| 81 |  |  |  |  |  |  | #pod   use YourApp -command; | 
| 82 |  |  |  |  |  |  | #pod   use strict; use warnings; | 
| 83 |  |  |  |  |  |  | #pod | 
| 84 |  |  |  |  |  |  | #pod   sub abstract { "blortex algorithm" } | 
| 85 |  |  |  |  |  |  | #pod | 
| 86 |  |  |  |  |  |  | #pod   sub description { "Long description on blortex algorithm" } | 
| 87 |  |  |  |  |  |  | #pod | 
| 88 |  |  |  |  |  |  | #pod   sub opt_spec { | 
| 89 |  |  |  |  |  |  | #pod     return ( | 
| 90 |  |  |  |  |  |  | #pod       [ "blortex|X",  "use the blortex algorithm" ], | 
| 91 |  |  |  |  |  |  | #pod       [ "recheck|r",  "recheck all results"       ], | 
| 92 |  |  |  |  |  |  | #pod     ); | 
| 93 |  |  |  |  |  |  | #pod   } | 
| 94 |  |  |  |  |  |  | #pod | 
| 95 |  |  |  |  |  |  | #pod   sub validate_args { | 
| 96 |  |  |  |  |  |  | #pod     my ($self, $opt, $args) = @_; | 
| 97 |  |  |  |  |  |  | #pod | 
| 98 |  |  |  |  |  |  | #pod     # no args allowed but options! | 
| 99 |  |  |  |  |  |  | #pod     $self->usage_error("No args allowed") if @$args; | 
| 100 |  |  |  |  |  |  | #pod   } | 
| 101 |  |  |  |  |  |  | #pod | 
| 102 |  |  |  |  |  |  | #pod   sub execute { | 
| 103 |  |  |  |  |  |  | #pod     my ($self, $opt, $args) = @_; | 
| 104 |  |  |  |  |  |  | #pod | 
| 105 |  |  |  |  |  |  | #pod     my $result = $opt->{blortex} ? blortex() : blort(); | 
| 106 |  |  |  |  |  |  | #pod | 
| 107 |  |  |  |  |  |  | #pod     recheck($result) if $opt->{recheck}; | 
| 108 |  |  |  |  |  |  | #pod | 
| 109 |  |  |  |  |  |  | #pod     print $result; | 
| 110 |  |  |  |  |  |  | #pod   } | 
| 111 |  |  |  |  |  |  | #pod | 
| 112 |  |  |  |  |  |  | #pod and, finally, at the command line: | 
| 113 |  |  |  |  |  |  | #pod | 
| 114 |  |  |  |  |  |  | #pod   knight!rjbs$ yourcmd blort --recheck | 
| 115 |  |  |  |  |  |  | #pod | 
| 116 |  |  |  |  |  |  | #pod   All blorts successful. | 
| 117 |  |  |  |  |  |  | #pod | 
| 118 |  |  |  |  |  |  | #pod =head1 DESCRIPTION | 
| 119 |  |  |  |  |  |  | #pod | 
| 120 |  |  |  |  |  |  | #pod App::Cmd is intended to make it easy to write complex command-line applications | 
| 121 |  |  |  |  |  |  | #pod without having to think about most of the annoying things usually involved. | 
| 122 |  |  |  |  |  |  | #pod | 
| 123 |  |  |  |  |  |  | #pod For information on how to start using App::Cmd, see L. | 
| 124 |  |  |  |  |  |  | #pod | 
| 125 |  |  |  |  |  |  | #pod =method new | 
| 126 |  |  |  |  |  |  | #pod | 
| 127 |  |  |  |  |  |  | #pod   my $cmd = App::Cmd->new(\%arg); | 
| 128 |  |  |  |  |  |  | #pod | 
| 129 |  |  |  |  |  |  | #pod This method returns a new App::Cmd object.  During initialization, command | 
| 130 |  |  |  |  |  |  | #pod plugins will be loaded. | 
| 131 |  |  |  |  |  |  | #pod | 
| 132 |  |  |  |  |  |  | #pod Valid arguments are: | 
| 133 |  |  |  |  |  |  | #pod | 
| 134 |  |  |  |  |  |  | #pod   no_commands_plugin - if true, the command list plugin is not added | 
| 135 |  |  |  |  |  |  | #pod | 
| 136 |  |  |  |  |  |  | #pod   no_help_plugin     - if true, the help plugin is not added | 
| 137 |  |  |  |  |  |  | #pod | 
| 138 |  |  |  |  |  |  | #pod   no_version_plugin  - if true, the version plugin is not added | 
| 139 |  |  |  |  |  |  | #pod | 
| 140 |  |  |  |  |  |  | #pod   show_version_cmd -   if true, the version command will be shown in the | 
| 141 |  |  |  |  |  |  | #pod                        command list | 
| 142 |  |  |  |  |  |  | #pod | 
| 143 |  |  |  |  |  |  | #pod   plugin_search_path - The path to search for commands in. Defaults to | 
| 144 |  |  |  |  |  |  | #pod                        results of plugin_search_path method | 
| 145 |  |  |  |  |  |  | #pod | 
| 146 |  |  |  |  |  |  | #pod If C is not given, L will be | 
| 147 |  |  |  |  |  |  | #pod required, and it will be registered to handle all of its command names not | 
| 148 |  |  |  |  |  |  | #pod handled by other plugins. | 
| 149 |  |  |  |  |  |  | #pod | 
| 150 |  |  |  |  |  |  | #pod If C is not given, L will be required, | 
| 151 |  |  |  |  |  |  | #pod and it will be registered to handle all of its command names not handled by | 
| 152 |  |  |  |  |  |  | #pod other plugins. B "help" is the default command, so if you do not load | 
| 153 |  |  |  |  |  |  | #pod the default help plugin, you should provide your own or override the | 
| 154 |  |  |  |  |  |  | #pod C method. | 
| 155 |  |  |  |  |  |  | #pod | 
| 156 |  |  |  |  |  |  | #pod If C is not given, L will be | 
| 157 |  |  |  |  |  |  | #pod required to show the application's version with command C<--version>. By | 
| 158 |  |  |  |  |  |  | #pod default, the version command is not included in the command list. Pass | 
| 159 |  |  |  |  |  |  | #pod C to include the version command in the list. | 
| 160 |  |  |  |  |  |  | #pod | 
| 161 |  |  |  |  |  |  | #pod =cut | 
| 162 |  |  |  |  |  |  |  | 
| 163 |  |  |  |  |  |  | sub new { | 
| 164 | 24 |  |  | 24 | 1 | 5860 | my ($class, $arg) = @_; | 
| 165 |  |  |  |  |  |  |  | 
| 166 | 24 |  |  |  |  | 68 | my $arg0 = $0; | 
| 167 | 24 |  |  |  |  | 1164 | my $base = File::Basename::basename $arg0; | 
| 168 |  |  |  |  |  |  |  | 
| 169 |  |  |  |  |  |  | my $self = { | 
| 170 |  |  |  |  |  |  | arg0         => $base, | 
| 171 |  |  |  |  |  |  | full_arg0    => $arg0, | 
| 172 | 24 |  | 100 |  |  | 234 | show_version => $arg->{show_version_cmd} // 0, | 
| 173 |  |  |  |  |  |  | }; | 
| 174 |  |  |  |  |  |  |  | 
| 175 | 24 |  |  |  |  | 50 | bless $self, $class; | 
| 176 |  |  |  |  |  |  |  | 
| 177 | 24 |  |  |  |  | 133 | $self->{command} = $self->_command($arg); | 
| 178 |  |  |  |  |  |  |  | 
| 179 | 24 |  |  |  |  | 101 | return $self; | 
| 180 |  |  |  |  |  |  | } | 
| 181 |  |  |  |  |  |  |  | 
| 182 |  |  |  |  |  |  | # effectively, returns the command-to-plugin mapping guts of a Cmd | 
| 183 |  |  |  |  |  |  | # if called on a class or on a Cmd with no mapping, construct a new hashref | 
| 184 |  |  |  |  |  |  | # suitable for use as the object's mapping | 
| 185 |  |  |  |  |  |  | sub _command { | 
| 186 | 169 |  |  | 169 |  | 264 | my ($self, $arg) = @_; | 
| 187 | 169 | 100 | 66 |  |  | 1143 | return $self->{command} if ref $self and $self->{command}; | 
| 188 |  |  |  |  |  |  |  | 
| 189 |  |  |  |  |  |  | # TODO _default_command_base can be wrong if people are not using | 
| 190 |  |  |  |  |  |  | # ::Setup and have no ::Command :( | 
| 191 |  |  |  |  |  |  | # | 
| 192 |  |  |  |  |  |  | #  my $want_isa = $self->_default_command_base; | 
| 193 |  |  |  |  |  |  | # -- kentnl, 2010-12 | 
| 194 | 28 |  |  |  |  | 54 | my $want_isa = 'App::Cmd::Command'; | 
| 195 |  |  |  |  |  |  |  | 
| 196 | 28 |  |  |  |  | 44 | my %plugin; | 
| 197 | 28 |  |  |  |  | 109 | for my $plugin ($self->_plugins) { | 
| 198 |  |  |  |  |  |  |  | 
| 199 | 80 |  |  |  |  | 247 | Class::Load::load_class($plugin); | 
| 200 |  |  |  |  |  |  |  | 
| 201 |  |  |  |  |  |  | # relies on either the plugin itself registering as ignored | 
| 202 |  |  |  |  |  |  | # during compile ( use MyApp::Cmd -ignore ) | 
| 203 |  |  |  |  |  |  | # or being explicitly registered elsewhere ( blacklisted ) | 
| 204 |  |  |  |  |  |  | # via $app_cmd->_register_ignore( $class ) | 
| 205 |  |  |  |  |  |  | #  -- kentnl, 2011-09 | 
| 206 | 80 | 50 |  |  |  | 169825 | next if $self->should_ignore( $plugin ); | 
| 207 |  |  |  |  |  |  |  | 
| 208 | 80 | 50 |  |  |  | 423 | die "$plugin is not a " . $want_isa | 
| 209 |  |  |  |  |  |  | unless $plugin->isa($want_isa); | 
| 210 |  |  |  |  |  |  |  | 
| 211 | 80 | 50 |  |  |  | 393 | next unless $plugin->can("command_names"); | 
| 212 |  |  |  |  |  |  |  | 
| 213 | 80 |  |  |  |  | 211 | foreach my $command (map { lc } $plugin->command_names) { | 
|  | 92 |  |  |  |  | 262 |  | 
| 214 |  |  |  |  |  |  | die "two plugins for command $command: $plugin and $plugin{$command}\n" | 
| 215 | 92 | 50 |  |  |  | 234 | if exists $plugin{$command}; | 
| 216 |  |  |  |  |  |  |  | 
| 217 | 92 |  |  |  |  | 233 | $plugin{$command} = $plugin; | 
| 218 |  |  |  |  |  |  | } | 
| 219 |  |  |  |  |  |  | } | 
| 220 |  |  |  |  |  |  |  | 
| 221 | 28 |  |  |  |  | 163 | $self->_load_default_plugin($_, $arg, \%plugin) for qw(commands help version); | 
| 222 |  |  |  |  |  |  |  | 
| 223 | 28 | 100 |  |  |  | 185 | if ($self->allow_any_unambiguous_abbrev) { | 
| 224 |  |  |  |  |  |  | # add abbreviations to list of authorized commands | 
| 225 | 1 |  |  |  |  | 587 | require Text::Abbrev; | 
| 226 | 1 |  |  |  |  | 40 | my %abbrev = Text::Abbrev::abbrev( keys %plugin ); | 
| 227 | 1 |  |  |  |  | 67 | @plugin{ keys %abbrev } = @plugin{ values %abbrev }; | 
| 228 |  |  |  |  |  |  | } | 
| 229 |  |  |  |  |  |  |  | 
| 230 | 28 |  |  |  |  | 90 | return \%plugin; | 
| 231 |  |  |  |  |  |  | } | 
| 232 |  |  |  |  |  |  |  | 
| 233 |  |  |  |  |  |  | # ->_plugins won't be called more than once on any given App::Cmd, but since | 
| 234 |  |  |  |  |  |  | # finding plugins can be a bit expensive, we'll do a lousy cache here. | 
| 235 |  |  |  |  |  |  | # -- rjbs, 2007-10-09 | 
| 236 |  |  |  |  |  |  | my %plugins_for; | 
| 237 |  |  |  |  |  |  | sub _plugins { | 
| 238 | 30 |  |  | 30 |  | 753 | my ($self) = @_; | 
| 239 | 30 |  | 66 |  |  | 92 | my $class = ref $self || $self; | 
| 240 |  |  |  |  |  |  |  | 
| 241 | 30 | 100 |  |  |  | 110 | return $plugins_for{$class}->@* if $plugins_for{$class}; | 
| 242 |  |  |  |  |  |  |  | 
| 243 | 11 |  |  |  |  | 79 | my $finder = Module::Pluggable::Object->new( | 
| 244 |  |  |  |  |  |  | search_path => $self->plugin_search_path, | 
| 245 |  |  |  |  |  |  | $self->_module_pluggable_options, | 
| 246 |  |  |  |  |  |  | ); | 
| 247 |  |  |  |  |  |  |  | 
| 248 | 11 |  |  |  |  | 153 | my @plugins = $finder->plugins; | 
| 249 | 11 |  |  |  |  | 18236 | $plugins_for{$class} = \@plugins; | 
| 250 |  |  |  |  |  |  |  | 
| 251 | 11 |  |  |  |  | 152 | return @plugins; | 
| 252 |  |  |  |  |  |  | } | 
| 253 |  |  |  |  |  |  |  | 
| 254 |  |  |  |  |  |  | sub _register_command { | 
| 255 | 5 |  |  | 5 |  | 11 | my ($self, $cmd_class) = @_; | 
| 256 | 5 |  |  |  |  | 18 | $self->_plugins; | 
| 257 |  |  |  |  |  |  |  | 
| 258 | 5 |  | 33 |  |  | 20 | my $class = ref $self || $self; | 
| 259 |  |  |  |  |  |  | push $plugins_for{ $class }->@*, $cmd_class | 
| 260 | 5 | 50 |  |  |  | 10 | unless grep { $_ eq $cmd_class } $plugins_for{ $class }->@*; | 
|  | 7 |  |  |  |  | 23 |  | 
| 261 |  |  |  |  |  |  | } | 
| 262 |  |  |  |  |  |  |  | 
| 263 |  |  |  |  |  |  | my %ignored_for; | 
| 264 |  |  |  |  |  |  |  | 
| 265 |  |  |  |  |  |  | sub should_ignore { | 
| 266 | 80 |  |  | 80 | 0 | 164 | my ($self, $cmd_class) = @_; | 
| 267 | 80 |  | 33 |  |  | 206 | my $class = ref $self || $self; | 
| 268 | 80 |  |  |  |  | 194 | for ($ignored_for{ $class }->@*) { | 
| 269 | 0 | 0 |  |  |  | 0 | return 1 if $_ eq $cmd_class; | 
| 270 |  |  |  |  |  |  | } | 
| 271 | 80 |  |  |  |  | 213 | return; | 
| 272 |  |  |  |  |  |  | } | 
| 273 |  |  |  |  |  |  |  | 
| 274 |  |  |  |  |  |  | sub _register_ignore { | 
| 275 | 1 |  |  | 1 |  | 3 | my ($self, $cmd_class) = @_; | 
| 276 | 1 |  | 33 |  |  | 4 | my $class = ref $self || $self; | 
| 277 |  |  |  |  |  |  | push $ignored_for{ $class }->@*, $cmd_class | 
| 278 | 1 | 50 |  |  |  | 6 | unless grep { $_ eq $cmd_class } $ignored_for{ $class }->@*; | 
|  | 0 |  |  |  |  | 0 |  | 
| 279 |  |  |  |  |  |  | } | 
| 280 |  |  |  |  |  |  |  | 
| 281 |  |  |  |  |  |  | sub _module_pluggable_options { | 
| 282 |  |  |  |  |  |  | # my ($self) = @_; # no point in creating these ops, just to toss $self | 
| 283 | 11 |  |  | 11 |  | 119 | return; | 
| 284 |  |  |  |  |  |  | } | 
| 285 |  |  |  |  |  |  |  | 
| 286 |  |  |  |  |  |  | # load one of the stock plugins, unless requested to squash; unlike normal | 
| 287 |  |  |  |  |  |  | # plugin loading, command-to-plugin mapping conflicts are silently ignored | 
| 288 |  |  |  |  |  |  | sub _load_default_plugin { | 
| 289 | 84 |  |  | 84 |  | 202 | my ($self, $plugin_name, $arg, $plugin_href) = @_; | 
| 290 | 84 | 100 |  |  |  | 241 | unless ($arg->{"no_$plugin_name\_plugin"}) { | 
| 291 | 77 |  |  |  |  | 165 | my $plugin = "App::Cmd::Command::$plugin_name"; | 
| 292 | 77 |  |  |  |  | 191 | Class::Load::load_class($plugin); | 
| 293 | 77 |  |  |  |  | 3380 | for my $command (map { lc } $plugin->command_names) { | 
|  | 185 |  |  |  |  | 399 |  | 
| 294 | 185 |  | 33 |  |  | 781 | $plugin_href->{$command} //= $plugin; | 
| 295 |  |  |  |  |  |  | } | 
| 296 |  |  |  |  |  |  | } | 
| 297 |  |  |  |  |  |  | } | 
| 298 |  |  |  |  |  |  |  | 
| 299 |  |  |  |  |  |  | #pod =method run | 
| 300 |  |  |  |  |  |  | #pod | 
| 301 |  |  |  |  |  |  | #pod   $cmd->run; | 
| 302 |  |  |  |  |  |  | #pod | 
| 303 |  |  |  |  |  |  | #pod This method runs the application.  If called the class, it will instantiate a | 
| 304 |  |  |  |  |  |  | #pod new App::Cmd object to run. | 
| 305 |  |  |  |  |  |  | #pod | 
| 306 |  |  |  |  |  |  | #pod It determines the requested command (generally by consuming the first | 
| 307 |  |  |  |  |  |  | #pod command-line argument), finds the plugin to handle that command, parses the | 
| 308 |  |  |  |  |  |  | #pod remaining arguments according to that plugin's rules, and runs the plugin. | 
| 309 |  |  |  |  |  |  | #pod | 
| 310 |  |  |  |  |  |  | #pod It passes the contents of the global argument array (C<@ARGV>) to | 
| 311 |  |  |  |  |  |  | #pod L>, but C<@ARGV> is not altered by running an App::Cmd. | 
| 312 |  |  |  |  |  |  | #pod | 
| 313 |  |  |  |  |  |  | #pod =cut | 
| 314 |  |  |  |  |  |  |  | 
| 315 |  |  |  |  |  |  | sub run { | 
| 316 | 23 |  |  | 23 | 1 | 2089 | my ($self) = @_; | 
| 317 |  |  |  |  |  |  |  | 
| 318 |  |  |  |  |  |  | # We should probably use Class::Default. | 
| 319 | 23 | 50 |  |  |  | 72 | $self = $self->new unless ref $self; | 
| 320 |  |  |  |  |  |  |  | 
| 321 |  |  |  |  |  |  | # prepare the command we're going to run... | 
| 322 | 23 |  |  |  |  | 90 | my @argv = $self->prepare_args(); | 
| 323 | 23 |  |  |  |  | 94 | my ($cmd, $opt, @args) = $self->prepare_command(@argv); | 
| 324 |  |  |  |  |  |  |  | 
| 325 |  |  |  |  |  |  | # ...and then run it | 
| 326 | 22 |  |  |  |  | 107 | $self->execute_command($cmd, $opt, @args); | 
| 327 |  |  |  |  |  |  | } | 
| 328 |  |  |  |  |  |  |  | 
| 329 |  |  |  |  |  |  | #pod =method prepare_args | 
| 330 |  |  |  |  |  |  | #pod | 
| 331 |  |  |  |  |  |  | #pod Normally App::Cmd uses C<@ARGV> for its commandline arguments. You can override | 
| 332 |  |  |  |  |  |  | #pod this method to change that behavior for testing or otherwise. | 
| 333 |  |  |  |  |  |  | #pod | 
| 334 |  |  |  |  |  |  | #pod =cut | 
| 335 |  |  |  |  |  |  |  | 
| 336 |  |  |  |  |  |  | sub prepare_args { | 
| 337 | 23 |  |  | 23 | 1 | 45 | my ($self) = @_; | 
| 338 | 23 | 100 |  |  |  | 86 | return scalar(@ARGV) | 
| 339 |  |  |  |  |  |  | ? (@ARGV) | 
| 340 |  |  |  |  |  |  | : ($self->default_args->@*); | 
| 341 |  |  |  |  |  |  | } | 
| 342 |  |  |  |  |  |  |  | 
| 343 |  |  |  |  |  |  | #pod =method default_args | 
| 344 |  |  |  |  |  |  | #pod | 
| 345 |  |  |  |  |  |  | #pod If C> is not changed and there are no arguments in C<@ARGV>, | 
| 346 |  |  |  |  |  |  | #pod this method is called and should return an arrayref to be used as the arguments | 
| 347 |  |  |  |  |  |  | #pod to the program.  By default, it returns an empty arrayref. | 
| 348 |  |  |  |  |  |  | #pod | 
| 349 |  |  |  |  |  |  | #pod =cut | 
| 350 |  |  |  |  |  |  |  | 
| 351 | 16 |  |  | 16 |  | 122 | use constant default_args => []; | 
|  | 16 |  |  |  |  | 27 |  | 
|  | 16 |  |  |  |  | 24403 |  | 
| 352 |  |  |  |  |  |  |  | 
| 353 |  |  |  |  |  |  | #pod =method abstract | 
| 354 |  |  |  |  |  |  | #pod | 
| 355 |  |  |  |  |  |  | #pod    sub abstract { "command description" } | 
| 356 |  |  |  |  |  |  | #pod | 
| 357 |  |  |  |  |  |  | #pod Defines the command abstract: a short description that will be printed in the | 
| 358 |  |  |  |  |  |  | #pod main command options list. | 
| 359 |  |  |  |  |  |  | #pod | 
| 360 |  |  |  |  |  |  | #pod =method description | 
| 361 |  |  |  |  |  |  | #pod | 
| 362 |  |  |  |  |  |  | #pod    sub description { "Long description" } | 
| 363 |  |  |  |  |  |  | #pod | 
| 364 |  |  |  |  |  |  | #pod Defines a longer command description that will be shown when the user asks for | 
| 365 |  |  |  |  |  |  | #pod help on a specific command. | 
| 366 |  |  |  |  |  |  | #pod | 
| 367 |  |  |  |  |  |  | #pod =method arg0 | 
| 368 |  |  |  |  |  |  | #pod | 
| 369 |  |  |  |  |  |  | #pod =method full_arg0 | 
| 370 |  |  |  |  |  |  | #pod | 
| 371 |  |  |  |  |  |  | #pod   my $program_name = $app->arg0; | 
| 372 |  |  |  |  |  |  | #pod | 
| 373 |  |  |  |  |  |  | #pod   my $full_program_name = $app->full_arg0; | 
| 374 |  |  |  |  |  |  | #pod | 
| 375 |  |  |  |  |  |  | #pod These methods return the name of the program invoked to run this application. | 
| 376 |  |  |  |  |  |  | #pod This is determined by inspecting C<$0> when the App::Cmd object is | 
| 377 |  |  |  |  |  |  | #pod instantiated, so it's probably correct, but doing weird things with App::Cmd | 
| 378 |  |  |  |  |  |  | #pod could lead to weird values from these methods. | 
| 379 |  |  |  |  |  |  | #pod | 
| 380 |  |  |  |  |  |  | #pod If the program was run like this: | 
| 381 |  |  |  |  |  |  | #pod | 
| 382 |  |  |  |  |  |  | #pod   knight!rjbs$ ~/bin/rpg dice 3d6 | 
| 383 |  |  |  |  |  |  | #pod | 
| 384 |  |  |  |  |  |  | #pod Then the methods return: | 
| 385 |  |  |  |  |  |  | #pod | 
| 386 |  |  |  |  |  |  | #pod   arg0      - rpg | 
| 387 |  |  |  |  |  |  | #pod   full_arg0 - /Users/rjbs/bin/rpg | 
| 388 |  |  |  |  |  |  | #pod | 
| 389 |  |  |  |  |  |  | #pod These values are captured when the App::Cmd object is created, so it is safe to | 
| 390 |  |  |  |  |  |  | #pod assign to C<$0> later. | 
| 391 |  |  |  |  |  |  | #pod | 
| 392 |  |  |  |  |  |  | #pod =cut | 
| 393 |  |  |  |  |  |  |  | 
| 394 | 1 |  |  | 1 | 1 | 14 | sub arg0      { $_[0]->{arg0} } | 
| 395 | 1 |  |  | 1 | 1 | 6 | sub full_arg0 { $_[0]->{full_arg0} } | 
| 396 |  |  |  |  |  |  |  | 
| 397 |  |  |  |  |  |  | #pod =method prepare_command | 
| 398 |  |  |  |  |  |  | #pod | 
| 399 |  |  |  |  |  |  | #pod   my ($cmd, $opt, @args) = $app->prepare_command(@ARGV); | 
| 400 |  |  |  |  |  |  | #pod | 
| 401 |  |  |  |  |  |  | #pod This method will load the plugin for the requested command, use its options to | 
| 402 |  |  |  |  |  |  | #pod parse the command line arguments, and eventually return everything necessary to | 
| 403 |  |  |  |  |  |  | #pod actually execute the command. | 
| 404 |  |  |  |  |  |  | #pod | 
| 405 |  |  |  |  |  |  | #pod =cut | 
| 406 |  |  |  |  |  |  |  | 
| 407 |  |  |  |  |  |  | sub prepare_command { | 
| 408 | 30 |  |  | 30 | 1 | 156 | my ($self, @args) = @_; | 
| 409 |  |  |  |  |  |  |  | 
| 410 |  |  |  |  |  |  | # figure out first-level dispatch | 
| 411 | 30 |  |  |  |  | 108 | my ($command, $opt, @sub_args) = $self->get_command(@args); | 
| 412 |  |  |  |  |  |  |  | 
| 413 |  |  |  |  |  |  | # set up the global options (which we just determined) | 
| 414 | 30 |  |  |  |  | 134 | $self->set_global_options($opt); | 
| 415 |  |  |  |  |  |  |  | 
| 416 |  |  |  |  |  |  | # find its plugin or else call default plugin (default default is help) | 
| 417 | 30 | 50 |  |  |  | 67 | if ($command) { | 
| 418 | 30 |  |  |  |  | 142 | $self->_prepare_command($command, $opt, @sub_args); | 
| 419 |  |  |  |  |  |  | } else { | 
| 420 | 0 |  |  |  |  | 0 | $self->_prepare_default_command($opt, @sub_args); | 
| 421 |  |  |  |  |  |  | } | 
| 422 |  |  |  |  |  |  | } | 
| 423 |  |  |  |  |  |  |  | 
| 424 |  |  |  |  |  |  | sub _prepare_command { | 
| 425 | 32 |  |  | 32 |  | 78 | my ($self, $command, $opt, @args) = @_; | 
| 426 | 32 | 100 |  |  |  | 97 | if (my $plugin = $self->plugin_for($command)) { | 
| 427 | 31 |  |  |  |  | 283 | return $plugin->prepare($self, @args); | 
| 428 |  |  |  |  |  |  | } else { | 
| 429 | 1 |  |  |  |  | 7 | return $self->_bad_command($command, $opt, @args); | 
| 430 |  |  |  |  |  |  | } | 
| 431 |  |  |  |  |  |  | } | 
| 432 |  |  |  |  |  |  |  | 
| 433 |  |  |  |  |  |  | sub _prepare_default_command { | 
| 434 | 1 |  |  | 1 |  | 3 | my ($self, $opt, @sub_args) = @_; | 
| 435 | 1 |  |  |  |  | 6 | $self->_prepare_command($self->default_command, $opt, @sub_args); | 
| 436 |  |  |  |  |  |  | } | 
| 437 |  |  |  |  |  |  |  | 
| 438 |  |  |  |  |  |  | sub _bad_command { | 
| 439 | 1 |  |  | 1 |  | 3 | my ($self, $command, $opt, @args) = @_; | 
| 440 | 1 | 50 |  |  |  | 7 | print "Unrecognized command: $command.\n\nUsage:\n" if defined($command); | 
| 441 |  |  |  |  |  |  |  | 
| 442 |  |  |  |  |  |  | # This should be class data so that, in Bizarro World, two App::Cmds will not | 
| 443 |  |  |  |  |  |  | # conflict. | 
| 444 | 1 |  |  |  |  | 15 | our $_bad++; | 
| 445 | 1 |  |  |  |  | 5 | $self->prepare_command(qw(commands --stderr)); | 
| 446 |  |  |  |  |  |  | } | 
| 447 |  |  |  |  |  |  |  | 
| 448 | 16 | 50 |  | 16 |  | 20342 | END { exit 1 if our $_bad }; | 
| 449 |  |  |  |  |  |  |  | 
| 450 |  |  |  |  |  |  | #pod =method default_command | 
| 451 |  |  |  |  |  |  | #pod | 
| 452 |  |  |  |  |  |  | #pod This method returns the name of the command to run if none is given on the | 
| 453 |  |  |  |  |  |  | #pod command line.  The default default is "help" | 
| 454 |  |  |  |  |  |  | #pod | 
| 455 |  |  |  |  |  |  | #pod =cut | 
| 456 |  |  |  |  |  |  |  | 
| 457 | 1 |  |  | 1 | 1 | 3 | sub default_command { "help" } | 
| 458 |  |  |  |  |  |  |  | 
| 459 |  |  |  |  |  |  | #pod =method execute_command | 
| 460 |  |  |  |  |  |  | #pod | 
| 461 |  |  |  |  |  |  | #pod   $app->execute_command($cmd, \%opt, @args); | 
| 462 |  |  |  |  |  |  | #pod | 
| 463 |  |  |  |  |  |  | #pod This method will invoke C and then C on C<$cmd>. | 
| 464 |  |  |  |  |  |  | #pod | 
| 465 |  |  |  |  |  |  | #pod =cut | 
| 466 |  |  |  |  |  |  |  | 
| 467 |  |  |  |  |  |  | sub execute_command { | 
| 468 | 22 |  |  | 22 | 1 | 69 | my ($self, $cmd, $opt, @args) = @_; | 
| 469 |  |  |  |  |  |  |  | 
| 470 | 22 |  |  |  |  | 53 | local our $active_cmd = $cmd; | 
| 471 |  |  |  |  |  |  |  | 
| 472 | 22 |  |  |  |  | 131 | $cmd->validate_args($opt, \@args); | 
| 473 | 21 |  |  |  |  | 90 | $cmd->execute($opt, \@args); | 
| 474 |  |  |  |  |  |  | } | 
| 475 |  |  |  |  |  |  |  | 
| 476 |  |  |  |  |  |  | #pod =method plugin_search_path | 
| 477 |  |  |  |  |  |  | #pod | 
| 478 |  |  |  |  |  |  | #pod This method returns the plugin_search_path as set.  The default implementation, | 
| 479 |  |  |  |  |  |  | #pod if called on "YourApp::Cmd" will return "YourApp::Cmd::Command" | 
| 480 |  |  |  |  |  |  | #pod | 
| 481 |  |  |  |  |  |  | #pod This is a method because it's fun to override it with, for example: | 
| 482 |  |  |  |  |  |  | #pod | 
| 483 |  |  |  |  |  |  | #pod   use constant plugin_search_path => __PACKAGE__; | 
| 484 |  |  |  |  |  |  | #pod | 
| 485 |  |  |  |  |  |  | #pod =cut | 
| 486 |  |  |  |  |  |  |  | 
| 487 |  |  |  |  |  |  | sub _default_command_base { | 
| 488 | 25 |  |  | 25 |  | 45 | my ($self) = @_; | 
| 489 | 25 |  | 66 |  |  | 83 | my $class = ref $self || $self; | 
| 490 | 25 |  |  |  |  | 75 | return "$class\::Command"; | 
| 491 |  |  |  |  |  |  | } | 
| 492 |  |  |  |  |  |  |  | 
| 493 |  |  |  |  |  |  | sub _default_plugin_base { | 
| 494 | 10 |  |  | 10 |  | 24 | my ($self) = @_; | 
| 495 | 10 |  | 66 |  |  | 35 | my $class = ref $self || $self; | 
| 496 | 10 |  |  |  |  | 44 | return "$class\::Plugin"; | 
| 497 |  |  |  |  |  |  | } | 
| 498 |  |  |  |  |  |  |  | 
| 499 |  |  |  |  |  |  | sub plugin_search_path { | 
| 500 | 10 |  |  | 10 | 1 | 21 | my ($self) = @_; | 
| 501 |  |  |  |  |  |  |  | 
| 502 | 10 |  |  |  |  | 39 | my $dcb = $self->_default_command_base; | 
| 503 | 10 | 100 |  |  |  | 54 | my $ccb = $dcb eq 'App::Cmd::Command' | 
| 504 |  |  |  |  |  |  | ? $self->App::Cmd::_default_command_base | 
| 505 |  |  |  |  |  |  | : $self->_default_command_base; | 
| 506 |  |  |  |  |  |  |  | 
| 507 | 10 |  |  |  |  | 59 | my @default = ($ccb, $self->_default_plugin_base); | 
| 508 |  |  |  |  |  |  |  | 
| 509 | 10 | 100 |  |  |  | 75 | if (ref $self) { | 
| 510 | 8 |  | 50 |  |  | 102 | return $self->{plugin_search_path} //= \@default; | 
| 511 |  |  |  |  |  |  | } else { | 
| 512 | 2 |  |  |  |  | 26 | return \@default; | 
| 513 |  |  |  |  |  |  | } | 
| 514 |  |  |  |  |  |  | } | 
| 515 |  |  |  |  |  |  |  | 
| 516 |  |  |  |  |  |  | #pod =method allow_any_unambiguous_abbrev | 
| 517 |  |  |  |  |  |  | #pod | 
| 518 |  |  |  |  |  |  | #pod If this method returns true (which, by default, it does I), then any | 
| 519 |  |  |  |  |  |  | #pod unambiguous abbreviation for a registered command name will be allowed as a | 
| 520 |  |  |  |  |  |  | #pod means to use that command.  For example, given the following commands: | 
| 521 |  |  |  |  |  |  | #pod | 
| 522 |  |  |  |  |  |  | #pod   reticulate | 
| 523 |  |  |  |  |  |  | #pod   reload | 
| 524 |  |  |  |  |  |  | #pod   rasterize | 
| 525 |  |  |  |  |  |  | #pod | 
| 526 |  |  |  |  |  |  | #pod Then the user could use C for C or C for C and | 
| 527 |  |  |  |  |  |  | #pod so on. | 
| 528 |  |  |  |  |  |  | #pod | 
| 529 |  |  |  |  |  |  | #pod =cut | 
| 530 |  |  |  |  |  |  |  | 
| 531 | 27 |  |  | 27 | 1 | 112 | sub allow_any_unambiguous_abbrev { return 0 } | 
| 532 |  |  |  |  |  |  |  | 
| 533 |  |  |  |  |  |  | #pod =method global_options | 
| 534 |  |  |  |  |  |  | #pod | 
| 535 |  |  |  |  |  |  | #pod   if ($cmd->app->global_options->{verbose}) { ... } | 
| 536 |  |  |  |  |  |  | #pod | 
| 537 |  |  |  |  |  |  | #pod This method returns the running application's global options as a hashref.  If | 
| 538 |  |  |  |  |  |  | #pod there are no options specified, an empty hashref is returned. | 
| 539 |  |  |  |  |  |  | #pod | 
| 540 |  |  |  |  |  |  | #pod =cut | 
| 541 |  |  |  |  |  |  |  | 
| 542 |  |  |  |  |  |  | sub global_options { | 
| 543 | 2 |  |  | 2 | 1 | 10 | my $self = shift; | 
| 544 | 2 | 50 | 50 |  |  | 18 | return $self->{global_options} //= {} if ref $self; | 
| 545 | 0 |  |  |  |  | 0 | return {}; | 
| 546 |  |  |  |  |  |  | } | 
| 547 |  |  |  |  |  |  |  | 
| 548 |  |  |  |  |  |  | #pod =method set_global_options | 
| 549 |  |  |  |  |  |  | #pod | 
| 550 |  |  |  |  |  |  | #pod   $app->set_global_options(\%opt); | 
| 551 |  |  |  |  |  |  | #pod | 
| 552 |  |  |  |  |  |  | #pod This method sets the global options. | 
| 553 |  |  |  |  |  |  | #pod | 
| 554 |  |  |  |  |  |  | #pod =cut | 
| 555 |  |  |  |  |  |  |  | 
| 556 |  |  |  |  |  |  | sub set_global_options { | 
| 557 | 32 |  |  | 32 | 1 | 62 | my ($self, $opt) = @_; | 
| 558 | 32 |  |  |  |  | 69 | return $self->{global_options} = $opt; | 
| 559 |  |  |  |  |  |  | } | 
| 560 |  |  |  |  |  |  |  | 
| 561 |  |  |  |  |  |  | #pod =method command_names | 
| 562 |  |  |  |  |  |  | #pod | 
| 563 |  |  |  |  |  |  | #pod   my @names = $cmd->command_names; | 
| 564 |  |  |  |  |  |  | #pod | 
| 565 |  |  |  |  |  |  | #pod This returns the commands names which the App::Cmd object will handle. | 
| 566 |  |  |  |  |  |  | #pod | 
| 567 |  |  |  |  |  |  | #pod =cut | 
| 568 |  |  |  |  |  |  |  | 
| 569 |  |  |  |  |  |  | sub command_names { | 
| 570 | 6 |  |  | 6 | 1 | 577 | my ($self) = @_; | 
| 571 | 6 |  |  |  |  | 30 | keys $self->_command->%*; | 
| 572 |  |  |  |  |  |  | } | 
| 573 |  |  |  |  |  |  |  | 
| 574 |  |  |  |  |  |  | #pod =method command_groups | 
| 575 |  |  |  |  |  |  | #pod | 
| 576 |  |  |  |  |  |  | #pod   my @groups = $cmd->commands_groups; | 
| 577 |  |  |  |  |  |  | #pod | 
| 578 |  |  |  |  |  |  | #pod This method can be implemented to return a grouped list of command names with | 
| 579 |  |  |  |  |  |  | #pod optional headers. Each group is given as arrayref and each header as string. | 
| 580 |  |  |  |  |  |  | #pod If an empty list is returned, the commands plugin will show two groups without | 
| 581 |  |  |  |  |  |  | #pod headers: the first group is for the "help" and "commands" commands, and all | 
| 582 |  |  |  |  |  |  | #pod other commands are in the second group. | 
| 583 |  |  |  |  |  |  | #pod | 
| 584 |  |  |  |  |  |  | #pod =cut | 
| 585 |  |  |  |  |  |  |  | 
| 586 |  |  |  | 4 | 1 |  | sub command_groups { } | 
| 587 |  |  |  |  |  |  |  | 
| 588 |  |  |  |  |  |  | #pod =method command_plugins | 
| 589 |  |  |  |  |  |  | #pod | 
| 590 |  |  |  |  |  |  | #pod   my @plugins = $cmd->command_plugins; | 
| 591 |  |  |  |  |  |  | #pod | 
| 592 |  |  |  |  |  |  | #pod This method returns the package names of the plugins that implement the | 
| 593 |  |  |  |  |  |  | #pod App::Cmd object's commands. | 
| 594 |  |  |  |  |  |  | #pod | 
| 595 |  |  |  |  |  |  | #pod =cut | 
| 596 |  |  |  |  |  |  |  | 
| 597 |  |  |  |  |  |  | sub command_plugins { | 
| 598 | 8 |  |  | 8 | 1 | 20 | my ($self) = @_; | 
| 599 | 8 |  |  |  |  | 24 | my %seen = map {; $_ => 1 } values $self->_command->%*; | 
|  | 90 |  |  |  |  | 149 |  | 
| 600 | 8 |  |  |  |  | 62 | keys %seen; | 
| 601 |  |  |  |  |  |  | } | 
| 602 |  |  |  |  |  |  |  | 
| 603 |  |  |  |  |  |  | #pod =method plugin_for | 
| 604 |  |  |  |  |  |  | #pod | 
| 605 |  |  |  |  |  |  | #pod   my $plugin = $cmd->plugin_for($command); | 
| 606 |  |  |  |  |  |  | #pod | 
| 607 |  |  |  |  |  |  | #pod This method returns the plugin (module) for the given command.  If no plugin | 
| 608 |  |  |  |  |  |  | #pod implements the command, it returns false. | 
| 609 |  |  |  |  |  |  | #pod | 
| 610 |  |  |  |  |  |  | #pod =cut | 
| 611 |  |  |  |  |  |  |  | 
| 612 |  |  |  |  |  |  | sub plugin_for { | 
| 613 | 67 |  |  | 67 | 1 | 123 | my ($self, $command) = @_; | 
| 614 | 67 | 50 |  |  |  | 135 | return unless $command; | 
| 615 | 67 | 100 |  |  |  | 162 | return unless exists $self->_command->{ $command }; | 
| 616 |  |  |  |  |  |  |  | 
| 617 | 64 |  |  |  |  | 144 | return $self->_command->{ $command }; | 
| 618 |  |  |  |  |  |  | } | 
| 619 |  |  |  |  |  |  |  | 
| 620 |  |  |  |  |  |  | #pod =method get_command | 
| 621 |  |  |  |  |  |  | #pod | 
| 622 |  |  |  |  |  |  | #pod   my ($command_name, $opt, @args) = $app->get_command(@args); | 
| 623 |  |  |  |  |  |  | #pod | 
| 624 |  |  |  |  |  |  | #pod Process arguments and into a command name and (optional) global options. | 
| 625 |  |  |  |  |  |  | #pod | 
| 626 |  |  |  |  |  |  | #pod =cut | 
| 627 |  |  |  |  |  |  |  | 
| 628 |  |  |  |  |  |  | sub get_command { | 
| 629 | 32 |  |  | 32 | 1 | 67 | my ($self, @args) = @_; | 
| 630 |  |  |  |  |  |  |  | 
| 631 | 32 |  |  |  |  | 159 | my ($opt, $args, %fields) | 
| 632 |  |  |  |  |  |  | = $self->_process_args(\@args, $self->_global_option_processing_params); | 
| 633 |  |  |  |  |  |  |  | 
| 634 |  |  |  |  |  |  | # map --help to help command | 
| 635 | 32 | 100 |  |  |  | 230 | if ($opt->{help}) { | 
| 636 | 2 |  |  |  |  | 6 | unshift @$args, 'help'; | 
| 637 | 2 |  |  |  |  | 6 | delete $opt->{help}; | 
| 638 |  |  |  |  |  |  | } | 
| 639 |  |  |  |  |  |  |  | 
| 640 | 32 |  |  |  |  | 177 | my ($command, $rest) = $self->_cmd_from_args($args); | 
| 641 |  |  |  |  |  |  |  | 
| 642 | 32 |  |  |  |  | 116 | $self->{usage} = $fields{usage}; | 
| 643 |  |  |  |  |  |  |  | 
| 644 | 32 |  |  |  |  | 128 | return ($command, $opt, @$rest); | 
| 645 |  |  |  |  |  |  | } | 
| 646 |  |  |  |  |  |  |  | 
| 647 |  |  |  |  |  |  | sub _cmd_from_args { | 
| 648 | 27 |  |  | 27 |  | 54 | my ($self, $args) = @_; | 
| 649 |  |  |  |  |  |  |  | 
| 650 | 27 |  |  |  |  | 54 | my $command = shift @$args; | 
| 651 | 27 |  |  |  |  | 70 | return ($command, $args); | 
| 652 |  |  |  |  |  |  | } | 
| 653 |  |  |  |  |  |  |  | 
| 654 |  |  |  |  |  |  | sub _global_option_processing_params { | 
| 655 | 32 |  |  | 32 |  | 74 | my ($self, @args) = @_; | 
| 656 |  |  |  |  |  |  |  | 
| 657 |  |  |  |  |  |  | return ( | 
| 658 | 32 |  |  |  |  | 119 | $self->usage_desc(@args), | 
| 659 |  |  |  |  |  |  | $self->global_opt_spec(@args), | 
| 660 |  |  |  |  |  |  | { getopt_conf => [qw/pass_through/] }, | 
| 661 |  |  |  |  |  |  | ); | 
| 662 |  |  |  |  |  |  | } | 
| 663 |  |  |  |  |  |  |  | 
| 664 |  |  |  |  |  |  | #pod =method usage | 
| 665 |  |  |  |  |  |  | #pod | 
| 666 |  |  |  |  |  |  | #pod   print $self->app->usage->text; | 
| 667 |  |  |  |  |  |  | #pod | 
| 668 |  |  |  |  |  |  | #pod Returns the usage object for the global options. | 
| 669 |  |  |  |  |  |  | #pod | 
| 670 |  |  |  |  |  |  | #pod =cut | 
| 671 |  |  |  |  |  |  |  | 
| 672 | 1 |  |  | 1 | 1 | 4 | sub usage { $_[0]{usage} }; | 
| 673 |  |  |  |  |  |  |  | 
| 674 |  |  |  |  |  |  | #pod =method usage_desc | 
| 675 |  |  |  |  |  |  | #pod | 
| 676 |  |  |  |  |  |  | #pod The top level usage line. Looks something like | 
| 677 |  |  |  |  |  |  | #pod | 
| 678 |  |  |  |  |  |  | #pod   "yourapp  [options]" | 
| 679 |  |  |  |  |  |  | #pod | 
| 680 |  |  |  |  |  |  | #pod =cut | 
| 681 |  |  |  |  |  |  |  | 
| 682 |  |  |  |  |  |  | sub usage_desc { | 
| 683 |  |  |  |  |  |  | # my ($self) = @_; # no point in creating these ops, just to toss $self | 
| 684 | 30 |  |  | 30 | 1 | 117 | return "%c  %o"; | 
| 685 |  |  |  |  |  |  | } | 
| 686 |  |  |  |  |  |  |  | 
| 687 |  |  |  |  |  |  | #pod =method global_opt_spec | 
| 688 |  |  |  |  |  |  | #pod | 
| 689 |  |  |  |  |  |  | #pod Returns a list with help command unless C has been specified or | 
| 690 |  |  |  |  |  |  | #pod an empty list. Can be overridden for pre-dispatch option processing.  This is | 
| 691 |  |  |  |  |  |  | #pod useful for flags like --verbose. | 
| 692 |  |  |  |  |  |  | #pod | 
| 693 |  |  |  |  |  |  | #pod =cut | 
| 694 |  |  |  |  |  |  |  | 
| 695 |  |  |  |  |  |  | sub global_opt_spec { | 
| 696 | 28 |  |  | 28 | 1 | 48 | my ($self) = @_; | 
| 697 |  |  |  |  |  |  |  | 
| 698 | 28 |  |  |  |  | 50 | my $cmd = $self->{command}; | 
| 699 | 28 |  |  |  |  | 39 | my %seen; | 
| 700 | 112 |  |  |  |  | 250 | my @help = grep { ! $seen{$_}++ } | 
| 701 | 112 |  |  |  |  | 288 | reverse sort map { s/^--?//; $_ } | 
|  | 112 |  |  |  |  | 248 |  | 
| 702 | 28 |  |  |  |  | 121 | grep { $cmd->{$_} eq 'App::Cmd::Command::help' } keys %$cmd; | 
|  | 306 |  |  |  |  | 463 |  | 
| 703 |  |  |  |  |  |  |  | 
| 704 | 28 | 50 |  |  |  | 330 | return (@help ? [ join('|', @help) => "show help" ] : ()); | 
| 705 |  |  |  |  |  |  | } | 
| 706 |  |  |  |  |  |  |  | 
| 707 |  |  |  |  |  |  | #pod =method usage_error | 
| 708 |  |  |  |  |  |  | #pod | 
| 709 |  |  |  |  |  |  | #pod   $self->usage_error("Something's wrong!"); | 
| 710 |  |  |  |  |  |  | #pod | 
| 711 |  |  |  |  |  |  | #pod Used to die with nice usage output, during C. | 
| 712 |  |  |  |  |  |  | #pod | 
| 713 |  |  |  |  |  |  | #pod =cut | 
| 714 |  |  |  |  |  |  |  | 
| 715 |  |  |  |  |  |  | sub usage_error { | 
| 716 | 0 |  |  | 0 | 1 | 0 | my ($self, $error) = @_; | 
| 717 | 0 |  |  |  |  | 0 | die "Error: $error\nUsage: " . $self->_usage_text; | 
| 718 |  |  |  |  |  |  | } | 
| 719 |  |  |  |  |  |  |  | 
| 720 |  |  |  |  |  |  | sub _usage_text { | 
| 721 | 1 |  |  | 1 |  | 3 | my ($self) = @_; | 
| 722 | 1 |  |  |  |  | 4 | my $text = $self->usage->text; | 
| 723 | 1 |  |  |  |  | 151 | $text =~ s/\A(\s+)/!/; | 
| 724 | 1 |  |  |  |  | 3 | return $text; | 
| 725 |  |  |  |  |  |  | } | 
| 726 |  |  |  |  |  |  |  | 
| 727 |  |  |  |  |  |  | #pod =head1 TODO | 
| 728 |  |  |  |  |  |  | #pod | 
| 729 |  |  |  |  |  |  | #pod =for :list | 
| 730 |  |  |  |  |  |  | #pod * publish and bring in Log::Speak (simple quiet/verbose output) | 
| 731 |  |  |  |  |  |  | #pod * publish and use our internal enhanced describe_options | 
| 732 |  |  |  |  |  |  | #pod * publish and use our improved simple input routines | 
| 733 |  |  |  |  |  |  | #pod | 
| 734 |  |  |  |  |  |  | #pod =cut | 
| 735 |  |  |  |  |  |  |  | 
| 736 |  |  |  |  |  |  | 1; | 
| 737 |  |  |  |  |  |  |  | 
| 738 |  |  |  |  |  |  | __END__ |