App-Easer

 view release on metacpan or  search on metacpan

docs/docs/40-command-options.md  view on Meta::CPAN

  arguments. This is useful if `foo` is just a wrapper around an
  external command, and the rest of the command line has to be taken
  verbatim to be passed down the line. Setting `allow-residual-options`
  to a true value in this case is not strictly needed, because we're not
  using the `+CmdLine` option so we're not checking the command line at
  all; anyway, it's good to document this.
- last, the `bar` child uses the defaults set in the main application
  configuration.

## Option values validation

[Getopt::Long][] enables a first coarse validation, by providing input
types for integers, strings and booleans. Sometimes, though, this might
not be sufficient, e.g. if some options are mutually exclusive and
incompatible.

To address this, it is possible to set key `validate` for performing
validation upon the collected options. This can happen at the top
`configuration` level or inside each command's specification.

In the first case, `validate` must point to an *executable* (i.e.
something that can be resolved by [App::Easer][] into a sub) with the
following signature:

```perl
sub validator ($global, $spec, $args) { die 'sorry!' if error(); }
```

The passed parameters are:

- `$global` the global application object;
- `$spec` the specification for the command under analysis;
- `$args` any command-line arguments residual up to this point.

The *latest* configuration to be checked is available in
`$global->{configs}[-1]` (not exactly an easy place...):

```perl
sub validator ($global, $spec, $args) {
   require Params::Validate;
   Params::Validate::validate(
      $self->{configs}[-1]->%*,  # configuration to validate
      {...}                      # hash for Params::Validate
   );
}
```

The interface above is not officially documented and is subject to
change, e.g. to make it easier to do the validation without having to
fiddle with the internals of `$global`.

When the `validate` key is set in a command's specification, it can
either be an *executable* like described above, or a hash reference. In
this latter case, [Params::Validate][] is used to validate the
configuration against that hash reference. This particular approach can
be considered stable and not subject to changes in the future.


## Configuration file from another option

It's possible to expand the options values gathering with loading them
from a JSON file, whose path is provided among the available options.
This allows e.g. to add a command-line option `-c|--config` to point to
a file with further values.

The indication to also look for a configuration file is usually best
placed at the end of the list:

```perl
my $app = {
    configuration => {
        sources => [qw< +Default +CmdLine +Environment +Parent
            +JsonFileFromConfig
        >],
        ...
    },
    ...
};
```

By default, source `+JsonFileFromConfig` will look into the built
configuration (i.e. coming from all previus sources) for an option
called exactly `config`, and use that as a path to the configuration
file to load.

> This is the exact reason why [The Default source](#the-default-source)
> works differently. It allows setting a default value for this option,
> so that it's considered at the right time if it's not provided on the
> command line, in the environment or from a parent's configuration.

It is possible to set a different configuration key to be used to gather
the path, though, through the command's configuration key
`config-option`. Example:

```perl
my $app = {
    configuration => {
        sources => [qw< +Default +CmdLine +Environment +Parent
            +JsonFileFromConfig
        >],
        ...
    },
    commands => {
        MAIN => {
            'config-option' => 'cnfile',
            options => [
                {
                    getopt => 'cnfile|C=s',
                    environment => 'MAH_CONFIGURATION_FILE',
                    default => "$HOME/.mah-app.json",
                    help => 'path to a JSON configuration file',
                },
                ...
            ],
            ...
        },
        ...
    },
};
```



( run in 0.626 second using v1.01-cache-2.11-cpan-5623c5533a1 )