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