diff --git a/lib/App/Yath/Options/Finder.pm b/lib/App/Yath/Options/Finder.pm index 94e5511ad..c1b0e5704 100644 --- a/lib/App/Yath/Options/Finder.pm +++ b/lib/App/Yath/Options/Finder.pm @@ -26,7 +26,7 @@ option_group {group => 'finder', category => "Finder Options"} => sub { long_examples => [' MyFinder', ' +App::Yath::Finder::MyFinder'], description => 'Specify what Finder subclass to use when searching for files/processing the file list. Use the "+" prefix to specify a fully qualified namespace, otherwise App::Yath::Finder::XXX namespace is assumed.', - normalize => sub { fqmod('App::Yath::Finder', $_[0]) }, + normalize => sub { fqmod($_[0], 'App::Yath::Finder') }, ); option extensions => ( @@ -83,7 +83,7 @@ option_group {group => 'finder', category => "Finder Options"} => sub { long_examples => [' Foo', ' +App::Yath::Plugin::Foo'], mod_adds_options => 1, - normalize => sub { fqmod('App::Yath::Plugin', $_[0]) }, + normalize => sub { fqmod($_[0], 'App::Yath::Plugin') }, ); my $modes = join '|' => sort keys %RERUN_MODES; diff --git a/lib/App/Yath/Options/IPC.pm b/lib/App/Yath/Options/IPC.pm index 60f64b1ef..06e61a605 100644 --- a/lib/App/Yath/Options/IPC.pm +++ b/lib/App/Yath/Options/IPC.pm @@ -56,7 +56,7 @@ option_group {group => 'ipc', category => 'IPC Options'} => sub { long_examples => [' AtomicPipe', ' +Test2::Harness::IPC::Protocol::AtomicPipe', ' UnixSocket', ' IPSocket'], description => 'Specify what IPC Protocol to use. Use the "+" prefix to specify a fully qualified namespace, otherwise Test2::Harness::IPC::Protocol::XXX namespace is assumed.', - normalize => sub { fqmod('Test2::Harness::IPC::Protocol', $_[0]) }, + normalize => sub { fqmod($_[0], 'Test2::Harness::IPC::Protocol') }, ); option address => ( @@ -168,8 +168,10 @@ sub vivify_ipc { ($discovered) = @{$found{p}}; @ipc{qw/address protocol port peer_pid/} = @$discovered; $ipc{address} = clean_path($ipc{address}); - $ipc{protocol} = fqmod('Test2::Harness::IPC::Protocol', $ipc{protocol}); - eval { require(mod2file($ipc{protocol})); 1 } or die "\nFailed to load IPC protocol ($ipc{protocol}) specified by IPC file ($ipc{address}): $@\n"; + + eval { $ipc{protocol} = fqmod($ipc{protocol}, 'Test2::Harness::IPC::Protocol'); 1 } + or die "\nFailed to load IPC protocol ($ipc{protocol}) specified by IPC file ($ipc{address}): $@\n"; + print "Found instance FIFO: $ipc{address}\n"; return {%ipc}; } diff --git a/lib/App/Yath/Options/Renderer.pm b/lib/App/Yath/Options/Renderer.pm index c3ad85ece..c4e45cfda 100644 --- a/lib/App/Yath/Options/Renderer.pm +++ b/lib/App/Yath/Options/Renderer.pm @@ -80,7 +80,7 @@ option_group {group => 'renderer', category => "Renderer Options"} => sub { short_examples => ['MyRenderer', ' +My::Renderer', ' MyRenderer,MyOtherRenderer', ' MyRenderer=opt1,opt2', ' :{ MyRenderer :{ opt1 opt2 }: }:', '=:{ MyRenderer opt1,opt2,... }:'], initialize => sub { {'App::Yath::Renderer::Default' => []} }, - normalize => sub { fqmod('App::Yath::Renderer', $_[0]), ref($_[1]) ? $_[1] : [split(',', $_[1] // '')] }, + normalize => sub { fqmod($_[0], 'App::Yath::Renderer'), ref($_[1]) ? $_[1] : [split(',', $_[1] // '')] }, mod_adds_options => 1, ); diff --git a/lib/App/Yath/Options/Resource.pm b/lib/App/Yath/Options/Resource.pm index b7837bc4c..4e5d6e23c 100644 --- a/lib/App/Yath/Options/Resource.pm +++ b/lib/App/Yath/Options/Resource.pm @@ -20,7 +20,7 @@ option_group {group => 'resource', category => "Resource Options"} => sub { long_examples => [' +My::Resource', ' MyResource,MyOtherResource', ' MyResource=opt1,opt2', ' :{ MyResource :{ opt1 opt2 }: }:', '=:{ MyResource opt1,opt2,... }:'], short_examples => ['MyResource', ' +My::Resource', ' MyResource,MyOtherResource', ' MyResource=opt1,opt2', ' :{ MyResource :{ opt1 opt2 }: }:', '=:{ MyResource opt1,opt2,... }:'], - normalize => sub { fqmod('App::Yath::Resource', $_[0]), ref($_[1]) ? $_[1] : [split(',', $_[1] // '')] }, + normalize => sub { fqmod($_[0], 'App::Yath::Resource'), ref($_[1]) ? $_[1] : [split(',', $_[1] // '')] }, mod_adds_options => 1, ); diff --git a/lib/App/Yath/Options/Runner.pm b/lib/App/Yath/Options/Runner.pm index d3b07f589..fcb7149ce 100644 --- a/lib/App/Yath/Options/Runner.pm +++ b/lib/App/Yath/Options/Runner.pm @@ -46,7 +46,7 @@ option_group {group => 'runner', category => "Runner Options"} => sub { long_examples => [' MyRunner', ' +Test2::Harness::Runner::MyRunner'], description => 'Specify what Runner subclass to use. Use the "+" prefix to specify a fully qualified namespace, otherwise Test2::Harness::Runner::XXX namespace is assumed.', - normalize => sub { fqmod('Test2::Harness::Runner', $_[0]) }, + normalize => sub { fqmod($_[0], 'Test2::Harness::Runner') }, ); option dump_depmap => ( @@ -59,7 +59,7 @@ option_group {group => 'runner', category => "Runner Options"} => sub { type => 'Auto', alt => ['reload'], autofill => 'Test2::Harness::Reloader', - normalize => sub { fqmod('Test2::Harness::Reloader', $_[0]) }, + normalize => sub { fqmod($_[0], 'Test2::Harness::Reloader') }, description => "Use a reloader (default Test2::Harness::Reloader) to reload modules in place. This is discouraged as there are too many gotchas", ); diff --git a/lib/App/Yath/Options/Scheduler.pm b/lib/App/Yath/Options/Scheduler.pm index 6ac922f6f..ba97da4ad 100644 --- a/lib/App/Yath/Options/Scheduler.pm +++ b/lib/App/Yath/Options/Scheduler.pm @@ -2,6 +2,8 @@ package App::Yath::Options::Scheduler; use strict; use warnings; +use Test2::Harness::Util qw/fqmod/; + our $VERSION = '2.000000'; use Getopt::Yath; @@ -20,7 +22,7 @@ option_group {group => 'scheduler', category => 'Scheduler Options'} => sub { long_examples => [' MyScheduler', ' +Test2::Harness::MyScheduler'], description => 'Specify what Scheduler subclass to use. Use the "+" prefix to specify a fully qualified namespace, otherwise Test2::Harness::Scheduler::XXX namespace is assumed.', - normalize => sub { fqmod('Test2::Harness::Scheduler', $_[0]) }, + normalize => sub { fqmod($_[0], 'Test2::Harness::Scheduler') }, ); option shared_jobs_config => ( diff --git a/lib/App/Yath/Options/Yath.pm b/lib/App/Yath/Options/Yath.pm index fee999e65..bd92a1c10 100644 --- a/lib/App/Yath/Options/Yath.pm +++ b/lib/App/Yath/Options/Yath.pm @@ -115,9 +115,7 @@ dev-lib '$_' added to \@INC late, it is possible some yath libraries were alread normalize => sub { my ($class, $args) = @_; - $class = fqmod('App::Yath::Plugin', $class); - my $file = mod2file($class); - require $file; + $class = fqmod($class, 'App::Yath::Plugin'); $args = $args ? [split ',', $args] : []; diff --git a/lib/Getopt/Yath/Instance.pm b/lib/Getopt/Yath/Instance.pm index 3be58e41d..2a6dbfb14 100644 --- a/lib/Getopt/Yath/Instance.pm +++ b/lib/Getopt/Yath/Instance.pm @@ -6,7 +6,7 @@ our $VERSION = '2.000000'; use Carp qw/croak/; -use Test2::Harness::Util qw/mod2file fqmod/; +use Test2::Harness::Util qw/mod2file/; use Getopt::Yath::Option; use Getopt::Yath::Settings; diff --git a/lib/Getopt/Yath/Option.pm b/lib/Getopt/Yath/Option.pm index 6f1982caf..e49c5b6ea 100644 --- a/lib/Getopt/Yath/Option.pm +++ b/lib/Getopt/Yath/Option.pm @@ -74,8 +74,7 @@ sub create { my $type = delete $params{type} or croak "No 'type' specified"; - my $new_class = fqmod(__PACKAGE__, $type); - require(mod2file($new_class)); + my $new_class = fqmod($type, __PACKAGE__); return $new_class->new(%params); } diff --git a/lib/Test2/Harness/Util.pm b/lib/Test2/Harness/Util.pm index a19f767d1..73ba76188 100644 --- a/lib/Test2/Harness/Util.pm +++ b/lib/Test2/Harness/Util.pm @@ -123,9 +123,35 @@ sub hub_truth { } sub fqmod { - my ($prefix, $input) = @_; - return $1 if $input =~ m/^\+(.*)$/; - return "$prefix\::$input"; + my ($input, $prefixes, %options) = @_; + + croak "At least 1 prefix is required" unless $prefixes; + + $prefixes = [$prefixes] unless ref($prefixes) eq 'ARRAY'; + + croak "At least 1 prefix is required" unless @$prefixes; + croak "Cannot use no_require when providing multiple prefixes" if $options{no_require} && @$prefixes > 1; + + if ($input =~ m/^\+(.*)$/) { + my $mod = $1; + return $mod if $options{no_require}; + return $mod if eval { require(mod2file($mod)); 1 }; + confess($@); + } + + for my $pre (@$prefixes) { + my $mod = "$pre\::$input"; + + if ($options{no_require}) { + return $mod; + } + else { + return $mod if eval { require(mod2file($mod)); 1 }; + confess($@) unless @$prefixes > 1; + } + } + + croak "Could not find a module with the given input in the given prefixes"; } sub file2mod {