File Coverage

blib/lib/MooseX/Getopt/Usage.pm
Criterion Covered Total %
statement 4 6 66.6
branch n/a
condition n/a
subroutine 2 2 100.0
pod n/a
total 6 8 75.0


line stmt bran cond sub pod time code
1              
2             package MooseX::Getopt::Usage;
3              
4 1     1   15916 use 5.010;
  1         4  
  1         40  
5             our $VERSION = '0.24';
6              
7 1     1   181 use Moose::Role;
  0            
  0            
8             use Try::Tiny;
9             use MooseX::Getopt::Usage::Formatter;
10              
11             with 'MooseX::Getopt::Basic';
12              
13             # As we don't use GLD insert our own help_flag.
14             has help_flag => (
15             is => 'rw',
16             isa => 'Bool',
17             traits => ['Getopt'],
18             cmd_flag => 'help',
19             cmd_aliases => [qw/? usage/],
20             documentation => "Display the usage message and exit"
21             );
22              
23             # Promote warnings to errors to capture invalid and missing options errors from
24             # Getopt::Long::GetOptions.
25             around _getopt_spec_warnings => sub {
26             shift; my $class = shift;
27             die @_;
28             };
29              
30             sub getopt_usage_config { () }
31              
32             sub getopt_usage {
33             my $proto = shift;
34             my $class = ref $proto || $proto;
35             my %args = @_;
36             my $conf = { $class->getopt_usage_config, %args };
37             if ( ! exists $conf->{colours} && exists $conf->{colors} ) {
38             $conf->{colours} = delete $conf->{colors}
39             }
40             $conf->{getopt_class} = $class;
41             my $fmtr = MooseX::Getopt::Usage::Formatter->new($conf);
42             return $args{man} ? $fmtr->manpage(%args) : $fmtr->usage(%args);
43             }
44              
45             # Replace new_with_options. The way it decides if usage is needed does not fit
46             # our needs as we don't supply a usage object. So we do it here. We also want
47             # access to the $pa object returned from process_argv.
48             around new_with_options => sub {
49             my $orig = shift;
50             my $class = shift;
51             my @params = @_;
52             my $self;
53              
54             my $conf = { $class->getopt_usage_config };
55             $conf->{auto_man} = 1 if not exists $conf->{auto_man};
56             $conf->{auto_help} = 1 if not exists $conf->{auto_help};
57              
58             try {
59             # Get in early on the arg passing to look for help or man options.
60             # This makes sure they still work even when required options are missing,
61             # (which would fail construction and stop us seeing the man option).
62             # See github issue #4
63             my $pa = $class->process_argv(@params);
64             my $cli_params = $pa->cli_params;
65             $class->getopt_usage( man => 1)
66             if $conf->{auto_man} and $class->can('man') and $cli_params->{man};
67             $class->getopt_usage( exit => 0 )
68             if $conf->{auto_help} and $cli_params->{help_flag};
69              
70             # Construct the object in the same way as our super new_with_options
71             $self = $class->new(
72             ARGV => $pa->argv_copy,
73             extra_argv => $pa->extra_argv,
74             ( $pa->usage ? ( usage => $pa->usage ) : () ),
75             %{ $pa->constructor_params }, # explicit params to ->new
76             %{ $pa->cli_params }, # params from CLI
77             );
78             return $self;
79             }
80             catch {
81             if (
82             /Attribute \((\w+)\) does not pass the type constraint because: (.*?) at/
83             ) {
84             $class->getopt_usage( exit => 1, err => "Invalid '$1' : $2" );
85             }
86             elsif (/Attribute \((\w+)\) is required /) {
87             $class->getopt_usage( exit => 2, err => "Required option missing: $1" );
88             }
89             elsif (/^Unknown option:|^Value .*? for option |Option .* does not take an argument/) {
90             # Getopt::Long warnings we promoted in _getopt_spec_warnings
91             s/\n+$//;
92             $class->getopt_usage( exit => 3, err => $_ );
93             }
94             else {
95             die $_;
96             }
97             };
98             };
99              
100             no Moose::Role;
101              
102             1;
103             __END__