App-Easer

 view release on metacpan or  search on metacpan

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

Anything different from the default is a liability.

=item C<help>

A concise form of help, ideally a single line to explain what the
(sub-)command does. It is used when generating the whole help for the
command, as well as the list of sub-commands of the help for the parent
command.

=item C<help_channel>

String. Defaults to C<-STDOUT:encoding(UTF-8)>.

Set the output channel for automatic commands C<help>, C<commands>, and
C<tree>.

It can be set to:

=over

=item *

a sub reference, which will be called with the following signature:

   sub channel ($cmd_object, @stuff_to_print);

=item *

a filehandle, used to print out stuff

=item *

a reference to a scalar, where the output will be placed

=item *

a string of the form C<filename[:binmode]>, where C<filename> can B<NOT>
contain the character C<:>. The file will be opened and if the
C<binmode> part is provided, C<binmode()> will be called on the
resulting filehandle with the provided value.

If the C<filename> part is C<-> or C<-stdout> (case insensitive), then
C<STDOUT> will be used. If C<filename> is C<-stderr> (case insensitive),
then C<STDERR> will be used.

=back

=item C<name>

String.

Name of the command. If absent, the first item in the C<alias> array is
used.

=item C<options>

Array of items.

See L</OPTIONS>.

=item C<params_validate>

Hash reference or C<undef>. Ignored if L</validate> is set.

If passed as a hash reference, two keys are supported:

=over

=item C<args>

call C<Params::Validate::validate_pos> on the C<residual_args> (see
L</OPTIONS>).

=item C<config>

call C<Params::Validate::validate> on the collected I<merged>
configuration (see L</OPTIONS>).

=back

=item C<sources>

Array of items.

See L</OPTIONS>.

=item C<validate>

Sub reference for performing validation. Will be called during the
validation phase and passed the command object instance:

   $validation_sub->($self);

If set, L</params_validate> is ignored.

=back

The following YAML representation gives an overview of the elements that
define an application managed by C<App::Easer::V2>, highlighting the
necessary or I<strongly suggested> ones at the beginning:

  aliases: «array of strings»
  execute: «executable»
  help: «string»
  options: «array of hashes»

  allow_residual_options: «boolean»
  auto_environment: «boolean»
  children: «array of hashes»
  children_prefixes: «array of strings»
  commit: «executable»
  default_child: «string»
  description: «string»
  environment_prefix: «string»
  fallback_to: «string»
  force_auto_children: «boolean»
  hashy_class: «string»
  help_channel: «string»
  name: «string»
  params_validate: «hash»
  sources: «array of items»
  validate: «executable»

As anticipated, it's entirely up to the user to decide what style is
best, i.e. define applications through metadata only, through
object-oriented derivation, or through a mix of the two. The following
examples are aimed at producing the same application:

   # metadata (mostly)
   my $app_as_metadata = {
      aliases => [qw< this that >],
      help => 'this is the application, but also that',
      options => [ { getopt => 'foo|f=s', default => 'bar' } ],
      execute => sub ($app) {
         say 'foo is ', $app->config('foo');
         return 0;
      },
   };

   # class only
   package ThisThatApp;
   use App::Easer::V2 '-command';
   sub aliases ($self) { return [qw< this that >] }
   sub help ($self) { return 'this is the application, but also that' }
   sub options ($self) { [ { getopt => 'foo|f=s', default => 'bar' } ] }
   sub execute ($self) {
      say 'foo is ', $self->config('foo');
      return 0;
   }

   # mixed style
   package ThisThatMixedApp;
   use App::Easer::V2 -command => -spec => {
      aliases => [qw< this that >],
      help => 'this is the application, but also that',
      options => [ { getopt => 'foo|f=s', default => 'bar' } ],
   };
   sub execute ($self) {
      say 'foo is ', $self->config('foo');
      return 0;
   }

The last style allows keeping data mostly as data, while leaving the
freedom to implement the logic as proper methods, which can be
beneficial for e.g. sharing common logic among several commands.

=head1 App::Easer::V2::Command METHODS

When a command is created, it is (usually) an instance of class
C<App::Easer::V2::Command> or a descendant. As such, it has the
methods explained in the following list, which at the moment appear as
public ones although some might be hidden in the future (stable ones are
expressely marked so).

=over

=item C<auto_children>

   my @classes = $self->auto_children;
   my @objects = $self->auto_children(1);

