App-CmdDispatch
view release on metacpan or search on metacpan
lib/App/CmdDispatch.pm view on Meta::CPAN
$self->_print( $ex->why(), "\n" );
$self->command_hint;
}
else
{
die $ex;
}
};
return;
}
sub command_list
{
my ( $self ) = @_;
return $self->{_command_sorter}->( $self->{table}->command_list() );
}
sub command_hint
{
my ( $self ) = @_;
return $self->{_helper}->hint() if defined $self->{_helper};
$self->_print( "Commands: ", join( ', ', $self->command_list() ), "\n" );
return;
}
sub hint
{
my ( $self, $arg ) = @_;
eval {
$self->run( 'hint', $arg );
1;
} or do
{
return $self->{_helper}->hint( $arg ) if defined $self->{_helper};
$self->_print( "Commands: ", join( ', ', $self->command_list() ), "\n" );
};
return;
}
sub help
{
my ( $self, $arg ) = @_;
eval {
$self->run( 'help', $arg );
1;
} or do
{
return $self->{_helper}->help( $arg ) if defined $self->{_helper};
$self->_print( "Commands: ", join( ', ', $self->command_list() ), "\n" );
};
return;
}
sub alias_list { return $_[0]->{table}->alias_list(); }
sub shell
{
my ( $self ) = @_;
$self->_print( "Enter a command or 'quit' to exit:\n" );
while ( my $line = $self->_prompt( '> ' ) )
{
chomp $line;
next unless $line =~ /\S/;
last if $line eq 'quit';
$self->run( split /\s+/, $line );
}
return;
}
sub _print
{
my $self = shift;
return $self->{io}->print( @_ );
}
sub _prompt
{
my $self = shift;
return $self->{io}->prompt( @_ );
}
sub _initialize_config
{
my ( $self, $config_file ) = @_;
my $conf = Config::Tiny->read( $config_file );
%{ $self->{config} } = (
( $conf->{_} ? %{ delete $conf->{_} } : () ), # first extract the top level
%{$conf}, # Keep any multi-levels that are not aliases
%{ $self->{config} }, # Override with supplied parameters
);
return;
}
sub _initialize_io_object
{
my ( $self ) = @_;
my $io = delete $self->{config}->{'io'};
if( !defined $io )
{
eval {
$io = App::CmdDispatch::IO->new();
} or do {
$io = App::CmdDispatch::MinimalIO->new();
};
die "Unable to create an IO object for CmdDispatch.\n" unless defined $io;
}
elsif( !_is_valid_io_object( $io ) )
{
die "Object supplied as io parameter does not supply correct interface.\n";
}
$self->{io} = $io;
return;
}
sub _is_valid_io_object
{
my ( $io ) = @_;
return unless ref $io;
return 2 == grep { $io->can( $_ ) } qw/print prompt/;
}
sub _setup_commands
{
my ( $self, $commands ) = @_;
$commands = { %{$commands} };
return $commands unless $self->{config}->{default_commands};
foreach my $def ( split / /, $self->{config}->{default_commands} )
{
if( $def eq 'shell' )
{
$commands->{shell} = {
code => \&App::CmdDispatch::shell,
clue => 'shell',
abstract => 'Launch an interactive command shell.',
help => 'Execute commands as entered until quit.',
};
}
elsif( $def eq 'help' )
{
require App::CmdDispatch::Help;
$self->{_helper} = App::CmdDispatch::Help->new( $self, $commands, $self->{config} );
}
else
{
die "Unrecognized default command: '$def'\n";
}
}
return $commands;
}
1;
__END__
=encoding utf-8
=head1 NAME
App::CmdDispatch - Handle command line processing for programs with subcommands
=head1 VERSION
This document describes C<App::CmdDispatch> version 0.44
=head1 SYNOPSIS
use App::CmdDispatch;
my %cmds = (
start => {
code => sub { my $app = shift; print "start: @_\n"; },
clue => 'start [what]',
abstract => 'Start something',
help => 'Start whatever is to be run.',
},
stop => {
code => sub { my $app = shift; print "stop @_\n"; },
lib/App/CmdDispatch.pm view on Meta::CPAN
This optional parameter gives a short (less than a line) explanation of the
command. The idea is to give a hint of the functionality to remind someone who
is mostly familiar with the commands.
When B<hint> is invoked, the C<abstract> is displayed on the same line as the
C<clue>.
If the parameter is not supplied and B<hint> is invoked, nothing is used by
default.
=item help
This optional parameter gives a fuller explanation of the command. It often
extends across several lines. The idea is to explain the functionality of the
command to someone that is not familiar with it.
When B<help> is invoked, the C<help> text is displayed after the line
containing the C<clue>.
If the parameter is not supplied and B<help> is invoked, nothing is used by
default.
=back
=head3 The $options hash
This hash determines some of the default behavior of the C<App::CmdDispatch>
object.
=over 4
=item config_file
This option is the name of a configuration file that is read using the format
specified in L<Config::Tiny>. This sets default configuration parameters and
aliases.
=item default_commands
This string provides a space separated list of default command behaviors.
The two supported behaviors are:
=over 4
=item help
Provide a B<help> command and a B<hint> command through the
L<App::CmdDispatch::Help> module.
=item shell
Prove a shell interface that loops asking for subcommands. Each command
is executed and contol returns to the loop.
=back
=item io
An object supplying input and output services for the CmdDispatcher. This
object must provide both a C<print> method and a C<prompt> method. See
L<App::CmdDispatch::IO> for more information on the interface.
=item help:*
The options beginning with the string 'help:' are described in the docs for
L<App::CmdDispatch::Help>.
=back
=head2 run( $cmd, @args )
This method looks up the supplied command and executes it.
=head2 command_hint( $cmd )
This method prints a short hint listing all commands and aliases or just the
hint for the supplied command.
=head2 hint( $cmd )
This method prints a short hint listing all commands and aliases or just the
hint for the supplied command.
=head2 help( $cmd )
This method prints help for the program or just help on the supplied command.
=head2 shell()
This method start a read/execute loop which supports running multiple commands
in the same execution of the main program.
=head2 get_config()
This method returns a reference to the configuration hash for the dispatcher.
=head2 command_list()
This method returns the list of commands in a defined order.
=head2 alias_list()
This method returns the list of aliases in sorted order.
=head1 CONFIGURATION AND ENVIRONMENT
C<App::CmdDispatch> can read a configuration file specified in a
L<Config::Tiny> supported format. Should be specified in the config parameter.
=head1 DEPENDENCIES
Config::Tiny
Term::Readline
=head1 INCOMPATIBILITIES
None reported.
=head1 BUGS AND LIMITATIONS
( run in 1.865 second using v1.01-cache-2.11-cpan-6aa56a78535 )