The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

Term::CLI::Role::CommandSet - Role for (sub-)commands in Term::CLI

VERSION

version 0.059000

SYNOPSIS

 package Term::CLI::Command {

    use Moo;

    with('Term::CLI::Role::CommandSet');

    ...
 };

 my $cmd = Term::CLI::Command->new( ... );

 $cmd->callback->( %args ) if $cmd->has_callback;

 if ( $cmd->has_commands ) {
    my $cmd_ref = $cmd->find_command( $cmd_name );
    die $cmd->error unless $cmd_ref;
 }

 say "command names:", join(', ', $cmd->command_names);

 $cmd->callback->( $cmd, %args ) if $cmd->has_callback;

 %args = $cmd->try_callback( %args );

DESCRIPTION

Role for Term::CLI(3p) elements that contain a set of Term::CLI::Command(3p) objects.

This role is used by Term::CLI(3p) and Term::CLI::Command(3p).

ATTRIBUTES

This role defines two additional attributes:

commands => { ArrayRef | CodeRef }

Either an ArrayRef containing Term::CLI::Command object instances that describe the sub-commands that the command takes, a CodeRef that returns such an ArrayRef, or undef.

Note that the elements of the array are copied over to an internal array, so modifications to the ArrayRef will not be seen.

In case a CodeRef is specified, the CodeRef will be called only once, i.e. when the list of commands needs to be expanded. This allows for delayed object creation, which can be useful in deeper levels of the command hierarchy to reduce startup time.

See also the commands accessor below.

callback => CodeRef

Reference to a subroutine that should be called when the command is executed, or undef.

require_sub_command => Bool

Default is 1 (true).

If the list of commands is not empty, it is normally required that the input contains one of these sub-commands after the "parent" command word. However, it may be desirable to allow the parent command to appear "naked", i.e. without a sub-command.

For such cases, set the require_sub_command to a false value.

See also Term::CLI::Role::CommandSet.

ACCESSORS AND PREDICATES

commands

Returns an ArrayRef containing Term::CLI::Command object instances that describe the sub-commands that the command takes, or undef.

Note that, although a CodeRef can be specified in the constructor, the actual accessor will never return the CodeRef. Rather, it will call the CodeRef once and store the result in an ArrayRef.

has_callback
has_commands

Predicate functions that return whether or not any (sub-)commands have been added to this object.

callback ( [ CODEREF ] )

CODEREF to be called when the command is executed. The callback is called as:

   OBJ->callback->(OBJ,
        status       => Int,
        error        => Str,
        options      => HashRef,
        arguments    => ArrayRef[Value],
        command_line => Str,
        command_path => ArrayRef[InstanceOf['Term::CLI::Command']],
   );

Where:

CLI_REF

Reference to the current Term::CLI object.

status

Indicates the status of parsing/execution so far. It has the following meanings:

< 0

Negative status values indicate a parse error. This is a sign that no action should be taken, but some error handling should be performed. The actual parse error can be found under the error key. A typical thing to do in this case is for one of the callbacks in the chain (e.g. the one on the Term::CLI object) to print the error to STDERR.

0

The command line parses as valid and execution so far has been successful.

> 0

Some error occurred in the execution of the action. Callback functions need to set this by themselves.

error

In case of a negative status, this will contain the parse error. In all other cases, it may or may not contain useful information.

options

Reference to a hash containing all command line options. Compatible with the options hash as set by Getopt::Long(3p).

arguments

Reference to an array containing all the arguments to the command. Each value is a scalar value, possibly converted by its corresponding Term::CLI::Argument's validate method (e.g. 3e-1 may have been converted to 0.3).

unparsed (DEPRECATED)
unprocessed

Reference to an array containing all the words on the command line that have not been parsed as arguments or sub-commands yet. In case of parse errors, this often contains elements, and otherwise should be empty.

command_line

The complete command line as given to the Term::CLI::execute method.

command_path

Reference to an array containing the "parse tree", i.e. a list of object references that represent the commands and sub-commands that led up to this point:

    [
        InstanceOf['Term::CLI'],
        InstanceOf['Term::CLI::Command'],
        ...
    ]

The first item in the command_path list is always the top-level Term::CLI object.

The OBJ_REF will be somewhere in that list; it will be the last one if it is the "leaf" command.

processed

