App-Easer

 view release on metacpan or  search on metacpan

lib/App/Easer/V1.pod  view on Meta::CPAN


   Description:
       Print list of supported sub-commands

   This command has no options.

   $ ./example.pl inexistent
   cannot find sub-command 'inexistent'

   $ ./example.pl help inexistent
   cannot find sub-command 'inexistent'


=head1 DESCRIPTION

B<NOTE>: THIS DOCUMENT HAS TO BE REVIEWED TO MAKE IT EXPLICIT THAT IT
REFERS TO VERSION 1 OF THE API.

App::Easer::V1 provides the scaffolding for implementing hierarchical
command-line applications in a very fast way. This is Version 1 of the
provided API, which does everything described below.

It makes it extremely simple to generate an application based on
specific interfacing options, while still leaving ample capabilities for
customising the shape of the application. As such, it aims at making
simple things easy and complex things possible, in pure Perl spirit.

An application is defined through a hash reference (or something that
can I<be transformed> into a hash reference, like a JSON-encoded string
containing an object, or Perl code) with the description of the
different aspects of the application and its commands.

By default, only commands need to be provided, each including metadata
for generating a help message, taking parameters from the command line
or other sources (e.g. environment variables), sub-commands, etc., as
well as the actual code to run when the command must be run.

=begin exclude

L<App::Easer::Tutorial> contains an example-based introduction; the rest
of this document provides details on the available interface and
customization capabilities.

=end exclude

=head2 Application High Level View

The following YAML representation gives a view of the structure of an
application managed by C<App::Easer::V1>:

   factory:
      create: «executable»
      prefixes: «hash or array of hashes»
   configuration:
      collect:   «executable»
      merge:     «executable»
      specfetch: «executable»
      validate:  «executable»
      sources:   «array»
      'auto-children':    «false or array»
      'help-on-stderr':   «boolean»
      'auto-leaves':      «boolean»
      'auto-environment': «boolean»
   commands:
      cmd-1:
         «command definition»
      cmd-2:
         «command definition»
      MAIN:
         «command definition»

Strictly speaking, only the C<commands> section is needed in defining an
application; all other parts only deal with I<customizing> the behaviour
of C<App::Easer::V1> itself and take sensible defaults when not provided.

=head2 Anatomy of a run

When an application is run, the following high level algorithm is
followed, assuming the initial command is defined as C<MAIN>:

=over

=item *

the specification of the command is fetched, either from a configuration
hash or by some other method, according to the I<specfetch> hook;

=item *

option values for that command are gathered, I<consuming> part of the
command-line arguments;

=item *

the configuration is optionally validated;

=item *

a I<commit> hook is optionally called, allowing an intermediate command
to perform some actions before a sub-command is run;

=item *

a sub-command is searched and, if present, the process restarts from the
first step above

=item *

when the final sub-command is reached, its C<execute> function is run.

=back

=head2 Factory and Executables

   factory:
      create: «executable»
      prefixes: «hash or array of hashes»

Many customization options appear as C<«executable»>.

At the basic level, these can be just simple references to a sub. In
this case, it is used directly.

When they are provided in some other form, though, a I<factory> function
is needed to turn that alternative representation into a sub reference.

C<App::Easer::V1> comes with a default I<factory> function (described below)
that should cover most of the needs. It is possible to override it by
setting the value for key C<create> inside C<factory>; the default
function is used to generate this new factory, which is then installed
to parse all other C<«executable»> values in the definition.

The default factory manages the following representations:

=over

=item *

sub references are passed through directly;

=item *

strings are first filtered according to the mapping/mappings provided by
the field C<prefixes> in C<factory>, then parsed to get the name of a
package and optionally the name of a sub in that package (each field
that carries an C<«executable»> is associated to a default sub name).

=back

The C<prefixes> can be either a hash reference, or an array of hashes.
The latter allows setting an order for substitutions, e.g. to make sure
that prefix C<::> is tried first if there is also prefix C<:> defined:

   prefixes:
      - '::' : 'What::Ever::'
      - ':' :  'My::App::'

Otherwise, the I<unordered> nature of Perl hashes would risk that the
expansion associated to C<:> is tried first, spoiling the result and
making it unpredictable.

By default, the C<+> character prefix is associated to a mapping into
functions in C<App::Easer::V1> starting with C<stock_>. As an example, the
string C<+CmdLine> is expanded into C<App::Easer::V1::stock_CmdLine>, which
happens to be an existing function (used in parsing command-line
options). It is possible to suppress this expansion by setting a mapping
from C<+> to C<+> in the C<prefixes>, although this will deviate from
the normal working of C<App::Easer::V1>.

=head2 Configuration Parsing Customization

   configuration:
      name:      «string»
      collect:   «executable»
      merge:     «executable»
      namenv:    «executable»
      specfetch: «executable»
      validate:  «executable»
      sources:   «array»
      'auto-children':    «false or array»
      'help-on-stderr':   «boolean»
      'auto-leaves':      «boolean»
      'auto-environment': «boolean»

The C<name> configuration allows setting a name for the application,
which can e.g. be used to generate automatic names for environment
variables to be associated to command options.

One of the central services provided by C<App::Easer::V1> is the automatic
gathering of options values from several sources (command line,
environment, commands upper in the hierarchy, defaults). Another service
is the automatic handling of two sub-commands C<help> and C<commands> to
ease navigating in the hierarchy and get information on the
(sub)commands.