Return a list of the automatic children (C<help>, C<commands>, and

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

bug from the past of Perl is addressed.

=item C<merge_hashes>

   my $merged = $self->merge_hashes(@inputs);

Takes a list of input hash references and generates a merged version of
all of them. Hashes in C<@inputs> are supposed to be provided in
priority order, where those coming first take precedence over those
coming next.

=item C<name>

   my $name = $self->name;
   $self->name($new_name);

Get/set name of command. If not present, the first item of C<aliases> is
used. If this is not set too, or empty, string C<** no name **> is used.

See L</Application High Level View>.

=item C<name_for_option>

   my $opt_name = $self->name_for_option($opt_spec_hashref);

Get the option's name, either from its C<name> key, or deriving it from
C<getopt>, or from C<environment>. Returns C<~~~> if none of them works.

=item C<new>

   my $instance = $class->new(@spec);
   my $other    = $class->new(\%spec);

Instantiate a new object, using the provided values.

In derived classes, additional specifications are also taken from the
package variable C<$class . '::app_easer_spec'>, if set.

=item C<options>

   my @options_aoh = $self->options;
   $self->options(\@new_options);

See L</Application High Level View> and L</OPTIONS>. The returned list
if passed through C<resolve_options> anyway, e.g. to inherit options.

=item C<options_help>

   my $options_help = $self->options_help;
   $self->options_help($new_help);

Set text to be printed for the options.

If set to a plain string, that string is all that will be printed, i.e.
no automatic help text from C<options> will be generated.

If set to a hash reference, two keys are supported: C<preamble> and
C<postamble>. When present, they will be printed respectively before and
after the help text generated automatically from C<options>.

=item C<params_validate>

   my $href_or_undef = $self->params_validate;
   $self->params_validate($new_pv_conf);

See L</Application High Level View>.

=item C<parent>

   my $parent_command = $self->parent;

Get the parent command.

=item C<ref_to_sub>

   my $sub = $self->ref_to_sub($locator);

Turn a I<locator> for a sub into a proper reference to a sub. The
C<$locator> can be:

=over

=item *

a sub reference, that is returned unmodified;

=item *

an array reference with two items inside, i.e. a class/module name
followed by a method/function name

=item *

a string pointing to the function, either fully qualified as in
C<My::Class::function> or as a plain name that will be looked for in the
class of C<$self>.

=back

=item C<residual_args>

   my @residual_args = $self->residual_args;
   $self->residual_args(\@new_args);

Access the list of I<residual> (i.e. unparsed) arguments from the
command line.

=item C<resolve_options>

   my @options = $self->resolve_options($single_specification);

Expand a C<$single_specification> into one or more options. Basic
optiosn specifications are hash references, but they might be strings
like C<+parent> (for inheriting all that is I<transmitted> from a parent
command) or regular expressions to bulk import options based on their
names.

=item C<root>

   my $root_command = $self->root;

Generalization of L</parent> to go all the way up to the topmost command
of the chain. Available after version C<2.007001>.

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

   $self->set_config(foo => 'bar');

Set a new value for a configuration, overriding what has been found out
from the several input sources.

=item C<set_config_hash>

   $self->set_config_hash($new_merged_config);
   $self->set_config_hash($new_overall, 1);

Set a new value for the whole configuration hash.

In the first form (no second parameter, or second parameter set to a
false value), only the I<merged> configuration hash is set, i.e. what is
returned by a call like C<< $instance->configuration_hash >>. In
practical terms, it replaces what can be taken when setting
L</config_hash_key> to either C<merged> (the default value) or
C<override>.

The second form allows setting the whole underlying data structure that
can be taken by a call like C<< $instance->configuration_hash(1) >>.
This allows messing up with the whole process.

=item C<slot>

   my $hashref = $self->slot;
   $self->slot($new_data);

C<App::Easer::V2> uses a blessed hash reference to manage all data
related to an object representing a command. To minimize overlapping
with a user's object data, all data for C<App::Easer::V2> is kept in a
sub-hash pointed by the C<slot> key, like this:

   bless {
      $class_name => {
         ... all actual App::Easer::V2 stuff here ...
      }
   }, $hashy_class;

This method gives access to this slot and can be overridden to keep this
data elsewhere, e.g. in an array element or in an inside-out object,
without the need to re-implement all accessors.

=item C<slurp>

   my $contents   = $self->slurp($filename);
   my $contents_2 = $self->slurp($filename, '<:raw');

Get the whole contents from a file, optionally specifying the mode for
openining the file. By default, UTF-8 encoding is assumed and enforced.

Use of this method is discouraged and not future-proof.

=item C<sources>

   my @sources = $self->sources;
   $self->sources(\@new_sources_list);

See L</Application High Level View> and L</OPTIONS>.

=item C<validate>

   $self->validate(\&validation_sub);
   $self->validate;

Performs validation.

When a validation sub is set (either calling with a parameter, or
setting it via C<validate> in L</new>) it will be called, receiving
C<$self> as the only parameter:

   $sub->($self);

The validator is supposed to throw an exception upon validation failure.

If no validation sub is set, L</params_validate> is looked for. If
present, validation is applied according to it, using
L<Params::Validate>.

=back

=head1 OPTIONS

The main capability provided by C<App::Easer> is the flexibility to
handle options, collecting them from several sources and merging them
together according to priorities.

Supported options are set in an array of hashes (or strings) pointed by
the C<options> key. Each hash in the array sets the details regarding a
single option.  When provided as string, the option is I<inherited> from
a parent, allowing the sub-command to expose the same option as the
parent. This gives freedom to put options and values either in the
parent or in the descendant command, providing flexibility.

This is a YAML overview of how to set one option as a hash:

   name: «string»
   help: «string»
   transmit: «boolean»
   transmit_exact: «boolean»
   getopt: «string»
   environment: «string» or 1
   default: any value

A few keys inside the hash regard the option itself, like:

=over

=item * C<name>

name of the option. This is not mandatory if C<getopt> is present, which
gets the name automatically from the first alias of the option itself;

=item * C<help>

some help about the option.

=item * C<transmit>

boolean to set whether an option can be easily "inherited" by a
sub-command (without the need to put all attributes of the option once
again).

=item * C<transmit_exact>

boolean to set whether the option must be spelled exactly to be
inherited (no inheritance via a regular expression).

=back

=head2 Option Values Collection (C<sources>)

The collection is performed thanks to I<sources>, which can be set with
the corresponding C<sources> key or method (depending on the style).
C<App::Easer> comes with several sources for getting configurations from
a variety of places, but still leaves the door open to add more



( run in 0.816 second using v1.01-cache-2.11-cpan-39bf76dae61 )