From 693fc6c87050ffa59dd5a70274448e54b1078c07 Mon Sep 17 00:00:00 2001 From: Graham Knop Date: Thu, 24 Aug 2023 15:37:54 +0200 Subject: [PATCH] use do rather than require to load a mojo application The return value of require is usually not a reasonable thing to rely on, aside from it being true. The first time requiring a file, it will return the value of the last statement in the file. The second time requiring a file, it will return a simple true value. Mojo was bypassing this problem by deleting the %INC entry for the file, forcing it to always be loaded again. But the new module_true core feature will cause require to always return a simple true value rather than the last statement in the file. This does not apply to do though. Switch to using do to be compatible with code using the new feature. --- lib/Mojo/Server.pm | 6 +++--- t/mojo/daemon.t | 9 +++++++++ t/mojo/lib/myapp-module-true.pl | 15 +++++++++++++++ 3 files changed, 27 insertions(+), 3 deletions(-) create mode 100644 t/mojo/lib/myapp-module-true.pl diff --git a/lib/Mojo/Server.pm b/lib/Mojo/Server.pm index 75c67278ea..dd33db8248 100644 --- a/lib/Mojo/Server.pm +++ b/lib/Mojo/Server.pm @@ -54,9 +54,9 @@ sub load_app { local @ARGS_OVERRIDE = @args; # Try to load application from script into sandbox - delete $INC{$path}; - my $app = eval "package Mojo::Server::Sandbox::@{[md5_sum $path]}; require \$path"; - die qq{Can't load application from file "$path": $@} if $@; + my $app = eval "package Mojo::Server::Sandbox::@{[md5_sum $path]}; do \$path"; + my $err = $app ? undef : $@ || $! || "$path did not return a true value"; + die qq{Can't load application from file "$path": $err} if $err; die qq{File "$path" did not return an application object.\n} unless blessed $app && $app->can('handler'); $self->app($app); }; diff --git a/t/mojo/daemon.t b/t/mojo/daemon.t index 58567febb7..72b60b6b57 100644 --- a/t/mojo/daemon.t +++ b/t/mojo/daemon.t @@ -91,6 +91,15 @@ subtest 'Load broken app' => sub { like $@, qr/^Can't load application/, 'right error'; }; +subtest 'Load app using module_true' => sub { + plan skip_all => 'module_true feature requires perl 5.38' if $] < 5.038; + my $daemon = Mojo::Server::Daemon->new; + my $path = curfile->sibling('lib', '..', 'lib', 'myapp-module-true.pl'); + my $app = eval { $daemon->load_app($path) }; + is $@, '', 'no error loading app'; + is ref $app, 'Mojolicious::Lite', 'right reference'; +}; + subtest 'Load missing application class' => sub { eval { Mojo::Server::Daemon->new->build_app('Mojo::DoesNotExist') }; like $@, qr/^Can't find application class "Mojo::DoesNotExist" in \@INC/, 'right error'; diff --git a/t/mojo/lib/myapp-module-true.pl b/t/mojo/lib/myapp-module-true.pl new file mode 100644 index 0000000000..79c61bbe1e --- /dev/null +++ b/t/mojo/lib/myapp-module-true.pl @@ -0,0 +1,15 @@ +use v5.38; +use Mojolicious::Lite; + +app->config(script => $0); + +app->start; + +=head1 SYNOPSIS + + USAGE: myapp.pl daemon + + test + 123 + +=cut