The configuration is collected by a function provided by
C<App::Easer::V1> that can be optionally overridden by setting a
different executable for C<collect> under C<configuration>. This of
course requires re-implementing the options value gathering from
scratch. Calling convention:

   sub ($app, $spec, $args)
   # $app:  hash ref with the details on the whole applications
   # $spec: hash ref with the specification of the command
   # $args: array ref with residual (command line) arguments

This function is expected to return a list with two items, the first a
hash reference with the collected configuration options, the second an
array reference with the residual arguments. The function is called
according to the following calling convention:

   sub ($app, $cspec, $ospec)
   # $app:   hash ref with the details on the whole applications
   # $cspec: hash ref with the specification of the command
   # $ospec: hash ref with the specification of the option

The C<merge> executable allows setting a function that merges several
hashes together. The default implementation operates at the higher level
of the hashes only, giving priority to the first hashes provided (in
order).  Calling convention:

   sub (@list_of_hashes_to_merge) # returns a hash reference

The C<namenv> executable allows setting a function that generates the
name of environment variables based on options specifications. By
default a C<stock_NamEnv> function is used (aliased to C<+NamEnv>) is
used, generating the name of the environment variable by uppercasing the
string generated by the application's name and the option name, joined
by an underscore character.

The C<specfetch> executable allows setting a function to perform
resolution of a command identifier (as e.g. stored in the C<children>)
or an upper command) into a specification. By default the internal
function corresponding to the executable specification string
C<+SpecFromHash> is used, insisting that the whole application is
entirely pre-assembled in the specification hash/object; it's also
possible to use C<+SpecFromHashOrModule> for allowing searching through
modules too.

The C<validate> executable allows setting a validator. By default the
validation is performed using L<Params::Validate> (if available, it is
anyway loaded only when needed).

It is possible to set several I<sources> for gathering options values,
setting them using the C<sources> array. By default it is set to the
ordered list with C<+Default>, C<+CmdLine>, C<+Environment>, and
C<+Parent>, , meaning that options from the command line will have the
highest precedence, then the environment, then whatever comes from the
parent command configuration, then default values if present. This can
be set explicitly with C<+DefaultSources>.

As an alternative, C<sources> can be set to C<+SourcesWithFiles>, which
adds C<+JsonFileFromConfig> and C<+JsonFiles> to the ones above. The
former looks for a configuration named C<config> (or whatever is set as
C<config-option> in the overall configuration hash) to load a JSON file
with additional configurations; the latter looks for a list of JSON
files to try in C<config-files> inside the configuration hash.

=over

Although the C<+Default> source is put I<first>, it actually acts as the
one with the I<least precedence> by how it is coded and how the merging
algorithm is implemented. From a practical point of view it's I<like> it
were put last, but is put first instead so that its defaults can be
applied as options are gathered along the way.

One case where this comes handy is in managing a C<--config> option to
pass a configuration file name to load some external file for additional
configurations (e.g. sources option C<+SourcesWithFiles>). In it,
default configuration must still appear with the I<least precedence>,
but still it can be handy to set a default file to load upon starting,
which means that it's handy to have this default at hand before the
configuration files are supposed to be loaded.

=back

As anticipated, the C<help> and C<commands> sub-commands are
automatically generated and associated to each command by default (more
or less). If this is not the desired behaviour, it is possible to either
disable the addition of the C<auto-children> completely (by setting a
false value), or provide an array of children names that will be added
automatically to each command (again, more or less).

It should be noted that both C<validate> and C<sources> are also part of
the specific setup for each command. As such, they will be rarely set at
the higher C<configuration> level and the whole C<configuration> section
can normally be left out of an application's definition.

Option C<help-on-stderr> allows printing the two stock helper
commands C<help> and C<commands> on standard error instead of standard
output (which is the default).

Option C<auto-leaves> allows setting any command that has no I<explicit>
sub-command as a leaf, which prevents it from getting a C<help> and a
C<commands> sub-command (or whatever has been put to override them). As
of version 0.007002 this is set to a I<true> value by default, but can
still be set to a I<false> value if the automatic sub-commands above are
deemed necessary for commands that have no explicit children in the
hierarchy.

Option C<auto-environment> turns on automatic addition of environment
variables to options, by setting the associated setting to 1. This can
also be set locally in a command.

=head2 Commands Specifications

Commands are stored in a hash of hashes, where the key represents an
internal I<identifier> for the command, which is then used to build the
hierarchy (each command can have a C<children> element where these
identifier are listed, or direct definitions for some of the children).

The command definition is a hash with the following shape:

   name: foo
   help: foo the bar
   description: foo allows us to foo the bar
   supports: ['foo', 'Foo']

   options:
     - name: whip
       getopt: 'whip|w=s'
       environment: FOO_WHIP
       default: gargle
       help: 'beware of the whip'
   auto-environment: 0
   allow-residual-options: 0
   sources: ['+CmdLine', '+Environment', '+Parent', '+Default']

   collect:  «executable»
   merge:    «executable»
   validate: ... «executable» or data structure...
   commit:   «executable»
   execute:  «executable»

   children: ['foo.bar', 'baz', {...}]
   default-child: 'foo.bar'
   dispatch: «executable»
   fallback: «executable»
   fallback-to: 'baz'
   fallback-to-default: 1
   leaf: 0
   no-auto: 1

The following keys are supported:

=over

=item C<name>



( run in 1.304 second using v1.01-cache-2.11-cpan-75ffa21a3d4 )