1 package MooseX::Runnable::Util::ArgParser;
3 use MooseX::Types::Moose qw(HashRef ArrayRef Str Bool);
4 use MooseX::Types::Path::Tiny qw(Path);
5 use Path::Tiny; # exports path()
6 use List::MoreUtils qw(first_index);
10 use namespace::autoclean -also => ['_look_for_dash_something', '_delete_first'];
32 has 'include_paths' => (
34 isa => ArrayRef[Path],
41 isa => HashRef[ArrayRef[Str]],
59 sub _build_class_name {
61 my @args = $self->argv;
64 my $need_dash_dash = 0;
77 next ARG if $arg =~ /^-[A-Za-z]/;
84 return $arg unless $need_dash_dash;
88 confess 'Parse error: expecting ClassName, got EOF';
91 confess 'Parse error: expecting --, got EOF';
94 confess "Parse error: looking for ClassName, but can't find it; perhaps you meant '--help' ?";
97 sub _look_for_dash_something($@) {
98 my ($something, @args) = @_;
101 my $rx = qr/^-$something(.*)$/;
103 for my $arg (@args) {
104 last ARG if $arg eq '--';
105 last ARG unless $arg =~ /^-/;
116 my @args = $self->argv;
117 return [ _look_for_dash_something 'M', @args ];
120 sub _build_include_paths {
122 my @args = $self->argv;
123 return [ map { path($_) } _look_for_dash_something 'I', @args ];
128 my @args = $self->argv;
130 (_look_for_dash_something 'h', @args) ||
131 (_look_for_dash_something '\\?', @args) ||
132 (_look_for_dash_something '-help', @args) ;;
137 my @args = $self->argv;
138 $self->class_name; # causes death when plugin syntax is wrong
142 my $in_plugin = undef;
145 for my $arg (@args) {
146 if(defined $in_plugin){
148 $plugins{$in_plugin} = [@accumulator];
152 elsif($arg =~ /^[+](.+)$/){
153 $plugins{$in_plugin} = [@accumulator];
159 push @accumulator, $arg;
162 else { # once we are $in_plugin, we can never be out again
166 elsif($arg =~ /^[+](.+)$/){
174 confess "Parse error: expecting arguments for plugin $in_plugin, but got EOF. ".
175 "Perhaps you forgot '--' ?";
181 sub _delete_first($\@) {
182 my ($to_delete, $list) = @_;
183 my $idx = first_index { $_ eq $to_delete } @$list;
184 splice @$list, $idx, 1;
188 # this is a dumb way to do it, but i forgot about it until just now,
189 # and don't want to rewrite the whole class ;) ;)
190 sub _build_app_args {
192 my @args = $self->argv;
194 return [] if $self->is_help; # LIES!!11!, but who cares
196 # functional programmers may wish to avert their eyes
197 _delete_first $_, @args for map { "-M$_" } $self->modules;
198 _delete_first $_, @args for map { "-I$_" } $self->include_paths;
200 my %plugins = %{ $self->plugins };
203 for my $p (keys %plugins){
204 my $vl = scalar @{ $plugins{$p} };
205 my $idx = first_index { $_ eq "+$p" } @args;
206 next PLUGIN if $idx == -1; # HORRIBLE API!
208 splice @args, $idx, $vl + 1;
211 if($args[0] eq '--'){
215 if($args[0] eq $self->class_name){
219 confess 'Parse error: Some residual crud was found before the app name: '.
228 my ($self, %opts) = @_;
230 confess 'Parser is help' if $self->is_help;
232 my @perl_flags = @{$opts{perl_flags} || []};
233 my @without_plugins = @{$opts{without_plugins} || []};
238 (map { "-I$_" } @INC),
240 $FindBin::Bin.'/'.$FindBin::Script,
242 push @cmdline, map { "-I$_" } $self->include_paths;
243 push @cmdline, map { "-M$_" } $self->modules;
246 for my $plugin (keys %{$self->plugins}){
247 for my $without (@without_plugins) {
248 next p if $without eq $plugin;
250 push @cmdline, "+$plugin", @{$self->plugins->{$plugin} || []};
253 push @cmdline, $self->class_name;
254 push @cmdline, $self->app_args;
265 MooseX::Runnable::Util::ArgParser - parse @ARGV for mx-run
269 my $parser = MooseX::Runnable::Util::ArgParser->new(
275 $parser->include_paths;