| App::Yath::Option(3pm) | User Contributed Perl Documentation | App::Yath::Option(3pm) |
App::Yath::Option - Representation of a yath option.
This class represents a single command line option for yath.
You usually will not be creating option instances directly. Usually you will use App::Yath::Options which provides sugar, and helps make sure options get to the right place.
use App::Yath::Options;
# You can specify a single option:
option color => (
prefix => 'display',
category => "Display Options",
description => "Turn color on, default is true if STDOUT is a TTY.",
default => sub { -t STDOUT ? 1 : 0 },
);
# If you are specifying multiple options you can use an option_group to
# define common parameters.
option_group {prefix => 'display', category => "Display Options"} => sub {
option color => (
description => "Turn color on, default is true if STDOUT is a TTY.",
default => sub { -t STDOUT ? 1 : 0 },
);
option verbose => (
short => 'v',
type => 'c',
description => "Be more verbose",
default => 0,
);
};
These can be provided at object construction, or are generated internally.
option foo => (
...,
applicable => sub {
my ($opt, $options) = @_;
...
return $bool;
},
);
REQUIRED
If you do not specify a "name" attribute then the default name will be "PREFIX-TITLE". The name is the main command line argument, so "--PREFIX-TITLE" is the default name.
Here are all the possible types, along with their aliases. You may use the type character, or any of the aliases to specify that type.
Real world example from the debug options (simplified for doc purposes):
option summary => (
type => 'd',
description => "Write out a summary json file, if no path is provided 'summary.json' will be used. The .json extension is added automatically if omitted.",
long_examples => ['', '=/path/to/summary.json'],
# New way to specify an auto-fill value for when no =VAL is provided.
# If you do not specify this the default autofill is '1' for legacy support.
autofill => 'VALUE',
# Old way to autofill a value (default is 1 for auto-fill)
# Using autofill is significantly better.
# You can also use action for additional behavior along with autofill,
# but the default will be your auto-fill value, not '1'.
action => sub {
my ($prefix, $field, $raw, $norm, $slot, $settings) = @_;
# $norm will be '1' if option was used without an argument, so we
# just use the provided value when it is not 1'.
return $$slot = $norm unless $norm eq '1';
# $norm was 1, so this is our no-arg "default" behavior
# Do nothing if a value is already set
return if $$slot;
# Set the default value of 'summary.json'
return $$slot = 'summary.json';
},
);
};
Real world example (simplified for doc purposes):
option dev_libs => (
type => 'D',
short => 'D',
name => 'dev-lib',
category => 'Developer',
description => 'Add paths to @INC before loading ANYTHING. This is what you use if you are developing yath or yath plugins to make sure the yath script finds the local code instead of the installed versions of the same code. You can provide an argument (-Dfoo) to provide a custom path, or you can just use -D without and arg to add lib, blib/lib and blib/arch.',
long_examples => ['', '=lib'],
short_examples => ['', '=lib', 'lib'],
# New way to specify the auto-fill values. This may be a single scalar,
# or an arrayref.
autofill => [ 'lib', 'blib/lib', 'blib/arch' ],
# Old way to specify the auto-fill values.
action => sub {
my ($prefix, $field, $raw, $norm, $slot, $settings) = @_;
# If no argument was provided use the 'lib', 'blib/lib', and 'blib/arch' defaults.
# If an argument was provided, use it.
push @{$$slot} => ($norm eq '1') ? ('lib', 'blib/lib', 'blib/arch') : ($norm);
},
);
yath --opt foo=bar --opt baz=bat
yath --opt foo=a,b,c --opt bar=1,2,3
The yath command obove would produce this structure:
{
foo => ['a', 'b', 'c'],
bar => ['1', '2', '3'],
}
If your title is 'foo-bar_baz' then your field will be 'foo_bar_baz' and your name will be '$PREFIX-foo-bar-baz'.
Basically title is used to generate a sane field and/or name if niether are specified. For field all dashes are changed to underscores. The field is used as a key in the settings: "$settings->prefix->field". For the name all underscores are changed to dashes, if the option is provided by a plugin then 'prefix-' is prepended as well. The name is used for the command line argument '--name'.
If you do not want/like the name and field generated from a title then you can specify a name or title directly.
This name is used as your primary command line argument. If your name is "foo" then your command line argument is "--foo".
The field is used in the settings hash. If your field is "foo" then your settings path is "$setting->prefix->foo".
OPTIONAL
option foo => (
...,
action => sub {
my ($prefix, $field_name, $raw_value, $normalized_value, $slot_ref, $settings, $handler, $options) = @_;
# If no action is specified the following is all that is normally
# done. Having an action means this is not done, so if you want the
# value stored you must call this or similar.
$handler->($slot, $normalized_value);
},
);
For options that do not take arguments, or where argumentes are optional and none are provided, this will be '1'.
The default behavior when no action is specified is usually one of these:
$$slot_ref = $normalized_value;
push @{$$slot_ref} => $normalized_value;
However, to save yourself trouble you can use the $handler instead (see below).
$handler->($slot, $normalized_value);
Example:
option foo => (
...
env_vars => ['foo', 'bar', 'baz'],
clear_env_vars => 1,
):
In this case you are saying option foo can be set to the value of $ENV{foo}, $ENV{bar}, or $ENV{baz} vars if any are defined. The "clear_env_vars" tell it to then delete the environment variables after they are used to set the option. This is useful if you want to use the env var to set an option, but do not want any tests to be able to see the env var after it is used to set the option.
Be sure to use the correct default value for your type. A scalar for 's', an arrayref for 'm', etc.
Note, for any non-scalar type you want to use a subref to define the value:
option foo => (
...
type => 'm',
default => sub { [qw/a b c/] },
);
Example:
option foo => (
prefix => 'blah',
type => 's',
env_vars => ['FOO', 'BAR'],
);
Then command line:
FOO="xxx" yath test
Should be the same as
yath test --foo "xxx"
You can also ask to have the environment variables cleared after they are checked:
option foo => (
prefix => 'blah',
type => 's',
env_vars => ['FOO', 'BAR'],
clear_env_vars => 1, # This tells yath to clear the env vars after they
are used.
);
If you would like the option set to the opposite of the envarinment variable you can prefix it with a '!' character:
option foo =>(
...
env_vars => ['!FOO'],
);
In this case these are equivelent:
FOO=0 yath test
yath test --foo=1
Note that this only works when the variable is defined. If $ENV{FOO} is not defined then the variable is not used.
option foo => (
...
negate => sub {
my ($prefix, $field, $slot, $settings, $options) = @_;
...
},
);
The variables are the same as those in the "action" callback.
option foo => (
...,
normalize => sub {
my $raw = shift;
...
return $norm;
},
);
yath --pre-command-opt COMMAND --command-opt
Most of the time this should be false, very few options qualify as pre-command.
option foo => (
...
pre_process => sub {
my %params = @_;
my $opt = $params{opt};
my $options = $params{options};
my $action = $params{action};
my $type = $params{type};
my $val = $params{val};
...;
},
);
Explanation of paremeters:
There are only so many single-characters available, so options are restricted to picking only 1.
Please note: Yath reserves the right to add any single-character short options in the main distribution, if they conflict with third party plugins/commands then the third party must adapt and change its options. As such it is not recommended to use any short options in third party addons.
This attribute is not used if you do not provide a "short" attribute.
If no callback was provided then this returns true.
Here is a snippet showing the defaults for types:
# First check env vars and return any values from there
...
# Then check for a custom default and use it.
...
return 0
if $self->{+TYPE} eq 'c'
|| $self->{+TYPE} eq 'b';
return []
if $self->{+TYPE} eq 'm'
|| $self->{+TYPE} eq 'D';
return {}
if $self->{+TYPE} eq 'h'
|| $self->{+TYPE} eq 'H';
# All others get undef
return undef;
This is where booleans are turned into 0 or 1, hashes are split, hash-lists are split further, etc.
=item ....
.. option details ...
The source code repository for Test2-Harness can be found at http://github.com/Test-More/Test2-Harness/.
Copyright 2020 Chad Granum <exodist7@gmail.com>.
This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
See http://dev.perl.org/licenses/
| 2023-10-04 | perl v5.36.0 |