changelog and version bump
[gitmo/MooseX-Getopt.git] / lib / MooseX / Getopt.pm
index 4e37238..1f40e00 100644 (file)
@@ -2,17 +2,18 @@
 package MooseX::Getopt;
 use Moose::Role;
 
-use Getopt::Long::Descriptive ();
-
 use MooseX::Getopt::OptionTypeMap;
 use MooseX::Getopt::Meta::Attribute;
 use MooseX::Getopt::Meta::Attribute::NoGetopt;
 
-our $VERSION   = '0.08';
+use Getopt::Long (); # GLD uses it anyway, doesn't hurt
+use constant HAVE_GLD => not not eval { require Getopt::Long::Descriptive };
+
+our $VERSION   = '0.09';
 our $AUTHORITY = 'cpan:STEVAN';
 
-has ARGV       => (is => 'rw', isa => 'ArrayRef');
-has extra_argv => (is => 'rw', isa => 'ArrayRef');
+has ARGV       => (is => 'rw', isa => 'ArrayRef', documentation => "hidden");
+has extra_argv => (is => 'rw', isa => 'ArrayRef', documentation => "hidden");
 
 sub new_with_options {
     my ($class, @params) = @_;
@@ -42,23 +43,11 @@ sub new_with_options {
 }
 
 sub _parse_argv {
-    my ( $class, @args ) = @_;
-
-    my ( $params, $argv_copy, $argv_mangled ) = $class->_call_getopt(@args);
-
-    return (
-        argv_copy => $argv_copy,
-        argv      => $argv_mangled,
-        params    => $params,
-    );
-}
-
-sub _call_getopt {
     my ( $class, %params ) = @_;
 
     local @ARGV = @{ $params{argv} || \@ARGV };
 
-    my ( $opt_spec, $name_to_init_arg ) = $class->_gld_spec(%params);
+    my ( $opt_spec, $name_to_init_arg ) = ( HAVE_GLD ? $class->_gld_spec(%params) : $class->_traditional_spec(%params) );
 
     # Get a clean copy of the original @ARGV
     my $argv_copy = [ @ARGV ];
@@ -67,7 +56,14 @@ sub _call_getopt {
 
     my ( $parsed_options, $usage ) = eval {
         local $SIG{__WARN__} = sub { push @err, @_ };
-        Getopt::Long::Descriptive::describe_options("usage: %c %o", @$opt_spec)
+
+        if ( HAVE_GLD ) {
+            return Getopt::Long::Descriptive::describe_options($class->_usage_format(%params), @$opt_spec);
+        } else {
+            my %options;
+            Getopt::Long::GetOptions(\%options, @$opt_spec);
+            return ( \%options, undef );
+        }
     };
 
     die join "", grep { defined } @err, $@ if @err or $@;
@@ -81,7 +77,29 @@ sub _call_getopt {
         } keys %$parsed_options,   
     );
 
-    return ( \%constructor_args, $argv_copy, $argv_mangled );
+    return (
+        params    => \%constructor_args,
+        argv_copy => $argv_copy,
+        argv      => $argv_mangled,
+        ( defined($usage) ? ( usage => $usage ) : () ),
+    );
+}
+
+sub _usage_format {
+    return "usage: %c %o";
+}
+
+sub _traditional_spec {
+    my ( $class, %params ) = @_;
+    
+    my ( @options, %name_to_init_arg, %options );
+
+    foreach my $opt ( @{ $params{options} } ) {
+        push @options, $opt->{opt_string};
+        $name_to_init_arg{ $opt->{name} } = $opt->{init_arg};
+    }
+
+    return ( \@options, \%name_to_init_arg );
 }
 
 sub _gld_spec {
@@ -344,6 +362,9 @@ and then return a newly constructed object.
 If L<Getopt::Long/GetOptions> fails (due to invalid arguments),
 C<new_with_options> will throw an exception.
 
+If you have L<Getopt::Long::Descriptive> a the C<usage> param is also passed to
+C<new>.
+
 =item B<ARGV>
 
 This accessor contains a reference to a copy of the C<@ARGV> array