From 9c7b213f58fe533953953e90b5bc77087ca4d45d Mon Sep 17 00:00:00 2001 From: dakkar Date: Fri, 13 Jul 2018 18:52:08 +0100 Subject: we can now parse boolean options --- lib/Getopt/Dakkar/Role/Command.pm | 53 +++++++++++++++++++++++++++++---------- lib/Getopt/Dakkar/Role/Piece.pm | 16 ------------ lib/Getopt/Dakkar/Role/Value.pm | 7 ++++++ 3 files changed, 47 insertions(+), 29 deletions(-) create mode 100644 lib/Getopt/Dakkar/Role/Value.pm (limited to 'lib/Getopt/Dakkar/Role') diff --git a/lib/Getopt/Dakkar/Role/Command.pm b/lib/Getopt/Dakkar/Role/Command.pm index 444a9a4..2a3186b 100644 --- a/lib/Getopt/Dakkar/Role/Command.pm +++ b/lib/Getopt/Dakkar/Role/Command.pm @@ -1,5 +1,7 @@ package Getopt::Dakkar::Role::Command; use Getopt::Dakkar::Style qw(role); +use Getopt::Dakkar::ArgPack; +use Module::Runtime qw(use_module); with 'Getopt::Dakkar::Role::Piece'; # VERSION # ABSTRACT: a command @@ -8,8 +10,26 @@ has options => ( is => 'ro', isa => ArrayRef, default => sub { [] } ); has parameters => ( is => 'ro', isa => ArrayRef, default => sub { [] } ); has subcommands => ( is => 'ro', isa => ArrayRef, default => sub { [] } ); +has class => ( is => 'ro', isa => Str ); +has object => ( is => 'ro', isa => Object ); +has op => ( is => 'ro', isa => Str|CodeRef, default => 'merge_with_argpack' ); + +sub make_stash($self,$argpack) { + if (my $o = $self->object) { return $o } + + return unless $self->class; + + my $class = use_module($self->class); + if (my $from_argpack = $class->can('new_from_argpack')) { + return $class->$from_argpack($argpack); + } + else { + return $class->new(); + } +} + sub parse($self,$args,$stash) { - my $stash = $self->_parse($args,$stash); + $stash = $self->_parse($args,$stash); if (my $op = $self->op) { return $stash->$op(); } @@ -18,17 +38,18 @@ sub parse($self,$args,$stash) { sub _parse($self,$args,$stash) { my $argpack = Getopt::Dakkar::ArgPack->new({getopt=>$self}); + my @parameters = $self->parameters->@*; while ($args->@*) { my $this = $args->[0]; if ($self->_looks_like_option($this) and not $self->_is_terminator($this)) { - if (my $match = $self->_match_option($this)) { + if (my $option = $self->_match_option($this)) { # ->parse will remove $this (or parts of # it, if it's a bundle) and shift its own arguments # out of $args - my $option = $match->parse($args,$stash); - $argpack->options->{$match->name} = $option; + my $option_value = $option->parse($args,$stash); + $argpack->options->{$option_value->name} = $option_value; } else { Getopt::Dakkar::X::BadOption->throw({ @@ -36,15 +57,12 @@ sub _parse($self,$args,$stash) { }); } } - elsif (my $match = $self->_match_subcommand($this)) { + elsif (my $subcommand = $self->_match_subcommand($this)) { shift $args->@*; - $stash //= $self->_make_stash($argpack); - my $op = $self->op; - $stash->$op($argpack); - $match->parse($args,$stash); + $subcommand->parse($args,$stash); } - else { - shift $args->@* if $self->_is_terminator($this); + elsif ($self->_is_terminator($this)) { + shift $args->@*; for my $parameter ($self->parameters->@*) { # ->parse will remove the argument(s) from $args my $argument = $parameter->parse($args,$stash); @@ -58,10 +76,19 @@ sub _parse($self,$args,$stash) { args => $args, }); } - # hmmm. what about 'ls foo -l' ? + } + else { + my $next_parameter = shift @parameters + or last; + my $argument = $next_parameter->parse($args,$stash); + $argpack->arguments->{$argument->name} = $argument; } } - return $stash; + my $new_stash = $self->make_stash($argpack) // $stash; + my $op = $self->op; + $new_stash->$op($argpack); + + return $new_stash; } sub _is_terminator($self,$arg) { return $arg eq q{--} } diff --git a/lib/Getopt/Dakkar/Role/Piece.pm b/lib/Getopt/Dakkar/Role/Piece.pm index 81c89e7..5b7609d 100644 --- a/lib/Getopt/Dakkar/Role/Piece.pm +++ b/lib/Getopt/Dakkar/Role/Piece.pm @@ -12,20 +12,4 @@ has matching_strings => ( ); sub _build_matching_strings($self) { [ $self->name, $self->aliases->@* ] } -has class => ( is => 'ro', isa => ClassName, default => 'Getopt::Dakkar::Stash' ); -has object => ( is => 'ro', isa => Object ); -has op => ( is => 'ro', isa => Str|CodeRef ); - -sub make_stash($self,$argpack) { - if (my $o = $self->object) { return $o } - - my $class = use_module($self->class); - if (my $from_argpack = $class->can('new_from_argpack')) { - return $class->$from_argpack($argpack); - } - else { - return $class->new(); - } -} - requires qw(parse match); diff --git a/lib/Getopt/Dakkar/Role/Value.pm b/lib/Getopt/Dakkar/Role/Value.pm new file mode 100644 index 0000000..ef4d4de --- /dev/null +++ b/lib/Getopt/Dakkar/Role/Value.pm @@ -0,0 +1,7 @@ +package Getopt::Dakkar::Role::Value; +use Getopt::Dakkar::Style qw(role); +# VERSION +# ABSTRACT: a value + +has name => ( is => 'ro', isa => Str, required => 1 ); +has value => ( is => 'ro', required => 1 ); -- cgit v1.2.3