| Fugu::CLI(3p) | Perl Library Manual | Fugu::CLI(3p) |
NAME
Fugu::CLI - subcommand dispatch for a command-line tool
SYNOPSIS
use Fugu::CLI;
my $cli = Fugu::CLI->new(
name => 'mytool',
usage => '[-c file] <command>',
options => { 'config|c=s' => 'the configuration file' },
commands => {
status => {
summary => 'report the state',
run => sub ($cli, @argv) {
say 'running';
return Fugu::CLI::EXIT_SUCCESS;
},
},
},
);
exit $cli->run(@ARGV);
DESCRIPTION
Fugu::CLI dispatches the subcommands of a command-line tool. A tool declares its global options once and its commands in a table. The module parses the global options, finds the command, parses that command's own options, and calls it. Every command in a tool would otherwise repeat the same Getopt::Long setup.
Output has two channels, and they are not the same channel. Data that a script reads goes to standard output; a command prints it itself. Diagnostics go to the logger, which writes to standard error. Thus "mytool list --names | xargs" keeps working when the tool starts to warn about something.
new
new(%args) creates a dispatcher.
These are the arguments:
- "commands"
- The subcommand table, as a hash reference. This argument is necessary.
- "name"
- The program name in the usage line and in diagnostics. The default is "cli".
- "options"
- The global options, as a hash reference whose keys are Getopt::Long specifications and whose values describe them.
- "usage"
- The one line that follows "usage: <name>".
- "epilogue"
- Text that follows the command list in the help. Put examples here.
- "log"
- The logger. The default is "Fugu::Log->default".
Each entry of "commands" maps a name to a hash reference:
- "run"
- The body, as a code reference. This key is necessary. The body receives the dispatcher and the remaining arguments, and returns an exit code.
- "usage"
- The argument summary of this command.
- "summary"
- One line for the command list.
- "options"
- This command's own options, in the same form as "options".
run
run(@argv) parses, dispatches, and returns the exit code of the command.
An unknown command, a bad option, and a missing command all give "EXIT_INVALID_ARGS" with the usage line on standard error.
A command name of "help", and an empty argument list, print the help and return "EXIT_SUCCESS". Asking for help is not a failure. Every command takes "--help", whether it declared the option or not.
option
option($name) returns a parsed option value. The name is the first name of the specification, so "config|c=s" arrives as "config".
Global options and the running command's options share one namespace. A tool that gives the same name two meanings is a tool nobody can use.
options
options() returns every parsed option as a hash reference.
command
command() returns the name of the command that is running.
name
name() returns the program name.
log
log() returns the logger. A command body reports through it.
print_help
print_help($command) prints the help for one command, or for the whole tool. The help goes to standard output, because the user asked for it.
usage_error
usage_error() prints the usage line on standard error.
command_usage_error
command_usage_error($command) prints the usage line of one command on standard error.
EXIT CODES
The module defines the codes that every tool shares:
- "EXIT_SUCCESS"
- 0
- "EXIT_ERROR"
- 1
- "EXIT_INVALID_ARGS"
- 2
- "EXIT_CONFIG_ERROR"
- 3
- "EXIT_TIMEOUT"
- 7
A caller can import "EXIT_SUCCESS" and "EXIT_ERROR" with "use Fugu::CLI qw(EXIT_SUCCESS EXIT_ERROR)".
A code that belongs to one tool is defined by that tool, not here, and starts above these.
RETURN VALUES
new() returns a dispatcher. run() returns an exit code. option() returns a value or "undef". options() returns a hash reference. name() and command() return a string. log() returns a logger.
EXAMPLES
This example declares a command with its own option:
list => {
summary => 'list the cached images',
usage => '[--names]',
options => { 'names' => 'print names only' },
run => sub ($cli, @argv) {
for my $entry (@entries) {
say $cli->option('names')
? $entry->{name}
: sprintf('%-20s %s', $entry->{name}, $entry->{size});
}
return Fugu::CLI::EXIT_SUCCESS;
},
},
ERRORS
new() dies when the command table is absent, and when a command has no "run" code reference. Both are programming errors that a tool hits on its first run.
run() does not die. Every input failure gives "EXIT_INVALID_ARGS" and a usage line.
SEE ALSO
Fugu::Config, Fugu::Log, Getopt::Long
AUTHORS
Dick Olsson <hi@senzilla.io>
CAVEATS
The module does not catch a die from a command body. A body that must not kill the tool catches its own errors.
Global options must come before the command name, and a command's own options after it. The parser stops at the first argument that is not an option, which is how a command can take an option name that the tool also uses.
| 2026-10-16 | OpenBSD |