More elaborate "parse tree": a list of hashes that represent all the elements on the command line that led up to this point, minus the Term::CLI object itself.

    [
        {
            element => InstanceOf['Term::CLI::Command'],
            value   => String
        },
        {
            element => InstanceOf['Term::CLI::Argument'],
            value   => String
        },
        {
            element => InstanceOf['Term::CLI::Argument'],
            value   => String
        },
        ...
    ]

The callback is expected to return a hash (list) containing at least the same keys. The command_path, arguments, and options should be considered read-only.

Note that a callback can be called even in the case of errors, so you should always check the status before doing anything.

commands

Return the list of subordinate Term::CLI::Command objects (i.e. "sub-commands") sorted on name.

METHODS

add_command ( CMD_REF, ... )

Add the given CMD_REF command(s) to the list of (sub-)commands, setting each CMD_REF's parent in the process.

command_names

Return the list of (sub-)command names, sorted alphabetically.

complete_line ( TEXT, LINE, START )

Called when the user hits the TAB key for completion.

TEXT is the text to complete, LINE is the input line so far, START is the position in the line where TEXT starts.

The function will split the line in words and delegate the completion to the first Term::CLI::Command sub-command, see Term::CLI::Command.

delete_command ( CMD, ... )

Remove the given CMD command(s) from the list of (sub-)commands, setting each object's parent attribute to undef.

CMD can be a string denoting a command name, or a Term::CLI::Command object reference; if it is a reference, its name will be used to locate the appropriate (sub-)command.

Return the list of objects that were removed.

execute ( Str ) ### DEPRECATED
execute_line ( Str )

Parse and execute the command line consisting of Str (see the return value of readline above).

The command line is split into words using the split_function. If that succeeds, then the resulting list of words is parsed and executed, otherwise a parse error is generated (i.e. the object's callback function is called with a status of -1 and a suitable error field).

For specifying a custom word splitting method, see split_function.

Example:

    while (my $line = $cli->readline(skip => qr/^\s*(?:#.*)?$/)) {
        $cli->execute_line($line);
    }

The command line is parsed depth-first, and for every Term::CLI::Command(3p) encountered, that object's callback function is executed (see callback in Term::CLI::Role::Command).

The execute_line function returns the results of the last called callback function.

  • Suppose that the file command has a show sub-command that takes an optional --verbose option and a single file argument.

  • Suppose the input is:

        file show --verbose foo.txt
  • Then the parse tree looks like this:

        (cli-root)
            |
            +--> Command 'file'
                    |
                    +--> Command 'show'
                            |
                            +--> Option '--verbose'
                            |
                            +--> Argument 'foo.txt'
  • Then the callbacks will be called in the following order:

    1. Callback for 'show'

    2. Callback for 'file'

    3. Callback for Term::CLI object.

The return value from each callback (a hash in list form) is fed into the next callback function in the chain. This allows for adding custom data to the return hash that will be fed back up the parse tree (and eventually to the caller).

find_matches ( Str )

Return a list of all commands in this object that match the Str prefix.

find_command ( Str )

Check whether Str uniquely matches a command in this Term::CLI object. Returns a reference to the appropriate Term::CLI::Command object if successful; otherwise, it sets the object's error field and returns undef.

Example:

    my $sub_cmd = $cmd->find_command($prefix);
    die $cmd->error unless $sub_cmd;
readline ( [ ATTR => VAL, ... ] )

Read a line from the input connected to term, using the Term::ReadLine interface.

By default, it returns the line read from the input, or an empty value if end of file has been reached (e.g. the user hitting Ctrl-D).

The following ATTR are recognised:

skip => RegEx

Override the object's skip attribute.

Skip lines that match the RegEx parameter. A common call is:

    $text = CLI->readline( skip => qr{^\s+(?:#.*)$} );

This will skip empty lines, lines containing whitespace, and comments.

prompt => Str

Override the prompt given by the prompt method.

Examples:

    # Just read the next input line.
    $line = $cli->readline;
    exit if !defined $line;

    # Skip empty lines and comments.
    $line = $cli->readline( skip => qr{^\s*(?:#.*)?$} );
    exit if !defined $line;
try_callback ( ARGS )

Wrapper function that will call the object's callback function if it has been set, otherwise simply returns its arguments.

SEE ALSO

Term::CLI(3p), Term::CLI::Command(3p).

AUTHOR

Steven Bakker <sbakker@cpan.org>, 2018.

COPYRIGHT AND LICENSE

Copyright (c) 2018 Steven Bakker

This module is free software; you can redistribute it and/or modify it under the same terms as Perl itself. See "perldoc perlartistic."

This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.