* MooseX::Getopt::Session: Drop die_on_warning attribute.
[gitmo/MooseX-Getopt.git] / lib / MooseX / Getopt / Parser / Descriptive.pm
1
2 package MooseX::Getopt::Parser::Descriptive;
3
4 use Moose;
5
6 with 'MooseX::Getopt::Parser';
7
8 use Getopt::Long::Descriptive;
9 use MooseX::Getopt::OptionTypeMap;
10
11 #use Smart::Comments;
12
13 # Special configuration for parser
14 has 'config' => (
15     is => 'rw',
16     isa => 'ArrayRef[Str]',
17     auto_deref => 1,
18     default => sub { [] },
19 );
20
21 # Format for usage description
22 has 'format' => (
23     is => 'rw',
24     isa => 'Str',
25     default => 'usage: %c %o',
26 );
27
28
29 sub build_options {
30     my $self = shift;
31     my ($getopt, @attrs) = @_;
32
33     Moose->throw_error('First argument is not a MooseX::Getopt::Session')
34         unless $getopt->isa('MooseX::Getopt::Session');
35
36     my $options = {};
37     my $usage;
38     my (@opts, %cmd_flags_to_names);
39
40     foreach my $attr (@attrs) {
41         my $name = $attr->name;
42
43         my ($flag, @aliases) = $getopt->_get_cmd_flags_for_attr($attr);
44         my $type = $getopt->_get_cmd_type_for_attr($attr);
45
46         $cmd_flags_to_names{$flag} = $name;
47
48         my $opt_string = join '|', $flag, @aliases;
49         $opt_string .= MooseX::Getopt::OptionTypeMap->get_option_type($type);
50
51         my $doc;
52         $doc = $attr->documentation if $attr->has_documentation;
53         $doc = ' ' unless $doc;
54
55         my $is_required = $attr->is_required && !$attr->has_default && !$attr->has_builder;
56
57         push @opts, [
58             $opt_string => $doc,
59             {
60                 ( $is_required ? ( required => $attr->is_required ) : () ),
61             }
62         ];
63     };
64
65     ### MooseX::Getopt::Parser::Descriptive::build_options @opts : @opts
66
67     GETOPT: {
68         local @ARGV = $getopt->argv;
69         ### MooseX::Getopt::Parser::Descriptive::build_options @ARGV : @ARGV
70
71         local $SIG{__WARN__} = sub {
72             return warn @_ if $_[0]=~/^\###/;   # Smart::Comments
73             $getopt->strcat_warning( $_[0] )
74         };
75
76         eval {
77             ($options, $usage) = Getopt::Long::Descriptive::describe_options(
78                 $self->format, @opts, { getopt_conf => [ $self->config ] }
79             );
80         };
81         my $e = $@;
82         $getopt->strcat_warning( $e ) if $e;
83         $getopt->status( ! $e );
84
85         my $extra_argv = \@ARGV;
86         $getopt->extra_argv( $extra_argv );
87     };
88
89     # Convert cmd_flags back to names in options hashref
90     $options = {
91         map {
92             $cmd_flags_to_names{$_} => $options->{$_}
93         } keys %$options,
94     };
95
96     #%options = map { $_ => $options{$_} } grep { defined $options{$_} } keys %options;
97     $getopt->options( $options );
98
99     ### MooseX::Getopt::Parser::Descriptive::build_options $options : $options
100     ### MooseX::Getopt::Parser::Descriptive::build_options $usage : $usage
101     ### MooseX::Getopt::Parser::Descriptive::build_options $getopt->status : $getopt->status
102
103     die join '', $getopt->warning if ($getopt->has_warning || !$getopt->status);
104
105     return $options;
106 };
107
108
109 1;