* MooseX::Getopt::Parser::Descriptive: fixed regression: does not require CLI param...
[gitmo/MooseX-Getopt.git] / lib / MooseX / Getopt.pm
CommitLineData
5dac17c3 1
2package MooseX::Getopt;
3use Moose::Role;
4
550da402 5use Moose::Util::TypeConstraints;
6
8034a232 7use MooseX::Getopt::OptionTypeMap;
550da402 8
c6c1f628 9use MooseX::Getopt::Session;
550da402 10
5dac17c3 11use MooseX::Getopt::Meta::Attribute;
0f8232b6 12use MooseX::Getopt::Meta::Attribute::NoGetopt;
5dac17c3 13
75a6449b 14
e4ab19b9 15our $VERSION = '0.15';
8034a232 16our $AUTHORITY = 'cpan:STEVAN';
17
550da402 18
c6c1f628 19use constant _default_getopt_session => 'MooseX::Getopt::Session';
20
21
550da402 22has ARGV => (
23 is => 'rw',
24 isa => 'ArrayRef',
25 metaclass => 'NoGetopt',
26);
27
28has extra_argv => (
29 is => 'rw',
30 isa => 'ArrayRef',
31 metaclass => 'NoGetopt',
32);
33
c6c1f628 34has getopt => (
550da402 35 is => 'rw',
c6c1f628 36 isa => 'MooseX::Getopt::Session',
550da402 37 metaclass => 'NoGetopt',
38);
3899e5df 39
ee211848 40
c6c1f628 41sub new_with_options {
42 my $class = shift;
6bb4cb66 43
c6c1f628 44 Moose->throw_error("Single parameters to new_with_options() must be a HASH ref")
45 if ref $_[0] and ref $_ ne 'HASH';
75a6449b 46
c6c1f628 47 my %params = ( @_ == 1 ? %{ $_[0] } : @_ );
6bb4cb66 48
c6c1f628 49 my $getopt = defined $params{getopt}
50 ? $params{getopt}
c7ecf9ea 51 : $class->_default_getopt_session->new(
053fa19e 52 classes_filter => sub { $_ eq $class },
53 params => \%params,
c7ecf9ea 54 );
ee211848 55
c6c1f628 56 my %options = $getopt->options;
ee211848 57
c6c1f628 58 $class->new(
59 ARGV => [ $getopt->argv ], # backward compatibility
60 extra_argv => [ $getopt->extra_argv ], # backward compatibility
61 getopt => $getopt,
053fa19e 62 %{ $getopt->params }, # params from session object
63 %params, # explicit params to ->new
64 %options, # params from CLI
ee211848 65 );
c6c1f628 66};
0e715336 67
0e715336 68
bff3807b 69sub _compute_getopt_attrs {
70 my $class = shift;
c6c1f628 71
72 return grep {
73 $_->does('MooseX::Getopt::Meta::Attribute::Trait')
bff3807b 74 or
75 $_->name !~ /^_/
adbe3e57 76 } grep {
77 !$_->does('MooseX::Getopt::Meta::Attribute::Trait::NoGetopt')
c6c1f628 78 } $class->meta->compute_all_applicable_attributes;
79};
4ad81caf 80
5dac17c3 81
8034a232 82no Moose::Role; 1;
5dac17c3 83
84__END__
85
86=pod
87
88=head1 NAME
89
8034a232 90MooseX::Getopt - A Moose role for processing command line options
5dac17c3 91
92=head1 SYNOPSIS
93
4e086633 94 ## In your class
5dac17c3 95 package My::App;
96 use Moose;
4e086633 97
5dac17c3 98 with 'MooseX::Getopt';
4e086633 99
5dac17c3 100 has 'out' => (is => 'rw', isa => 'Str', required => 1);
101 has 'in' => (is => 'rw', isa => 'Str', required => 1);
4e086633 102
5dac17c3 103 # ... rest of the class here
4e086633 104
5dac17c3 105 ## in your script
106 #!/usr/bin/perl
4e086633 107
5dac17c3 108 use My::App;
4e086633 109
5dac17c3 110 my $app = My::App->new_with_options();
111 # ... rest of the script here
4e086633 112
5dac17c3 113 ## on the command line
114 % perl my_app_script.pl -in file.input -out file.dump
115
116=head1 DESCRIPTION
117
4e086633 118This is a role which provides an alternate constructor for creating
119objects using parameters passed in from the command line.
8034a232 120
4e086633 121This module attempts to DWIM as much as possible with the command line
122params by introspecting your class's attributes. It will use the name
123of your attribute as the command line option, and if there is a type
8034a232 124constraint defined, it will configure Getopt::Long to handle the option
3899e5df 125accordingly.
126
2814de27 127You can use the trait L<MooseX::Getopt::Meta::Attribute::Trait> or the
128attribute metaclass L<MooseX::Getopt::Meta::Attribute> to get non-default
129commandline option names and aliases.
3899e5df 130
2814de27 131You can use the trait L<MooseX::Getopt::Meta::Attribute::Trait::NoGetopt>
132or the attribute metaclass L<MooseX::Getopt::Meta::Attribute::NoGetopt>
0f8232b6 133to have C<MooseX::Getopt> ignore your attribute in the commandline options.
134
3899e5df 135By default, attributes which start with an underscore are not given
136commandline argument support, unless the attribute's metaclass is set
3d9a716d 137to L<MooseX::Getopt::Meta::Attribute>. If you don't want you accessors
138to have the leading underscore in thier name, you can do this:
139
140 # for read/write attributes
141 has '_foo' => (accessor => 'foo', ...);
4e086633 142
3d9a716d 143 # or for read-only attributes
4e086633 144 has '_bar' => (reader => 'bar', ...);
3d9a716d 145
4e086633 146This will mean that Getopt will not handle a --foo param, but your
147code can still call the C<foo> method.
8034a232 148
ee69c4ba 149If your class also uses a configfile-loading role based on
150L<MooseX::ConfigFromFile>, such as L<MooseX::SimpleConfig>,
151L<MooseX::Getopt>'s C<new_with_options> will load the configfile
b4a79051 152specified by the C<--configfile> option (or the default you've
153given for the configfile attribute) for you.
154
155Options specified in multiple places follow the following
156precendence order: commandline overrides configfile, which
157overrides explicit new_with_options parameters.
ee69c4ba 158
8034a232 159=head2 Supported Type Constraints
160
161=over 4
162
163=item I<Bool>
164
4e086633 165A I<Bool> type constraint is set up as a boolean option with
8034a232 166Getopt::Long. So that this attribute description:
167
168 has 'verbose' => (is => 'rw', isa => 'Bool');
169
4e086633 170would translate into C<verbose!> as a Getopt::Long option descriptor,
8034a232 171which would enable the following command line options:
172
173 % my_script.pl --verbose
4e086633 174 % my_script.pl --noverbose
175
8034a232 176=item I<Int>, I<Float>, I<Str>
177
4e086633 178These type constraints are set up as properly typed options with
8034a232 179Getopt::Long, using the C<=i>, C<=f> and C<=s> modifiers as appropriate.
180
181=item I<ArrayRef>
182
183An I<ArrayRef> type constraint is set up as a multiple value option
184in Getopt::Long. So that this attribute description:
185
186 has 'include' => (
4e086633 187 is => 'rw',
188 isa => 'ArrayRef',
8034a232 189 default => sub { [] }
190 );
191
4e086633 192would translate into C<includes=s@> as a Getopt::Long option descriptor,
8034a232 193which would enable the following command line options:
194
195 % my_script.pl --include /usr/lib --include /usr/local/lib
196
197=item I<HashRef>
198
199A I<HashRef> type constraint is set up as a hash value option
200in Getopt::Long. So that this attribute description:
201
202 has 'define' => (
4e086633 203 is => 'rw',
204 isa => 'HashRef',
8034a232 205 default => sub { {} }
206 );
207
4e086633 208would translate into C<define=s%> as a Getopt::Long option descriptor,
8034a232 209which would enable the following command line options:
210
211 % my_script.pl --define os=linux --define vendor=debian
212
213=back
214
215=head2 Custom Type Constraints
216
4e086633 217It is possible to create custom type constraint to option spec
8034a232 218mappings if you need them. The process is fairly simple (but a
4e086633 219little verbose maybe). First you create a custom subtype, like
8034a232 220so:
221
222 subtype 'ArrayOfInts'
223 => as 'ArrayRef'
224 => where { scalar (grep { looks_like_number($_) } @$_) };
225
226Then you register the mapping, like so:
227
228 MooseX::Getopt::OptionTypeMap->add_option_type_to_map(
229 'ArrayOfInts' => '=i@'
230 );
231
4e086633 232Now any attribute declarations using this type constraint will
8034a232 233get the custom option spec. So that, this:
234
235 has 'nums' => (
236 is => 'ro',
237 isa => 'ArrayOfInts',
238 default => sub { [0] }
239 );
240
241Will translate to the following on the command line:
242
243 % my_script.pl --nums 5 --nums 88 --nums 199
244
4e086633 245This example is fairly trivial, but more complex validations are
8034a232 246easily possible with a little creativity. The trick is balancing
247the type constraint validations with the Getopt::Long validations.
248
249Better examples are certainly welcome :)
250
f63e6310 251=head2 Inferred Type Constraints
252
253If you define a custom subtype which is a subtype of one of the
254standard L</Supported Type Constraints> above, and do not explicitly
255provide custom support as in L</Custom Type Constraints> above,
256MooseX::Getopt will treat it like the parent type for Getopt
257purposes.
258
259For example, if you had the same custom C<ArrayOfInts> subtype
260from the examples above, but did not add a new custom option
261type for it to the C<OptionTypeMap>, it would be treated just
262like a normal C<ArrayRef> type for Getopt purposes (that is,
263C<=s@>).
264
5dac17c3 265=head1 METHODS
266
267=over 4
268
269=item B<new_with_options (%params)>
270
4e086633 271This method will take a set of default C<%params> and then collect
8034a232 272params from the command line (possibly overriding those in C<%params>)
273and then return a newly constructed object.
274
f63e6310 275If L<Getopt::Long/GetOptions> fails (due to invalid arguments),
276C<new_with_options> will throw an exception.
277
fad5da09 278If you have L<Getopt::Long::Descriptive> a the C<usage> param is also passed to
279C<new>.
280
3899e5df 281=item B<ARGV>
282
283This accessor contains a reference to a copy of the C<@ARGV> array
f63e6310 284as it originally existed at the time of C<new_with_options>.
285
286=item B<extra_argv>
287
288This accessor contains an arrayref of leftover C<@ARGV> elements that
289L<Getopt::Long> did not parse. Note that the real C<@ARGV> is left
290un-mangled.
3899e5df 291
5dac17c3 292=item B<meta>
293
8034a232 294This returns the role meta object.
295
5dac17c3 296=back
297
298=head1 BUGS
299
4e086633 300All complex software has bugs lurking in it, and this module is no
5dac17c3 301exception. If you find a bug please either email me, or add the bug
302to cpan-RT.
303
304=head1 AUTHOR
305
306Stevan Little E<lt>stevan@iinteractive.comE<gt>
307
e2911e34 308Brandon L. Black, E<lt>blblack@gmail.comE<gt>
309
630657d5 310Yuval Kogman, E<lt>nothingmuch@woobling.orgE<gt>
311
78a71ae5 312=head1 CONTRIBUTORS
313
314Ryan D Johnson, E<lt>ryan@innerfence.comE<gt>
315
5dac17c3 316=head1 COPYRIGHT AND LICENSE
317
adbe3e57 318Copyright 2007-2008 by Infinity Interactive, Inc.
5dac17c3 319
320L<http://www.iinteractive.com>
321
322This library is free software; you can redistribute it and/or modify
323it under the same terms as Perl itself.
324
325=cut