* Add current $VERSION to all files.
[gitmo/MooseX-Getopt.git] / lib / MooseX / Getopt / Parser / Descriptive.pm
CommitLineData
550da402 1
2package MooseX::Getopt::Parser::Descriptive;
3
96df119b 4our $VERSION = '0.150001';
5
550da402 6use Moose;
7
8with 'MooseX::Getopt::Parser';
9
dd012666 10use MooseX::Getopt::OptionTypeMap;
550da402 11
2a4bd49b 12use Getopt::Long::Descriptive ();
13
c6c1f628 14
dd012666 15# Special configuration for parser
ac2073c8 16has config => (
c5c99e6b 17 is => 'rw',
18 isa => 'ArrayRef[Str]',
19 default => sub { ['default'] },
dd012666 20);
550da402 21
dd012666 22# Format for usage description
ac2073c8 23has format => (
c5c99e6b 24 is => 'rw',
25 isa => 'Str',
dd012666 26 default => 'usage: %c %o',
27);
550da402 28
e013a17c 29# Usage object
30has usage => (
c5c99e6b 31 is => 'rw',
32 isa => 'Maybe[Getopt::Long::Descriptive::Usage]',
e013a17c 33 predicate => 'has_usage',
34);
35
550da402 36
dd012666 37sub build_options {
38 my $self = shift;
c5c99e6b 39 my ( $getopt, @attrs ) = @_;
dd012666 40
c5c99e6b 41 Moose->throw_error("First argument is not a MooseX::Getopt::Session")
dd012666 42 unless $getopt->isa('MooseX::Getopt::Session');
43
c5c99e6b 44 my $options = $getopt->options;
10ed52cb 45 my $new_options = {};
46
19b87ede 47 my $usage;
c5c99e6b 48 my ( @opts, %cmd_flags_to_names );
dd012666 49
50 foreach my $attr (@attrs) {
51 my $name = $attr->name;
c6c1f628 52
c5c99e6b 53 my ( $flag, @aliases ) = $getopt->_get_cmd_flags_for_attr($attr);
dd012666 54 my $type = $getopt->_get_cmd_type_for_attr($attr);
550da402 55
dd012666 56 my $opt_string = join '|', $flag, @aliases;
c5c99e6b 57 $opt_string .= MooseX::Getopt::OptionTypeMap->get_option_type($type)
58 if $type;
550da402 59
c5c99e6b 60 # opt_string is unmangled; parsed options keys are mangled
ec05c565 61 $flag =~ tr/-/_/;
62 $cmd_flags_to_names{$flag} = $name;
63
dd012666 64 my $doc;
65 $doc = $attr->documentation if $attr->has_documentation;
66 $doc = ' ' unless $doc;
550da402 67
10ed52cb 68 my $is_required = !exists $options->{$name}
053fa19e 69 && $attr->is_required
70 && !$attr->has_default
71 && !$attr->has_builder;
550da402 72
dd012666 73 push @opts, [
74 $opt_string => $doc,
550da402 75 {
dd012666 76 ( $is_required ? ( required => $attr->is_required ) : () ),
10ed52cb 77 },
550da402 78 ];
dd012666 79 };
550da402 80
ac2073c8 81 my $warnings = '';
550da402 82
dd012666 83 GETOPT: {
ac2073c8 84 local @ARGV = @{ $getopt->ARGV };
550da402 85
dd012666 86 local $SIG{__WARN__} = sub {
ac2073c8 87 $warnings .= $_[0];
dd012666 88 };
89
90 eval {
c5c99e6b 91 ( $new_options, $usage ) =
92 Getopt::Long::Descriptive::describe_options(
93 $self->format,
94 @opts,
95 { getopt_conf => $self->config }
96 );
dd012666 97 };
c5c99e6b 98 $warnings .= $@ if $@;
dd012666 99
100 my $extra_argv = \@ARGV;
c5c99e6b 101 $getopt->extra_argv($extra_argv);
dd012666 102 };
103
e013a17c 104 # Store usage object
105 $self->usage( $usage );
106
19b87ede 107 # Convert cmd_flags back to names in options hashref
c5c99e6b 108 $new_options = {
109 map { $cmd_flags_to_names{$_} => $new_options->{$_} }
110 keys %$new_options
111 };
10ed52cb 112
e013a17c 113 # Include old options
114 $new_options = { %$options, %$new_options };
19b87ede 115
41dd8ab3 116 $getopt->status( ! $warnings );
10ed52cb 117 $getopt->options( $new_options );
550da402 118
ac2073c8 119 die $warnings if $warnings;
550da402 120
10ed52cb 121 return $new_options;
dd012666 122};
550da402 123
550da402 124
1251;
ac2073c8 126
c5c99e6b 127
ac2073c8 128__END__
129
130=pod
131
132=head1 NAME
133
134MooseX::Getopt::Parser::Descriptive - A Getopt::Long::Descriptive parser for MooseX::Getopt
135
136=head1 SYNOPSIS
137
138 use MooseX::Getopt::Parser::Descriptive;
139
140 my $parser = MooseX::Getopt::Parser::Descriptive->new(
141 format => 'Usage: %c %o',
142 config => ['pass_through']
143 );
144 my $getopt = MooseX::Getopt::Session->new( parser => $parser );
145 my $app = My::App->new( getopt => $getopt );
146
147=head1 DESCRIPTION
148
149This class does L<MooseX::Getopt::Parser> for L<MooseX::Getopt>. This
150class is used by default if L<Getopt::Long::Descriptive> module is
151missing.
152
153=head1 METHODS
154
155=over 4
156
157=item B<build_options ($getopt, @attrs)>
158
159This method parses the CLI options with L<Getopt::Long> and returns a hashref to options list.
160
161The first argument have to be L<MooseX::Getopt::Session> object and
162second argument is a list of attributes which contains options.
163
164=item B<config>
165
166This accessor contains the arrayref to list with special configuration
167keywords for L<Getopt::Long>.
168
169=item B<format>
170
171This accessor contains the string with message printed by
172L<Getopt::Long::Descriptive> if error is occured.
173
174=back
175
176=head1 BUGS
177
178All complex software has bugs lurking in it, and this module is no
179exception. If you find a bug please either email me, or add the bug
180to cpan-RT.
181
182=head1 SEE ALSO
183
184=over 4
185
186=item L<MooseX::Getopt::Parser>
187
188=item L<MooseX::Getopt::Parser::Default>
189
190=item L<MooseX::Getopt::Parser::Long>
191
192=item L<Getopt::Long::Descriptive>
193
194=back
195
196=head1 AUTHOR
197
198Piotr Roszatycki, E<lt>dexter@cpan.orgE<gt>
199
200=head1 COPYRIGHT AND LICENSE
201
202Copyright 2007-2008 by Infinity Interactive, Inc.
203
204L<http://www.iinteractive.com>
205
206This library is free software; you can redistribute it and/or modify
207it under the same terms as Perl itself.
208
209=cut