Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package perl-Mojolicious for 
openSUSE:Factory checked in at 2023-09-12 21:03:53
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/perl-Mojolicious (Old)
 and      /work/SRC/openSUSE:Factory/.perl-Mojolicious.new.1766 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "perl-Mojolicious"

Tue Sep 12 21:03:53 2023 rev:173 rq:1110568 version:9.340.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/perl-Mojolicious/perl-Mojolicious.changes        
2023-07-12 17:27:05.694404692 +0200
+++ 
/work/SRC/openSUSE:Factory/.perl-Mojolicious.new.1766/perl-Mojolicious.changes  
    2023-09-12 21:05:07.268964781 +0200
@@ -1,0 +2,20 @@
+Tue Sep 12 03:08:53 UTC 2023 - Tina Müller <timueller+p...@suse.de>
+
+- updated to 9.34
+   see /usr/share/doc/packages/perl-Mojolicious/Changes
+
+  9.34  2023-09-11
+    - Added support for serving static files with a prefix.
+    - Deprecated Mojo::File::spurt in favor of Mojo::File::spew.
+    - Added prefix attribute to Mojolicious::Static.
+    - Added url_for_file method to Mojolicious::Controller.
+    - Added file_path method to Mojolicious::Static.
+    - Added spew method to Mojo::File. (genio)
+    - Added encoding option to slurp method in Mojo::File. (genio)
+    - Added url_for_asset and url_for_file helpers to 
Mojolicious::Plugins::DefaultHelpers.
+    - Added favicon helper to Mojolicious::Plugin::TagHelpers.
+    - Fixed support for module_true Perl feature in Mojolicious apps. (haarg)
+    - Fixed a bug in Mojo::Promise where map could hang on false values after 
concurrency limit. (ilmari)
+    - Fixed built-in templates to not require an internet connection. 
(hernan604)
+
+-------------------------------------------------------------------

Old:
----
  Mojolicious-9.33.tar.gz

New:
----
  Mojolicious-9.34.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ perl-Mojolicious.spec ++++++
--- /var/tmp/diff_new_pack.dalFmh/_old  2023-09-12 21:05:08.389004733 +0200
+++ /var/tmp/diff_new_pack.dalFmh/_new  2023-09-12 21:05:08.389004733 +0200
@@ -18,12 +18,13 @@
 
 %define cpan_name Mojolicious
 Name:           perl-Mojolicious
-Version:        9.33
+Version:        9.340.0
 Release:        0
+%define cpan_version 9.34
 License:        Artistic-2.0
 Summary:        Real-time web framework
 URL:            https://metacpan.org/release/%{cpan_name}
-Source0:        
https://cpan.metacpan.org/authors/id/S/SR/SRI/%{cpan_name}-%{version}.tar.gz
+Source0:        
https://cpan.metacpan.org/authors/id/S/SR/SRI/%{cpan_name}-%{cpan_version}.tar.gz
 Source1:        cpanspec.yml
 BuildArch:      noarch
 BuildRequires:  perl
@@ -32,6 +33,120 @@
 BuildRequires:  perl(Sub::Util) >= 1.41
 Requires:       perl(IO::Socket::IP) >= 0.37
 Requires:       perl(Sub::Util) >= 1.41
+Provides:       perl(Mojo)
+Provides:       perl(Mojo::Asset)
+Provides:       perl(Mojo::Asset::File)
+Provides:       perl(Mojo::Asset::Memory)
+Provides:       perl(Mojo::Base)
+Provides:       perl(Mojo::ByteStream)
+Provides:       perl(Mojo::Cache)
+Provides:       perl(Mojo::Collection)
+Provides:       perl(Mojo::Content)
+Provides:       perl(Mojo::Content::MultiPart)
+Provides:       perl(Mojo::Content::Single)
+Provides:       perl(Mojo::Cookie)
+Provides:       perl(Mojo::Cookie::Request)
+Provides:       perl(Mojo::Cookie::Response)
+Provides:       perl(Mojo::DOM)
+Provides:       perl(Mojo::DOM::CSS)
+Provides:       perl(Mojo::DOM::HTML)
+Provides:       perl(Mojo::Date)
+Provides:       perl(Mojo::DynamicMethods)
+Provides:       perl(Mojo::EventEmitter)
+Provides:       perl(Mojo::Exception)
+Provides:       perl(Mojo::File)
+Provides:       perl(Mojo::Headers)
+Provides:       perl(Mojo::HelloWorld)
+Provides:       perl(Mojo::Home)
+Provides:       perl(Mojo::IOLoop)
+Provides:       perl(Mojo::IOLoop::Client)
+Provides:       perl(Mojo::IOLoop::Server)
+Provides:       perl(Mojo::IOLoop::Stream)
+Provides:       perl(Mojo::IOLoop::Subprocess)
+Provides:       perl(Mojo::IOLoop::TLS)
+Provides:       perl(Mojo::JSON)
+Provides:       perl(Mojo::JSON::Pointer)
+Provides:       perl(Mojo::Loader)
+Provides:       perl(Mojo::Log)
+Provides:       perl(Mojo::Log::_Capture)
+Provides:       perl(Mojo::Message)
+Provides:       perl(Mojo::Message::Request)
+Provides:       perl(Mojo::Message::Response)
+Provides:       perl(Mojo::Parameters)
+Provides:       perl(Mojo::Path)
+Provides:       perl(Mojo::Promise)
+Provides:       perl(Mojo::Reactor)
+Provides:       perl(Mojo::Reactor::EV)
+Provides:       perl(Mojo::Reactor::Poll)
+Provides:       perl(Mojo::Server)
+Provides:       perl(Mojo::Server::CGI)
+Provides:       perl(Mojo::Server::Daemon)
+Provides:       perl(Mojo::Server::Hypnotoad)
+Provides:       perl(Mojo::Server::Morbo)
+Provides:       perl(Mojo::Server::Morbo::Backend)
+Provides:       perl(Mojo::Server::Morbo::Backend::Poll)
+Provides:       perl(Mojo::Server::PSGI)
+Provides:       perl(Mojo::Server::PSGI::_IO)
+Provides:       perl(Mojo::Server::Prefork)
+Provides:       perl(Mojo::Template)
+Provides:       perl(Mojo::Transaction)
+Provides:       perl(Mojo::Transaction::HTTP)
+Provides:       perl(Mojo::Transaction::WebSocket)
+Provides:       perl(Mojo::URL)
+Provides:       perl(Mojo::Upload)
+Provides:       perl(Mojo::UserAgent)
+Provides:       perl(Mojo::UserAgent::CookieJar)
+Provides:       perl(Mojo::UserAgent::Proxy)
+Provides:       perl(Mojo::UserAgent::Server)
+Provides:       perl(Mojo::UserAgent::Transactor)
+Provides:       perl(Mojo::Util)
+Provides:       perl(Mojo::Util::_Guard)
+Provides:       perl(Mojo::WebSocket)
+Provides:       perl(Mojolicious) = 9.340.0
+Provides:       perl(Mojolicious::Command)
+Provides:       perl(Mojolicious::Command::Author::cpanify)
+Provides:       perl(Mojolicious::Command::Author::generate)
+Provides:       perl(Mojolicious::Command::Author::generate::app)
+Provides:       perl(Mojolicious::Command::Author::generate::dockerfile)
+Provides:       perl(Mojolicious::Command::Author::generate::lite_app)
+Provides:       perl(Mojolicious::Command::Author::generate::makefile)
+Provides:       perl(Mojolicious::Command::Author::generate::plugin)
+Provides:       perl(Mojolicious::Command::Author::inflate)
+Provides:       perl(Mojolicious::Command::cgi)
+Provides:       perl(Mojolicious::Command::daemon)
+Provides:       perl(Mojolicious::Command::eval)
+Provides:       perl(Mojolicious::Command::get)
+Provides:       perl(Mojolicious::Command::prefork)
+Provides:       perl(Mojolicious::Command::psgi)
+Provides:       perl(Mojolicious::Command::routes)
+Provides:       perl(Mojolicious::Command::version)
+Provides:       perl(Mojolicious::Commands)
+Provides:       perl(Mojolicious::Controller)
+Provides:       perl(Mojolicious::Lite)
+Provides:       perl(Mojolicious::Plugin)
+Provides:       perl(Mojolicious::Plugin::Config)
+Provides:       perl(Mojolicious::Plugin::DefaultHelpers)
+Provides:       perl(Mojolicious::Plugin::EPLRenderer)
+Provides:       perl(Mojolicious::Plugin::EPRenderer)
+Provides:       perl(Mojolicious::Plugin::HeaderCondition)
+Provides:       perl(Mojolicious::Plugin::JSONConfig)
+Provides:       perl(Mojolicious::Plugin::Mount)
+Provides:       perl(Mojolicious::Plugin::NotYAMLConfig)
+Provides:       perl(Mojolicious::Plugin::TagHelpers)
+Provides:       perl(Mojolicious::Plugins)
+Provides:       perl(Mojolicious::Renderer)
+Provides:       perl(Mojolicious::Routes)
+Provides:       perl(Mojolicious::Routes::Match)
+Provides:       perl(Mojolicious::Routes::Pattern)
+Provides:       perl(Mojolicious::Routes::Route)
+Provides:       perl(Mojolicious::Sessions)
+Provides:       perl(Mojolicious::Static)
+Provides:       perl(Mojolicious::Types)
+Provides:       perl(Mojolicious::Validator)
+Provides:       perl(Mojolicious::Validator::Validation)
+Provides:       perl(Test::Mojo)
+Provides:       perl(ojo)
+%define         __perllib_provides /bin/true
 %{perl_requires}
 
 %description
@@ -44,7 +159,7 @@
 Take a look at our excellent documentation in Mojolicious::Guides!
 
 %prep
-%autosetup  -n %{cpan_name}-%{version}
+%autosetup  -n %{cpan_name}-%{cpan_version}
 
 find . -type f ! -path "*/t/*" ! -name "*.pl" ! -path "*/bin/*" ! -path 
"*/script/*" ! -path "*/scripts/*" ! -name "configure" -print0 | xargs -0 chmod 
644
 

++++++ Mojolicious-9.33.tar.gz -> Mojolicious-9.34.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Mojolicious-9.33/Changes new/Mojolicious-9.34/Changes
--- old/Mojolicious-9.33/Changes        2023-06-14 19:41:01.000000000 +0200
+++ new/Mojolicious-9.34/Changes        2023-09-11 20:33:12.000000000 +0200
@@ -1,4 +1,18 @@
 
+9.34  2023-09-11
+  - Added support for serving static files with a prefix.
+  - Deprecated Mojo::File::spurt in favor of Mojo::File::spew.
+  - Added prefix attribute to Mojolicious::Static.
+  - Added url_for_file method to Mojolicious::Controller.
+  - Added file_path method to Mojolicious::Static.
+  - Added spew method to Mojo::File. (genio)
+  - Added encoding option to slurp method in Mojo::File. (genio)
+  - Added url_for_asset and url_for_file helpers to 
Mojolicious::Plugins::DefaultHelpers.
+  - Added favicon helper to Mojolicious::Plugin::TagHelpers.
+  - Fixed support for module_true Perl feature in Mojolicious apps. (haarg)
+  - Fixed a bug in Mojo::Promise where map could hang on false values after 
concurrency limit. (ilmari)
+  - Fixed built-in templates to not require an internet connection. (hernan604)
+
 9.33  2023-06-14
   - Improved log messages to refer to the FAQ when they have an entry.
   - Fixed a bug where the prefork server could sometimes send redundant QUIT 
signals, which could result in unintended
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Mojolicious-9.33/MANIFEST 
new/Mojolicious-9.34/MANIFEST
--- old/Mojolicious-9.33/MANIFEST       2023-06-14 21:25:30.000000000 +0200
+++ new/Mojolicious-9.34/MANIFEST       2023-09-11 20:34:08.000000000 +0200
@@ -161,6 +161,7 @@
 LICENSE
 Makefile.PL
 MANIFEST                       This list of files
+MANIFEST.bak
 MANIFEST.SKIP
 README.md
 script/hypnotoad
@@ -221,6 +222,7 @@
 t/mojo/lib/Mojo/LoaderTestException/A.pm
 t/mojo/lib/Mojo/Server/Morbo/Backend/TestBackend.pm
 t/mojo/lib/Mojo/TestConnectProxy.pm
+t/mojo/lib/myapp-module-true.pl
 t/mojo/lib/myapp.pl
 t/mojo/loader.t
 t/mojo/log.t
@@ -344,6 +346,7 @@
 t/mojolicious/signatures_lite_app.t
 t/mojolicious/single_file_test_app.conf
 t/mojolicious/static_lite_app.t
+t/mojolicious/static_prefix_lite_app.t
 t/mojolicious/tag_helper_lite_app.t
 t/mojolicious/templates/23.html.epl
 t/mojolicious/templates/dies_too.html.ep
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Mojolicious-9.33/MANIFEST.bak 
new/Mojolicious-9.34/MANIFEST.bak
--- old/Mojolicious-9.33/MANIFEST.bak   1970-01-01 01:00:00.000000000 +0100
+++ new/Mojolicious-9.34/MANIFEST.bak   2023-06-14 21:25:28.000000000 +0200
@@ -0,0 +1,384 @@
+.perltidyrc
+Changes
+examples/chat.pl
+examples/connect-proxy.pl
+examples/entities.pl
+examples/fast.pl
+examples/hello-template.pl
+examples/hello.pl
+examples/login/lib/LoginApp.pm
+examples/login/lib/LoginApp/Controller/Login.pm
+examples/login/lib/LoginApp/Model/Users.pm
+examples/login/script/login_app
+examples/login/t/login.t
+examples/login/templates/layouts/default.html.ep
+examples/login/templates/login/index.html.ep
+examples/login/templates/login/protected.html.ep
+examples/microhttpd.pl
+examples/proxy.pl
+examples/responses.pl
+lib/Mojo.pm
+lib/Mojo/Asset.pm
+lib/Mojo/Asset/File.pm
+lib/Mojo/Asset/Memory.pm
+lib/Mojo/Base.pm
+lib/Mojo/ByteStream.pm
+lib/Mojo/Cache.pm
+lib/Mojo/Collection.pm
+lib/Mojo/Content.pm
+lib/Mojo/Content/MultiPart.pm
+lib/Mojo/Content/Single.pm
+lib/Mojo/Cookie.pm
+lib/Mojo/Cookie/Request.pm
+lib/Mojo/Cookie/Response.pm
+lib/Mojo/Date.pm
+lib/Mojo/DOM.pm
+lib/Mojo/DOM/CSS.pm
+lib/Mojo/DOM/HTML.pm
+lib/Mojo/DynamicMethods.pm
+lib/Mojo/EventEmitter.pm
+lib/Mojo/Exception.pm
+lib/Mojo/File.pm
+lib/Mojo/Headers.pm
+lib/Mojo/HelloWorld.pm
+lib/Mojo/Home.pm
+lib/Mojo/IOLoop.pm
+lib/Mojo/IOLoop/Client.pm
+lib/Mojo/IOLoop/resources/server.crt
+lib/Mojo/IOLoop/resources/server.key
+lib/Mojo/IOLoop/Server.pm
+lib/Mojo/IOLoop/Stream.pm
+lib/Mojo/IOLoop/Subprocess.pm
+lib/Mojo/IOLoop/TLS.pm
+lib/Mojo/JSON.pm
+lib/Mojo/JSON/Pointer.pm
+lib/Mojo/Loader.pm
+lib/Mojo/Log.pm
+lib/Mojo/Message.pm
+lib/Mojo/Message/Request.pm
+lib/Mojo/Message/Response.pm
+lib/Mojo/Parameters.pm
+lib/Mojo/Path.pm
+lib/Mojo/Promise.pm
+lib/Mojo/Reactor.pm
+lib/Mojo/Reactor/EV.pm
+lib/Mojo/Reactor/Poll.pm
+lib/Mojo/resources/html_entities.txt
+lib/Mojo/Server.pm
+lib/Mojo/Server/CGI.pm
+lib/Mojo/Server/Daemon.pm
+lib/Mojo/Server/Hypnotoad.pm
+lib/Mojo/Server/Morbo.pm
+lib/Mojo/Server/Morbo/Backend.pm
+lib/Mojo/Server/Morbo/Backend/Poll.pm
+lib/Mojo/Server/Prefork.pm
+lib/Mojo/Server/PSGI.pm
+lib/Mojo/Template.pm
+lib/Mojo/Transaction.pm
+lib/Mojo/Transaction/HTTP.pm
+lib/Mojo/Transaction/WebSocket.pm
+lib/Mojo/Upload.pm
+lib/Mojo/URL.pm
+lib/Mojo/UserAgent.pm
+lib/Mojo/UserAgent/CookieJar.pm
+lib/Mojo/UserAgent/Proxy.pm
+lib/Mojo/UserAgent/Server.pm
+lib/Mojo/UserAgent/Transactor.pm
+lib/Mojo/Util.pm
+lib/Mojo/WebSocket.pm
+lib/Mojolicious.pm
+lib/Mojolicious/Command.pm
+lib/Mojolicious/Command/Author/cpanify.pm
+lib/Mojolicious/Command/Author/generate.pm
+lib/Mojolicious/Command/Author/generate/app.pm
+lib/Mojolicious/Command/Author/generate/dockerfile.pm
+lib/Mojolicious/Command/Author/generate/lite_app.pm
+lib/Mojolicious/Command/Author/generate/makefile.pm
+lib/Mojolicious/Command/Author/generate/plugin.pm
+lib/Mojolicious/Command/Author/inflate.pm
+lib/Mojolicious/Command/cgi.pm
+lib/Mojolicious/Command/daemon.pm
+lib/Mojolicious/Command/eval.pm
+lib/Mojolicious/Command/get.pm
+lib/Mojolicious/Command/prefork.pm
+lib/Mojolicious/Command/psgi.pm
+lib/Mojolicious/Command/routes.pm
+lib/Mojolicious/Command/version.pm
+lib/Mojolicious/Commands.pm
+lib/Mojolicious/Controller.pm
+lib/Mojolicious/Guides.pod
+lib/Mojolicious/Guides/Contributing.pod
+lib/Mojolicious/Guides/Cookbook.pod
+lib/Mojolicious/Guides/FAQ.pod
+lib/Mojolicious/Guides/Growing.pod
+lib/Mojolicious/Guides/Rendering.pod
+lib/Mojolicious/Guides/Routing.pod
+lib/Mojolicious/Guides/Testing.pod
+lib/Mojolicious/Guides/Tutorial.pod
+lib/Mojolicious/Lite.pm
+lib/Mojolicious/Plugin.pm
+lib/Mojolicious/Plugin/Config.pm
+lib/Mojolicious/Plugin/DefaultHelpers.pm
+lib/Mojolicious/Plugin/EPLRenderer.pm
+lib/Mojolicious/Plugin/EPRenderer.pm
+lib/Mojolicious/Plugin/HeaderCondition.pm
+lib/Mojolicious/Plugin/JSONConfig.pm
+lib/Mojolicious/Plugin/Mount.pm
+lib/Mojolicious/Plugin/NotYAMLConfig.pm
+lib/Mojolicious/Plugin/TagHelpers.pm
+lib/Mojolicious/Plugins.pm
+lib/Mojolicious/Renderer.pm
+lib/Mojolicious/resources/public/favicon.ico
+lib/Mojolicious/resources/public/mojo/bootstrap/bootstrap.css
+lib/Mojolicious/resources/public/mojo/bootstrap/bootstrap.js
+lib/Mojolicious/resources/public/mojo/failraptor.png
+lib/Mojolicious/resources/public/mojo/highlight.js/highlight-mojo-dark.css
+lib/Mojolicious/resources/public/mojo/highlight.js/highlight.min.js
+lib/Mojolicious/resources/public/mojo/highlight.js/mojolicious.min.js
+lib/Mojolicious/resources/public/mojo/jquery/jquery.js
+lib/Mojolicious/resources/public/mojo/logo-white-2x.png
+lib/Mojolicious/resources/public/mojo/logo-white.png
+lib/Mojolicious/resources/public/mojo/logo.png
+lib/Mojolicious/resources/public/mojo/mojo.css
+lib/Mojolicious/resources/public/mojo/noraptor.png
+lib/Mojolicious/resources/public/mojo/notfound.png
+lib/Mojolicious/resources/public/mojo/pinstripe-dark.png
+lib/Mojolicious/resources/public/mojo/pinstripe-light.png
+lib/Mojolicious/resources/templates/mojo/debug.html.ep
+lib/Mojolicious/resources/templates/mojo/exception.html.ep
+lib/Mojolicious/resources/templates/mojo/not_found.html.ep
+lib/Mojolicious/Routes.pm
+lib/Mojolicious/Routes/Match.pm
+lib/Mojolicious/Routes/Pattern.pm
+lib/Mojolicious/Routes/Route.pm
+lib/Mojolicious/Sessions.pm
+lib/Mojolicious/Static.pm
+lib/Mojolicious/Types.pm
+lib/Mojolicious/Validator.pm
+lib/Mojolicious/Validator/Validation.pm
+lib/ojo.pm
+lib/Test/Mojo.pm
+LICENSE
+Makefile.PL
+MANIFEST                       This list of files
+MANIFEST.SKIP
+README.md
+script/hypnotoad
+script/mojo
+script/morbo
+t/mojo/asset.t
+t/mojo/base.t
+t/mojo/bytestream.t
+t/mojo/cache.t
+t/mojo/certs/bad.crt
+t/mojo/certs/bad.key
+t/mojo/certs/ca.crt
+t/mojo/certs/ca.key
+t/mojo/certs/client.crt
+t/mojo/certs/client.key
+t/mojo/certs/domain.crt
+t/mojo/certs/domain.key
+t/mojo/certs/server.crt
+t/mojo/certs/server.key
+t/mojo/cgi.t
+t/mojo/collection.t
+t/mojo/content.t
+t/mojo/cookie.t
+t/mojo/cookiejar.t
+t/mojo/daemon.t
+t/mojo/daemon_ipv6_tls.t
+t/mojo/date.t
+t/mojo/dom.t
+t/mojo/dynamic_methods.t
+t/mojo/eventemitter.t
+t/mojo/exception.t
+t/mojo/exception/non_utf8.txt
+t/mojo/exception/utf8.txt
+t/mojo/file.t
+t/mojo/headers.t
+t/mojo/home.t
+t/mojo/hypnotoad.t
+t/mojo/ioloop.t
+t/mojo/ioloop_ipv6.t
+t/mojo/ioloop_tls.t
+t/mojo/json.t
+t/mojo/json_pointer.t
+t/mojo/json_xs.t
+t/mojo/lib/Mojo/.hidden.txt
+t/mojo/lib/Mojo/.test/hidden.txt
+t/mojo/lib/Mojo/BaseTest/Base1.pm
+t/mojo/lib/Mojo/BaseTest/Base2.pm
+t/mojo/lib/Mojo/BaseTest/Base3.pm
+t/mojo/lib/Mojo/DeprecationTest.pm
+t/mojo/lib/Mojo/LoaderException.pm
+t/mojo/lib/Mojo/LoaderException2.pm
+t/mojo/lib/Mojo/LoaderTest/A.pm
+t/mojo/lib/Mojo/LoaderTest/B.pm
+t/mojo/lib/Mojo/LoaderTest/C.pm
+t/mojo/lib/Mojo/LoaderTest/D.txt
+t/mojo/lib/Mojo/LoaderTest/E/F.pm
+t/mojo/lib/Mojo/LoaderTest/E/G.txt
+t/mojo/lib/Mojo/LoaderTestException/A.pm
+t/mojo/lib/Mojo/Server/Morbo/Backend/TestBackend.pm
+t/mojo/lib/Mojo/TestConnectProxy.pm
+t/mojo/lib/myapp.pl
+t/mojo/loader.t
+t/mojo/log.t
+t/mojo/morbo.t
+t/mojo/parameters.t
+t/mojo/path.t
+t/mojo/prefork.t
+t/mojo/promise.t
+t/mojo/promise_async_await.t
+t/mojo/proxy.t
+t/mojo/psgi.t
+t/mojo/reactor_detect.t
+t/mojo/reactor_ev.t
+t/mojo/reactor_poll.t
+t/mojo/request.t
+t/mojo/request_cgi.t
+t/mojo/response.t
+t/mojo/roles.t
+t/mojo/signatures.t
+t/mojo/subprocess.t
+t/mojo/subprocess_ev.t
+t/mojo/template.t
+t/mojo/templates/exception.mt
+t/mojo/templates/test.mt
+t/mojo/templates/utf8_exception.mt
+t/mojo/tls.t
+t/mojo/transactor.t
+t/mojo/url.t
+t/mojo/user_agent.t
+t/mojo/user_agent_online.t
+t/mojo/user_agent_socks.t
+t/mojo/user_agent_tls.t
+t/mojo/user_agent_unix.t
+t/mojo/util.t
+t/mojo/websocket.t
+t/mojo/websocket_frames.t
+t/mojo/websocket_proxy.t
+t/mojo/websocket_proxy_tls.t
+t/mojolicious/app.t
+t/mojolicious/charset_lite_app.t
+t/mojolicious/command.t
+t/mojolicious/commands.t
+t/mojolicious/dispatch.t
+t/mojolicious/dispatcher_lite_app.t
+t/mojolicious/embedded_app.t
+t/mojolicious/embedded_lite_app.json
+t/mojolicious/embedded_lite_app.t
+t/mojolicious/exception_lite_app.t
+t/mojolicious/external/lib/MyApp.pm
+t/mojolicious/external/my_app.conf
+t/mojolicious/external/my_app.testing.conf
+t/mojolicious/external/myapp.conf
+t/mojolicious/external/myapp.pl
+t/mojolicious/external/myapp.testing.conf
+t/mojolicious/external/myapp2.pl
+t/mojolicious/external/public/index.html
+t/mojolicious/external/script/my_app
+t/mojolicious/external/templates/index.html.ep
+t/mojolicious/external_app.t
+t/mojolicious/external_lite_app.t
+t/mojolicious/group_lite_app.t
+t/mojolicious/json_config_lite_app.json
+t/mojolicious/json_config_lite_app.t
+t/mojolicious/json_config_lite_app_abs.development.json
+t/mojolicious/json_config_lite_app_abs.json
+t/mojolicious/json_config_mode_lite_app.json
+t/mojolicious/json_config_mode_lite_app.t
+t/mojolicious/json_config_mode_lite_app.testing.json
+t/mojolicious/layouted_lite_app.t
+t/mojolicious/lib/AroundPlugin.pm
+t/mojolicious/lib/EmbeddedTestApp.pm
+t/mojolicious/lib/MojoliciousConfigTest.pm
+t/mojolicious/lib/MojoliciousTest.pm
+t/mojolicious/lib/MojoliciousTest/Baz.pm
+t/mojolicious/lib/MojoliciousTest/Command/_test2_command.pm
+t/mojolicious/lib/MojoliciousTest/Command/test_command.pm
+t/mojolicious/lib/MojoliciousTest/Controller/Foo/Bar.pm
+t/mojolicious/lib/MojoliciousTest/Exceptional.pm
+t/mojolicious/lib/MojoliciousTest/Foo.pm
+t/mojolicious/lib/MojoliciousTest/Plugin/DeploymentPlugin.pm
+t/mojolicious/lib/MojoliciousTest/Plugin/Test/SomePlugin2.pm
+t/mojolicious/lib/MojoliciousTest/Plugin/UPPERCASETestPlugin.pm
+t/mojolicious/lib/MojoliciousTest/PODTest.pm
+t/mojolicious/lib/MojoliciousTest/SideEffects/Test.pm
+t/mojolicious/lib/MojoliciousTest/SyntaxError.pm
+t/mojolicious/lib/MojoliciousTest2/Foo.pm
+t/mojolicious/lib/MojoliciousTest3/Bar.pm
+t/mojolicious/lib/MojoliciousTest3/Baz.pm
+t/mojolicious/lib/PluginWithEmbeddedApp.pm
+t/mojolicious/lib/PluginWithTemplate.pm
+t/mojolicious/lib/SingleFileTestApp.pm
+t/mojolicious/lite_app.t
+t/mojolicious/log_lite_app.t
+t/mojolicious/longpolling_lite_app.t
+t/mojolicious/mojolicious_config_test.whatever.conf
+t/mojolicious/multipath_lite_app.t
+t/mojolicious/ojo.t
+t/mojolicious/ojo_signatures.t
+t/mojolicious/pattern.t
+t/mojolicious/production_app.t
+t/mojolicious/proxy_app.t
+t/mojolicious/public/assets/foo.ab1234cd5678ef.css
+t/mojolicious/public/assets/foo.ab1234cd5678ef.js
+t/mojolicious/public/assets/foo/bar.321.js
+t/mojolicious/public/assets/foo/bar/baz.123.js
+t/mojolicious/public/assets/foo/bar/baz.development.js
+t/mojolicious/public/assets/foo/bar/test.ab1234cd5678ef.min.js
+t/mojolicious/public/assets/foo/bar/yada.css
+t/mojolicious/public/hello.txt
+t/mojolicious/public/hello2.txt
+t/mojolicious/public/hello4.txt
+t/mojolicious/public2/hello.txt
+t/mojolicious/public2/hello3.txt
+t/mojolicious/public_dev/another/file
+t/mojolicious/public_dev/hello.txt
+t/mojolicious/rebased_lite_app.t
+t/mojolicious/renderer.t
+t/mojolicious/restful_lite_app.t
+t/mojolicious/routes.t
+t/mojolicious/secret.txt
+t/mojolicious/signatures_lite_app.t
+t/mojolicious/single_file_test_app.conf
+t/mojolicious/static_lite_app.t
+t/mojolicious/tag_helper_lite_app.t
+t/mojolicious/templates/23.html.epl
+t/mojolicious/templates/dies_too.html.ep
+t/mojolicious/templates/encoding.koi8-r.ep
+t/mojolicious/templates/exception.html.epl
+t/mojolicious/templates/exception.testing.html.ep
+t/mojolicious/templates/foo/bar.rss.ep
+t/mojolicious/templates/foo/bar/index.html.epl
+t/mojolicious/templates/foo/bar/test.html.ep
+t/mojolicious/templates/foo/index.html.xpl
+t/mojolicious/templates/foo/yada.html.ep
+t/mojolicious/templates/layouts/default.html.epl
+t/mojolicious/templates/layouts/green.html.epl
+t/mojolicious/templates/not_found.testing.html.ep
+t/mojolicious/templates/simple.html.pod
+t/mojolicious/templates/syntaxerror.html.epl
+t/mojolicious/templates/withblock.txt.epl
+t/mojolicious/templates/WithGreenLayout.html.epl
+t/mojolicious/templates2/42.html+test.ep
+t/mojolicious/templates2/42.html.ep
+t/mojolicious/templates2/foo/yada.html.epl
+t/mojolicious/testing_app.t
+t/mojolicious/tls_lite_app.t
+t/mojolicious/twinkle_lite_app.conf
+t/mojolicious/twinkle_lite_app.t
+t/mojolicious/types.t
+t/mojolicious/upload_lite_app.t
+t/mojolicious/upload_stream_lite_app.t
+t/mojolicious/validation_lite_app.t
+t/mojolicious/websocket_lite_app.t
+t/mojolicious/yaml_config_lite_app.t
+t/mojolicious/yaml_config_lite_app.yaml
+t/mojolicious/yaml_config_lite_app.yml
+t/mojolicious/yaml_config_lite_app_abs.development.yml
+t/mojolicious/yaml_config_lite_app_abs.yml
+t/pod.t
+t/pod_coverage.t
+t/test/mojo.t
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Mojolicious-9.33/META.json 
new/Mojolicious-9.34/META.json
--- old/Mojolicious-9.33/META.json      2023-06-14 21:25:30.000000000 +0200
+++ new/Mojolicious-9.34/META.json      2023-09-11 20:34:08.000000000 +0200
@@ -64,6 +64,6 @@
          "web" : "https://web.libera.chat/#mojo";
       }
    },
-   "version" : "9.33",
+   "version" : "9.34",
    "x_serialization_backend" : "JSON::PP version 4.07"
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Mojolicious-9.33/META.yml 
new/Mojolicious-9.34/META.yml
--- old/Mojolicious-9.33/META.yml       2023-06-14 21:25:30.000000000 +0200
+++ new/Mojolicious-9.34/META.yml       2023-09-11 20:34:08.000000000 +0200
@@ -35,5 +35,5 @@
   homepage: https://mojolicious.org
   license: http://www.opensource.org/licenses/artistic-license-2.0
   repository: https://github.com/mojolicious/mojo.git
-version: '9.33'
+version: '9.34'
 x_serialization_backend: 'CPAN::Meta::YAML version 0.018'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Mojolicious-9.33/lib/Mojo/Asset/Memory.pm 
new/Mojolicious-9.34/lib/Mojo/Asset/Memory.pm
--- old/Mojolicious-9.33/lib/Mojo/Asset/Memory.pm       2023-03-08 
19:43:28.000000000 +0100
+++ new/Mojolicious-9.34/lib/Mojo/Asset/Memory.pm       2023-08-15 
14:27:06.000000000 +0200
@@ -43,7 +43,7 @@
   return substr shift->{content} // '', $offset, $max;
 }
 
-sub move_to { path($_[1])->spurt($_[0]{content} // '') and return $_[0] }
+sub move_to { path($_[1])->spew($_[0]{content} // '') and return $_[0] }
 
 sub size { length(shift->{content} // '') }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Mojolicious-9.33/lib/Mojo/File.pm 
new/Mojolicious-9.34/lib/Mojo/File.pm
--- old/Mojolicious-9.33/lib/Mojo/File.pm       2023-03-08 19:43:29.000000000 
+0100
+++ new/Mojolicious-9.34/lib/Mojo/File.pm       2023-08-15 14:29:47.000000000 
+0200
@@ -14,6 +14,7 @@
 use File::Temp            ();
 use IO::File              ();
 use Mojo::Collection;
+use Mojo::Util qw(decode deprecated encode);
 
 our @EXPORT_OK = ('curfile', 'path', 'tempdir', 'tempfile');
 
@@ -127,23 +128,30 @@
 }
 
 sub slurp {
-  my $self = shift;
+  my ($self, $encoding) = @_;
 
   CORE::open my $file, '<', $$self or croak qq{Can't open file "$$self": $!};
   my $ret = my $content = '';
   while ($ret = $file->sysread(my $buffer, 131072, 0)) { $content .= $buffer }
   croak qq{Can't read from file "$$self": $!} unless defined $ret;
 
-  return $content;
+  return $encoding ? decode($encoding, $content) : $content;
 }
 
-sub spurt {
-  my ($self, $content) = (shift, join '', @_);
+sub spew {
+  my ($self, $content, $encoding) = @_;
+  $content = encode($encoding, $content) if $encoding;
   CORE::open my $file, '>', $$self or croak qq{Can't open file "$$self": $!};
   ($file->syswrite($content) // -1) == length $content or croak qq{Can't write 
to file "$$self": $!};
   return $self;
 }
 
+# DEPRECATED!
+sub spurt {
+  deprecated 'Mojo::File::spurt is deprecated in favor of Mojo::File::spew';
+  shift->spew(join '', @_);
+}
+
 sub stat { File::stat::stat(${shift()}) }
 
 sub tap { shift->Mojo::Base::tap(@_) }
@@ -192,7 +200,7 @@
   # Use the alternative constructor
   use Mojo::File qw(path);
   my $path = path('/tmp/foo/bar')->make_path;
-  $path->child('test.txt')->spurt('Hello Mojo!');
+  $path->child('test.txt')->spew('Hello Mojo!');
 
 =head1 DESCRIPTION
 
@@ -471,15 +479,17 @@
 =head2 slurp
 
   my $bytes = $path->slurp;
+  my $chars = $path->slurp('UTF-8');
 
-Read all data at once from the file.
+Read all data at once from the file. If an encoding is provided, an attempt 
will be made to decode the content.
 
-=head2 spurt
+=head2 spew
 
-  $path = $path->spurt($bytes);
-  $path = $path->spurt(@chunks_of_bytes);
+  $path = $path->spew($bytes);
+  $path = $path->spew($chars, 'UTF-8');
 
-Write all data at once to the file.
+Write all data at once to the file. If an encoding is provided, an attempt to 
encode the content will be made prior to
+writing.
 
 =head2 stat
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Mojolicious-9.33/lib/Mojo/Promise.pm 
new/Mojolicious-9.34/lib/Mojo/Promise.pm
--- old/Mojolicious-9.33/lib/Mojo/Promise.pm    2023-03-08 19:49:14.000000000 
+0100
+++ new/Mojolicious-9.34/lib/Mojo/Promise.pm    2023-07-06 19:03:59.000000000 
+0200
@@ -72,7 +72,8 @@
   my @wait  = map { $start[0]->clone } 0 .. $#items;
 
   my $start_next = sub {
-    return () unless my $item = shift @items;
+    return () unless @items;
+    my $item = shift @items;
     my ($start_next, $chain) = (__SUB__, shift @wait);
     $_->$cb->then(sub { $chain->resolve(@_); $start_next->() }, sub { 
$chain->reject(@_); @items = () }) for $item;
     return ();
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Mojolicious-9.33/lib/Mojo/Server/Prefork.pm 
new/Mojolicious-9.34/lib/Mojo/Server/Prefork.pm
--- old/Mojolicious-9.33/lib/Mojo/Server/Prefork.pm     2023-06-14 
19:38:31.000000000 +0200
+++ new/Mojolicious-9.34/lib/Mojo/Server/Prefork.pm     2023-08-15 
14:27:14.000000000 +0200
@@ -39,7 +39,7 @@
   return if -e (my $file = path($self->pid_file));
 
   # Create PID file
-  if (my $err = eval { $file->spurt("$pid\n")->chmod(0644) } ? undef : $@) {
+  if (my $err = eval { $file->spew("$pid\n")->chmod(0644) } ? undef : $@) {
     $self->app->log->error(qq{Can't create process id file "$file": $err})
       and die qq{Can't create process id file "$file": $err};
   }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Mojolicious-9.33/lib/Mojo/Server.pm 
new/Mojolicious-9.34/lib/Mojo/Server.pm
--- old/Mojolicious-9.33/lib/Mojo/Server.pm     2023-03-08 19:43:29.000000000 
+0100
+++ new/Mojolicious-9.34/lib/Mojo/Server.pm     2023-08-25 18:41:26.000000000 
+0200
@@ -54,9 +54,9 @@
     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 -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Mojolicious-9.33/lib/Mojolicious/Command.pm 
new/Mojolicious-9.34/lib/Mojolicious/Command.pm
--- old/Mojolicious-9.33/lib/Mojolicious/Command.pm     2023-03-08 
19:43:30.000000000 +0100
+++ new/Mojolicious-9.34/lib/Mojolicious/Command.pm     2023-08-15 
14:27:23.000000000 +0200
@@ -59,7 +59,7 @@
   my ($self, $path, $data) = @_;
   return $self->_loud("  [exist] $path") if -f $path;
   $self->create_dir(path($path)->dirname);
-  path($path)->spurt($data);
+  path($path)->spew($data);
   return $self->_loud("  [write] $path");
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Mojolicious-9.33/lib/Mojolicious/Controller.pm 
new/Mojolicious-9.34/lib/Mojolicious/Controller.pm
--- old/Mojolicious-9.33/lib/Mojolicious/Controller.pm  2023-03-08 
19:43:30.000000000 +0100
+++ new/Mojolicious-9.34/lib/Mojolicious/Controller.pm  2023-08-15 
16:31:19.000000000 +0200
@@ -277,6 +277,11 @@
   return $self->url_for($self->app->static->asset_path($asset));
 }
 
+sub url_for_file {
+  my ($self, $file) = @_;
+  return $self->url_for($self->app->static->file_path($file));
+}
+
 sub write {
   my ($self, $chunk, $cb) = @_;
   $self->res->content->write($chunk, $cb ? sub { shift; $self->$cb(@_) } : ());
@@ -780,6 +785,12 @@
 
 Generate a portable L<Mojo::URL> object with base for a static asset.
 
+=head2 url_for_file
+
+  my $url = $c->url_for_file('/index.html');
+
+Generate a portable L<Mojo::URL> object with base for a static file.
+
 =head2 write
 
   $c = $c->write;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/Mojolicious-9.33/lib/Mojolicious/Guides/Rendering.pod 
new/Mojolicious-9.34/lib/Mojolicious/Guides/Rendering.pod
--- old/Mojolicious-9.33/lib/Mojolicious/Guides/Rendering.pod   2022-09-11 
02:39:58.000000000 +0200
+++ new/Mojolicious-9.34/lib/Mojolicious/Guides/Rendering.pod   2023-08-15 
20:05:19.000000000 +0200
@@ -356,6 +356,15 @@
 
   app->start;
 
+By default static files do not use a prefix and are simply served with a 
higher precedence than routes. This can be
+changed with L<Mojolicious::Static/"prefix">.
+
+  # Serve static files only with a "/static" prefix
+  $app->static->prefix('/static');
+
+To allow for the prefix to be configured dynamically, you can use 
L<Mojolicious::Controller/"url_for_file"> to generate
+URLs with it. Many tag helpers will also use the prefix automatically when it 
makes sense.
+
 =head2 Static assets
 
 While Mojolicious does not have any special support for frontend frameworks 
like L<Vue.js|https://vuejs.org> and
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/Mojolicious-9.33/lib/Mojolicious/Plugin/DefaultHelpers.pm 
new/Mojolicious-9.34/lib/Mojolicious/Plugin/DefaultHelpers.pm
--- old/Mojolicious-9.33/lib/Mojolicious/Plugin/DefaultHelpers.pm       
2023-05-09 00:06:24.000000000 +0200
+++ new/Mojolicious-9.34/lib/Mojolicious/Plugin/DefaultHelpers.pm       
2023-08-15 16:57:23.000000000 +0200
@@ -16,7 +16,7 @@
   my ($self, $app) = @_;
 
   # Controller alias helpers
-  for my $name (qw(app param stash session url_for)) {
+  for my $name (qw(app param stash session url_for url_for_asset 
url_for_file)) {
     $app->helper($name => sub { shift->$name(@_) });
   }
 
@@ -859,6 +859,18 @@
 
   %= url_for('/index.html')->query(foo => 'bar')
 
+=head2 url_for_asset
+
+  %= url_for_asset('/app.js');
+
+Alias for L<Mojolicious::Controller/"url_for_asset">.
+
+=head2 url_for_file
+
+  %= url_for_file('/index.html');
+
+Alias for L<Mojolicious::Controller/"url_for_file">.
+
 =head2 url_with
 
   %= url_with 'named', foo => 'bar', baz => 'yada'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/Mojolicious-9.33/lib/Mojolicious/Plugin/TagHelpers.pm 
new/Mojolicious-9.34/lib/Mojolicious/Plugin/TagHelpers.pm
--- old/Mojolicious-9.33/lib/Mojolicious/Plugin/TagHelpers.pm   2023-03-08 
19:43:31.000000000 +0100
+++ new/Mojolicious-9.34/lib/Mojolicious/Plugin/TagHelpers.pm   2023-08-15 
17:43:41.000000000 +0200
@@ -24,8 +24,9 @@
   $app->helper(button_to      => sub { _button_to(0, @_) });
   $app->helper(check_box      => sub { _input(@_, type => 'checkbox') });
   $app->helper(csrf_button_to => sub { _button_to(1, @_) });
+  $app->helper(favicon        => sub { _favicon(@_) });
   $app->helper(file_field     => sub { _empty_field('file', @_) });
-  $app->helper(image          => sub { _tag('img', src => 
shift->url_for(shift), @_) });
+  $app->helper(image          => sub { _tag('img', src => _file_url(shift, 
shift), @_) });
   $app->helper(input_tag      => sub { _input(@_) });
   $app->helper(password_field => sub { _empty_field('password', @_) });
   $app->helper(radio_button   => sub { _input(@_, type => 'radio') });
@@ -60,6 +61,16 @@
   return _validation($c, $name, 'input', name => $name, @_, type => $type);
 }
 
+sub _favicon {
+  my ($c, $file) = @_;
+  return _tag('link', rel => 'icon', href => _file_url($c, $file // 
'favicon.ico'));
+}
+
+sub _file_url {
+  my ($c, $url) = @_;
+  return blessed $url && $url->isa('Mojo::URL') ? $url : 
$c->url_for_file($url);
+}
+
 sub _form_for {
   my ($c, @url) = (shift, shift);
   push @url, shift if ref $_[0] eq 'HASH';
@@ -103,7 +114,7 @@
 sub _javascript {
   my $c       = shift;
   my $content = ref $_[-1] eq 'CODE' ? "//<![CDATA[\n" . pop->() . "\n//]]>" : 
'';
-  my @src     = @_ % 2               ? (src => $c->url_for(shift))           : 
();
+  my @src     = @_ % 2               ? (src => _file_url($c, shift))         : 
();
   return _tag('script', @src, @_, sub {$content});
 }
 
@@ -166,7 +177,7 @@
   my $c       = shift;
   my $content = ref $_[-1] eq 'CODE' ? "/*<![CDATA[*/\n" . pop->() . 
"\n/*]]>*/" : '';
   return _tag('style', @_, sub {$content}) unless @_ % 2;
-  return _tag('link', rel => 'stylesheet', href => $c->url_for(shift), @_);
+  return _tag('link', rel => 'stylesheet', href => _file_url($c, shift), @_);
 }
 
 sub _submit_button {
@@ -352,6 +363,16 @@
   <input name="notify" type="email" value="nos...@example.com">
   <input id="foo" name="notify" type="email" value="nos...@example.com">
 
+=head2 favicon
+
+  %= favicon
+  %= favicon '/favicon.ico';
+
+Generate C<link> tag for favicon, defaulting to the one that comes bundled 
with Mojolicious.
+
+  <link rel="icon" href="/mojo/favicon.ico">
+  <link rel="icon" href="/favicon.ico">
+
 =head2 file_field
 
   %= file_field 'avatar'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Mojolicious-9.33/lib/Mojolicious/Static.pm 
new/Mojolicious-9.34/lib/Mojolicious/Static.pm
--- old/Mojolicious-9.33/lib/Mojolicious/Static.pm      2023-03-08 
19:43:31.000000000 +0100
+++ new/Mojolicious-9.34/lib/Mojolicious/Static.pm      2023-08-15 
17:24:21.000000000 +0200
@@ -16,12 +16,13 @@
 has classes   => sub { ['main'] };
 has extra     => sub { +{%EXTRA} };
 has paths     => sub { [] };
+has 'prefix';
 
 sub asset_path {
   my ($self, $asset) = @_;
   $asset = "/$asset" unless $asset =~ /^\//;
   my $assets = $self->{assets} //= {};
-  return '/' . $self->asset_dir . ($assets->{$asset} // $asset);
+  return $self->file_path('/' . $self->asset_dir . ($assets->{$asset} // 
$asset));
 }
 
 sub dispatch {
@@ -70,6 +71,13 @@
   return exists $extra->{$rel} ? _get_file($extra->{$rel}) : undef;
 }
 
+sub file_path {
+  my ($self, $file) = @_;
+  $file = "/$file" unless $file =~ /^\//;
+  return $file unless my $prefix = $self->prefix;
+  return "$prefix$file";
+}
+
 sub is_fresh {
   my ($self, $c, $options) = @_;
 
@@ -94,6 +102,13 @@
 
 sub serve {
   my ($self, $c, $rel) = @_;
+
+  # Prefix
+  if (my $prefix = $self->prefix) {
+    $rel = "/$rel";
+    return undef unless $rel =~ s/^\Q$prefix\E\///;
+  }
+
   return undef unless my $asset = $self->file($rel);
   $c->app->types->content_type($c, {file => $rel});
   return !!$self->serve_asset($c, $asset);
@@ -248,6 +263,14 @@
   # Add another "public" directory with higher precedence
   unshift @{$static->paths}, '/home/sri/themes/blue/public';
 
+=head2 prefix
+
+  my $prefix = $static->prefix;
+  $static    = $static->prefix('/static');
+
+Prefix to use for all static files, defaults to C<undef>. This can be very 
useful for production deployments where the
+reverse proxy server should take over serving static files.
+
 =head1 METHODS
 
 L<Mojolicious::Static> inherits all methods from L<Mojo::Base> and implements 
the following new ones.
@@ -275,6 +298,12 @@
 
   my $content = $static->file('foo/bar.html')->slurp;
 
+=head2 file_path
+
+  my $path = $static->file_path('/index.html');
+
+Get static file path with L</"prefix"> if it has been configured.
+
 =head2 is_fresh
 
   my $bool = $static->is_fresh(Mojolicious::Controller->new, {etag => 'abc'});
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/Mojolicious-9.33/lib/Mojolicious/resources/templates/mojo/debug.html.ep 
new/Mojolicious-9.34/lib/Mojolicious/resources/templates/mojo/debug.html.ep
--- old/Mojolicious-9.33/lib/Mojolicious/resources/templates/mojo/debug.html.ep 
2023-04-28 00:37:27.000000000 +0200
+++ new/Mojolicious-9.34/lib/Mojolicious/resources/templates/mojo/debug.html.ep 
2023-08-15 17:08:54.000000000 +0200
@@ -7,13 +7,13 @@
     <title><%= $title %> (<%= app->mode %> mode)</title>
     <meta http-equiv="Pragma" content="no-cache">
     <meta http-equiv="Expires" content="-1">
+    %= favicon
     %= javascript '/mojo/jquery/jquery.js'
     %= javascript '/mojo/highlight.js/highlight.min.js'
     %= javascript '/mojo/highlight.js/mojolicious.min.js'
     %= javascript '/mojo/bootstrap/bootstrap.js'
     %= stylesheet '/mojo/bootstrap/bootstrap.css'
     %= stylesheet '/mojo/highlight.js/highlight-mojo-dark.css'
-    %= stylesheet 
'https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css'
     %= stylesheet '/mojo/mojo.css'
     <script>
       hljs.initHighlightingOnLoad();
@@ -21,14 +21,28 @@
         $('[data-toggle="tooltip"]').tooltip()
       });
     </script>
+    <style>
+      .fa-copyright {
+        line-height: 12px;
+        height: 12px;
+        width: 12px;
+        display: inline-block;
+      }
+
+      .fa-icon {
+        width: 32px;
+        display: inline-block;
+        line-height: 24px;
+      }
+    </style>
   </head>
   <body class="d-flex flex-column h-100">
     <header>
       <nav class="navbar navbar-expand-lg navbar-dark mojobar">
         <a href="https://mojolicious.org"; id="mojobar-brand" 
class="navbar-brand">
           <picture>
-            <img src="<%= url_for '/mojo/logo-white.png' %>"
-              srcset="<%= url_for '/mojo/logo-white-2x.png' %> 2x">
+            <img src="<%= url_for_file '/mojo/logo-white.png' %>"
+              srcset="<%= url_for_file '/mojo/logo-white-2x.png' %> 2x">
           </picture>
         </a>
         <button class="navbar-toggler" type="button" data-toggle="collapse" 
data-target="#navbarNav" aria-controls="navbarNav"
@@ -306,13 +320,19 @@
             <b>Free</b> and <b>Open Source</b>.
           </div>
           <div class="col-sm align-self-center text-center mojo-copy">
-              <i class="far fa-copyright"></i> 2008-2023 Sebastian Riedel and 
the
+              <i class="far fa-copyright"><svg 
xmlns="http://www.w3.org/2000/svg"; viewBox="0 0 512 512"><path 
fill="currentColor" d="M256 8C119.033 8 8 119.033 8 256s111.033 248 248 
248s248-111.033 248-248S392.967 8 256 8zm0 448c-110.532 
0-200-89.451-200-200c0-110.531 89.451-200 200-200c110.532 0 200 89.451 200 
200c0 110.532-89.451 200-200 200zm107.351-101.064c-9.614 9.712-45.53 
41.396-104.065 41.396c-82.43 0-140.484-61.425-140.484-141.567c0-79.152 
60.275-139.401 139.762-139.401c55.531 0 88.738 26.62 97.593 34.779a11.965 
11.965 0 0 1 1.936 15.322l-18.155 28.113c-3.841 5.95-11.966 7.282-17.499 
2.921c-8.595-6.776-31.814-22.538-61.708-22.538c-48.303 0-77.916 35.33-77.916 
80.082c0 41.589 26.888 83.692 78.277 83.692c32.657 0 56.843-19.039 
65.726-27.225c5.27-4.857 13.596-4.039 17.82 1.738l19.865 27.17a11.947 11.947 0 
0 1-1.152 15.518z"/></svg></i> 2008-2023 Sebastian Riedel and the
               <a 
href="https://docs.mojolicious.org/Mojolicious#AUTHORS";>Mojolicious 
contributors</a>.
           </div>
           <div class="col-sm align-self-center text-center mojo-social">
-            <a alt="GitHub" href="https://github.com/mojolicious/mojo";><i 
class="fab fa-github-alt"></i></a>
-            <a alt="Mastodon" href="https://fosstodon.org/@mojolicious";><i 
class="fab fa-mastodon"></i></a>
-            <a alt="LinkedIn" 
href="https://www.linkedin.com/groups/8963713/";><i class="fab 
fa-linkedin"></i></a>
+            <a alt="GitHub" href="https://github.com/mojolicious/mojo"; 
class="fa-icon">
+              <svg xmlns="http://www.w3.org/2000/svg"; viewBox="0 0 480 512" 
style="height: 23px;"><path fill="currentColor" d="M186.1 328.7c0 20.9-10.9 
55.1-36.7 55.1s-36.7-34.2-36.7-55.1s10.9-55.1 36.7-55.1s36.7 34.2 36.7 
55.1zM480 278.2c0 31.9-3.2 65.7-17.5 95c-37.9 76.6-142.1 74.8-216.7 74.8c-75.8 
0-186.2 2.7-225.6-74.8c-14.6-29-20.2-63.1-20.2-95c0-41.9 13.9-81.5 
41.5-113.6c-5.2-15.8-7.7-32.4-7.7-48.8c0-21.5 4.9-32.3 14.6-51.8c45.3 0 74.3 9 
108.8 36c29-6.9 58.8-10 88.7-10c27 0 54.2 2.9 80.4 9.2c34-26.7 63-35.2 
107.8-35.2c9.8 19.5 14.6 30.3 14.6 51.8c0 16.4-2.6 32.7-7.7 48.2c27.5 32.4 39 
72.3 39 114.2zm-64.3 50.5c0-43.9-26.7-82.6-73.5-82.6c-18.9 0-37 3.4-56 6c-14.9 
2.3-29.8 3.2-45.1 3.2c-15.2 0-30.1-.9-45.1-3.2c-18.7-2.6-37-6-56-6c-46.8 0-73.5 
38.7-73.5 82.6c0 87.8 80.4 101.3 150.4 101.3h48.2c70.3 0 150.6-13.4 
150.6-101.3zm-82.6-55.1c-25.8 0-36.7 34.2-36.7 55.1s10.9 55.1 36.7 
55.1s36.7-34.2 36.7-55.1s-10.9-55.1-36.7-55.1z"/></svg>
+            </a>
+            <a alt="Mastodon" href="https://fosstodon.org/@mojolicious"; 
class="fa-icon">
+              <svg xmlns="http://www.w3.org/2000/svg"; viewBox="0 0 448 512" 
style="height: 23px;"><path fill="currentColor" d="M433 
179.11c0-97.2-63.71-125.7-63.71-125.7c-62.52-28.7-228.56-28.4-290.48 0c0 
0-63.72 28.5-63.72 125.7c0 115.7-6.6 259.4 105.63 289.1c40.51 10.7 75.32 13 
103.33 11.4c50.81-2.8 79.32-18.1 79.32-18.1l-1.7-36.9s-36.31 11.4-77.12 
10.1c-40.41-1.4-83-4.4-89.63-54a102.54 102.54 0 0 1-.9-13.9c85.63 20.9 158.65 
9.1 178.75 6.7c56.12-6.7 105-41.3 111.23-72.9c9.8-49.8 9-121.5 9-121.5zm-75.12 
125.2h-46.63v-114.2c0-49.7-64-51.6-64 
6.9v62.5h-46.33V197c0-58.5-64-56.6-64-6.9v114.2H90.19c0-122.1-5.2-147.9 
18.41-175c25.9-28.9 79.82-30.8 103.83 6.1l11.6 19.5l11.6-19.5c24.11-37.1 
78.12-34.8 103.83-6.1c23.71 27.3 18.4 53 18.4 175z"/></svg>
+            </a>
+            <a alt="LinkedIn" href="https://www.linkedin.com/groups/8963713/"; 
class="fa-icon">
+              <svg xmlns="http://www.w3.org/2000/svg"; viewBox="0 0 448 512" 
style="height: 23px;"><path fill="currentColor" d="M416 32H31.9C14.3 32 0 46.5 
0 64.3v383.4C0 465.5 14.3 480 31.9 480H416c17.6 0 32-14.5 
32-32.3V64.3c0-17.8-14.4-32.3-32-32.3zM135.4 
416H69V202.2h66.5V416zm-33.2-243c-21.3 0-38.5-17.3-38.5-38.5S80.9 96 102.2 
96c21.2 0 38.5 17.3 38.5 38.5c0 21.3-17.2 38.5-38.5 38.5zm282.1 
243h-66.4V312c0-24.8-.5-56.7-34.5-56.7c-34.6 0-39.9 27-39.9 
54.9V416h-66.4V202.2h63.7v29.2h.9c8.9-16.8 30.6-34.5 62.9-34.5c67.2 0 79.7 44.3 
79.7 101.9V416z"/></svg>
+            </a>
           </div>
         </div>
       </div>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/Mojolicious-9.33/lib/Mojolicious/resources/templates/mojo/exception.html.ep 
new/Mojolicious-9.34/lib/Mojolicious/resources/templates/mojo/exception.html.ep
--- 
old/Mojolicious-9.33/lib/Mojolicious/resources/templates/mojo/exception.html.ep 
    2022-06-14 13:31:51.000000000 +0200
+++ 
new/Mojolicious-9.34/lib/Mojolicious/resources/templates/mojo/exception.html.ep 
    2023-08-15 17:09:41.000000000 +0200
@@ -8,7 +8,7 @@
         background-color: #caecf6;
       }
       #raptor {
-        background: url(<%= url_for '/mojo/failraptor.png' %>);
+        background: url(<%= url_for_file '/mojo/failraptor.png' %>);
         height: 488px;
         left: 50%;
         margin-left: -371px;
@@ -18,6 +18,7 @@
         width: 743px;
       }
     </style>
+    %= favicon
   </head>
   <body><div id="raptor"></div></body>
 </html>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/Mojolicious-9.33/lib/Mojolicious/resources/templates/mojo/not_found.html.ep 
new/Mojolicious-9.34/lib/Mojolicious/resources/templates/mojo/not_found.html.ep
--- 
old/Mojolicious-9.33/lib/Mojolicious/resources/templates/mojo/not_found.html.ep 
    2022-06-14 13:31:51.000000000 +0200
+++ 
new/Mojolicious-9.34/lib/Mojolicious/resources/templates/mojo/not_found.html.ep 
    2023-08-15 17:10:18.000000000 +0200
@@ -16,7 +16,7 @@
         top: 60%;
       }
       #notfound {
-        background: url(<%= url_for '/mojo/notfound.png' %>);
+        background: url(<%= url_for_file '/mojo/notfound.png' %>);
         height: 62px;
         left: 50%;
         margin-left: -153px;
@@ -26,6 +26,7 @@
         width: 306px;
       }
     </style>
+    %= favicon
   </head>
   <body>
     %= link_to url_for->base => begin
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Mojolicious-9.33/lib/Mojolicious.pm 
new/Mojolicious-9.34/lib/Mojolicious.pm
--- old/Mojolicious-9.33/lib/Mojolicious.pm     2023-05-15 11:22:06.000000000 
+0200
+++ new/Mojolicious-9.34/lib/Mojolicious.pm     2023-08-15 16:34:29.000000000 
+0200
@@ -57,7 +57,7 @@
 has validator => sub { Mojolicious::Validator->new };
 
 our $CODENAME = 'Waffle';
-our $VERSION  = '9.33';
+our $VERSION  = '9.34';
 
 sub BUILD_DYNAMIC {
   my ($class, $method, $dyn_methods) = @_;
@@ -526,6 +526,9 @@
 
 For serving static files from your C<public> directories, defaults to a 
L<Mojolicious::Static> object.
 
+  # Serve static files only with a "/static" prefix
+  $app->static->prefix('/static');
+
   # Add another "public" directory
   push @{$app->static->paths}, '/home/sri/public';
 
@@ -776,6 +779,11 @@
 
 Licensed under the MIT License, L<http://creativecommons.org/licenses/MIT>.
 
+=head2 Font Awesome
+
+Licensed under the CC-BY License, Version 4.0 
L<https://creativecommons.org/licenses/by/4.0/> and SIL OFL, Version 1.1
+L<https://opensource.org/licenses/OFL-1.1>.
+
 =head1 CODE NAMES
 
 Every major release of L<Mojolicious> has a code name, these are the ones that 
have been used in the past.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Mojolicious-9.33/lib/ojo.pm 
new/Mojolicious-9.34/lib/ojo.pm
--- old/Mojolicious-9.33/lib/ojo.pm     2023-03-08 19:43:31.000000000 +0100
+++ new/Mojolicious-9.34/lib/ojo.pm     2023-08-15 14:26:57.000000000 +0200
@@ -155,7 +155,7 @@
 
 Encode Perl data structure or decode JSON with L<Mojo::JSON/"j">.
 
-  $ perl -Mojo -E 'f("hello.json")->spurt(j {hello => "world!"})'
+  $ perl -Mojo -E 'f("hello.json")->spew(j {hello => "world!"})'
 
 =head2 l
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Mojolicious-9.33/t/mojo/daemon.t 
new/Mojolicious-9.34/t/mojo/daemon.t
--- old/Mojolicious-9.33/t/mojo/daemon.t        2023-03-08 19:43:32.000000000 
+0100
+++ new/Mojolicious-9.34/t/mojo/daemon.t        2023-08-25 18:41:33.000000000 
+0200
@@ -91,6 +91,15 @@
   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 -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Mojolicious-9.33/t/mojo/file.t 
new/Mojolicious-9.34/t/mojo/file.t
--- old/Mojolicious-9.33/t/mojo/file.t  2023-03-08 19:43:33.000000000 +0100
+++ new/Mojolicious-9.34/t/mojo/file.t  2023-08-15 14:30:50.000000000 +0200
@@ -7,7 +7,7 @@
 use File::Spec::Functions qw(abs2rel canonpath catfile rel2abs splitdir);
 use File::Temp;
 use Mojo::File qw(curfile path tempdir tempfile);
-use Mojo::Util qw(encode);
+use Mojo::Util qw(decode encode);
 
 subtest 'Constructor' => sub {
   is(Mojo::File->new, canonpath(getcwd), 'same path');
@@ -103,8 +103,8 @@
   my $file = tempfile(DIR => $dir);
   my $path = "$file";
   ok -f $path, 'file exists';
-  is $file->dirname,              $dir,   'same directory';
-  is $file->spurt('test')->slurp, 'test', 'right result';
+  is $file->dirname,             $dir,   'same directory';
+  is $file->spew('test')->slurp, 'test', 'right result';
   undef $file;
   ok !-f $path, 'file does not exist anymore';
 };
@@ -113,7 +113,7 @@
   plan skip_all => 'cannot move open file' if $^O eq 'MSWin32';
   my $dir  = tempdir;
   my $file = tempfile(DIR => $dir);
-  $file->spurt('works');
+  $file->spew('works');
   is $file->slurp, 'works', 'right content';
   my $file2 = tempfile(DIR => $dir);
   $file->move_to($file2);
@@ -126,14 +126,14 @@
 
 subtest 'open' => sub {
   my $file = tempfile;
-  $file->spurt("test\n123\n");
+  $file->spew("test\n123\n");
   my $handle = $file->open('<');
   is_deeply [<$handle>], ["test\n", "123\n"], 'right structure';
   $handle = $file->open('r');
   is_deeply [<$handle>], ["test\n", "123\n"], 'right structure';
   $handle = $file->open(O_RDONLY);
   is_deeply [<$handle>], ["test\n", "123\n"], 'right structure';
-  $file->spurt(encode('UTF-8', '♥'));
+  $file->spew(encode('UTF-8', '♥'));
   $handle = $file->open('<:encoding(UTF-8)');
   is_deeply [<$handle>], ['♥'], 'right structure';
   my $dir = tempdir;
@@ -141,7 +141,7 @@
   like $@, qr/^Can't open file/, 'right error';
   eval { $dir->child('does_not_exist')->slurp };
   like $@, qr/^Can't open file/, 'right error';
-  eval { $dir->child('foo')->make_path->spurt('fail') };
+  eval { $dir->child('foo')->make_path->spew('fail') };
   like $@, qr/^Can't open file/, 'right error';
 };
 
@@ -158,7 +158,7 @@
 
 subtest 'remove' => sub {
   my $dir = tempdir;
-  $dir->child('test.txt')->spurt('test!');
+  $dir->child('test.txt')->spew('test!');
   ok -e $dir->child('test.txt'), 'file exists';
   is $dir->child('test.txt')->slurp, 'test!', 'right content';
   ok !-e $dir->child('test.txt')->remove->touch->remove->remove, 'file no 
longer exists';
@@ -168,19 +168,19 @@
 
 subtest 'remove_tree' => sub {
   my $dir = tempdir;
-  $dir->child('foo', 'bar')->make_path->child('test.txt')->spurt('test!');
+  $dir->child('foo', 'bar')->make_path->child('test.txt')->spew('test!');
   is $dir->child('foo', 'bar', 'test.txt')->slurp, 'test!', 'right content';
   my $subdir = $dir->child('foo', 'foobar')->make_path;
-  ok -e $subdir->child('bar')->make_path->child('test.txt')->spurt('test'), 
'file created';
-  ok -d $subdir->remove_tree({keep_root => 1}),                             
'directory still exists';
-  ok !-e $subdir->child('bar'),                                             
'children have been removed';
-  ok !-e $dir->child('foo')->remove_tree->to_string,                        
'directory has been removed';
+  ok -e $subdir->child('bar')->make_path->child('test.txt')->spew('test'), 
'file created';
+  ok -d $subdir->remove_tree({keep_root => 1}),                            
'directory still exists';
+  ok !-e $subdir->child('bar'),                                            
'children have been removed';
+  ok !-e $dir->child('foo')->remove_tree->to_string,                       
'directory has been removed';
 };
 
 subtest 'move_to' => sub {
   my $dir         = tempdir;
   my $destination = $dir->child('dest.txt');
-  my $source      = $dir->child('src.txt')->spurt('works!');
+  my $source      = $dir->child('src.txt')->spew('works!');
   ok -f $source,       'file exists';
   ok !-f $destination, 'file does not exists';
   is $source->move_to($destination)->to_string, $destination, 'same path';
@@ -198,7 +198,7 @@
 subtest 'copy_to' => sub {
   my $dir         = tempdir;
   my $destination = $dir->child('dest.txt');
-  my $source      = $dir->child('src.txt')->spurt('works!');
+  my $source      = $dir->child('src.txt')->spew('works!');
   ok -f $source,       'file exists';
   ok !-f $destination, 'file does not exists';
   is $source->copy_to($destination)->to_string, $destination, 'same path';
@@ -223,12 +223,12 @@
 
 subtest 'stat' => sub {
   my $dir = tempdir;
-  is $dir->child('test.txt')->spurt('1234')->stat->size, 4, 'right size';
+  is $dir->child('test.txt')->spew('1234')->stat->size, 4, 'right size';
 };
 
 subtest 'lstat' => sub {
   my $dir  = tempdir;
-  my $orig = $dir->child('test.txt')->spurt('');
+  my $orig = $dir->child('test.txt')->spew('');
   my $link = $orig->sibling('test.link');
   plan skip_all => 'symlink unimplemented' unless eval { symlink $orig, $link 
};
   is $link->stat->size,    0, 'target file is empty';
@@ -314,8 +314,8 @@
   my $file = $dir->child('test.txt');
   ok !-e $file,       'file does not exist';
   ok -e $file->touch, 'file exists';
-  is $file->spurt('test!')->slurp, 'test!', 'right content';
-  is $file->touch->slurp,          'test!', 'right content';
+  is $file->spew('test!')->slurp, 'test!', 'right content';
+  is $file->touch->slurp,         'test!', 'right content';
   my $future = time + 1000;
   utime $future, $future, $file->to_string;
   is $file->stat->mtime,          $future, 'right mtime';
@@ -331,15 +331,34 @@
 
 subtest 'I/O' => sub {
   my $dir  = tempdir;
-  my $file = $dir->child('test.txt')->spurt('just works!');
-  is $file->slurp,                              'just works!', 'right content';
-  is $file->spurt('w', 'orks', ' too!')->slurp, 'works too!',  'right content';
+  my $file = $dir->child('test.txt')->spew('just works!');
+  is $file->slurp, 'just works!', 'right content';
   {
     no warnings 'redefine';
     local *IO::Handle::syswrite = sub { $! = 0; 5 };
-    eval { $file->spurt("just\nworks!") };
+    eval { $file->spew("just\nworks!") };
     like $@, qr/Can't write to file ".*/, 'right error';
   }
 };
 
+subtest 'I/O with encoding' => sub {
+  my $dir  = tempdir;
+  my $file = $dir->child('test.txt')->spew('♥1', 'UTF-8');
+  is $file->slurp('UTF-8'),            '♥1',         'right content';
+  is decode('UTF-8', $file->slurp()),  '♥1',         'right content';
+  is $file->spew('works too!')->slurp, 'works too!', 'right content';
+
+  subtest 'I/O with manual encoding' => sub {
+    $file->spew(encode('UTF-8', '♥1'));
+    is $file->slurp('UTF-8'),           '♥1', 'right content';
+    is decode('UTF-8', $file->slurp()), '♥1', 'right content';
+  };
+
+  {
+    local $@;
+    eval { $file->spew('♥1') };
+    like $@, qr/Wide character/, 'right error';
+  }
+};
+
 done_testing();
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Mojolicious-9.33/t/mojo/hypnotoad.t 
new/Mojolicious-9.34/t/mojo/hypnotoad.t
--- old/Mojolicious-9.33/t/mojo/hypnotoad.t     2023-03-08 19:43:33.000000000 
+0100
+++ new/Mojolicious-9.34/t/mojo/hypnotoad.t     2023-08-15 14:28:46.000000000 
+0200
@@ -61,7 +61,7 @@
   my $log    = $dir->child('mojo.log');
   my $port1  = Mojo::IOLoop::Server->generate_port;
   my $port2  = Mojo::IOLoop::Server->generate_port;
-  $script->spurt(<<EOF);
+  $script->spew(<<EOF);
 use Mojolicious::Lite;
 use Mojo::IOLoop;
 
@@ -133,7 +133,7 @@
     is $tx->res->body, 'Hello Hypnotoad!', 'right content';
   };
 
-  $script->spurt(<<'EOF');
+  $script->spew(<<'EOF');
 use Mojolicious::Lite;
 
 die if $ENV{HYPNOTOAD_PID};
@@ -168,7 +168,7 @@
     $ua->start($tx => sub { });
     Mojo::IOLoop->one_tick until $tx->req->is_finished;
 
-    $script->spurt(<<EOF);
+    $script->spew(<<EOF);
 use Mojolicious::Lite;
 
 app->log->path('$log');
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Mojolicious-9.33/t/mojo/lib/myapp-module-true.pl 
new/Mojolicious-9.34/t/mojo/lib/myapp-module-true.pl
--- old/Mojolicious-9.33/t/mojo/lib/myapp-module-true.pl        1970-01-01 
01:00:00.000000000 +0100
+++ new/Mojolicious-9.34/t/mojo/lib/myapp-module-true.pl        2023-08-25 
18:41:43.000000000 +0200
@@ -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
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Mojolicious-9.33/t/mojo/morbo.t 
new/Mojolicious-9.34/t/mojo/morbo.t
--- old/Mojolicious-9.33/t/mojo/morbo.t 2023-03-08 19:43:33.000000000 +0100
+++ new/Mojolicious-9.34/t/mojo/morbo.t 2023-08-15 14:28:57.000000000 +0200
@@ -27,7 +27,7 @@
 $morbo->backend->watch([$subdir, $script]);
 is_deeply $morbo->backend->modified_files, [], 'no files have changed';
 my $started = $dir->child('started1.txt');
-$script->spurt(<<EOF);
+$script->spew(<<EOF);
 use Mojolicious::Lite;
 use Mojo::File qw(path);
 use Mojo::IOLoop;
@@ -61,7 +61,7 @@
 subtest 'Update script without changing size' => sub {
   my ($size, $mtime) = (stat $script)[7, 9];
   $started = $started->sibling('started2.txt');
-  $script->spurt(<<EOF);
+  $script->spew(<<EOF);
 use Mojolicious::Lite;
 use Mojo::File qw(path);
 use Mojo::IOLoop;
@@ -96,7 +96,7 @@
   my ($size, $mtime) = (stat $script)[7, 9];
   is_deeply $morbo->backend->modified_files, [], 'no files have changed';
   $started = $started->sibling('started3.txt');
-  $script->spurt(<<"EOF");
+  $script->spew(<<"EOF");
 use Mojolicious::Lite;
 use Mojo::File qw(path);
 use Mojo::IOLoop;
@@ -134,9 +134,9 @@
 subtest 'New file(s)' => sub {
   is_deeply $morbo->backend->modified_files, [], 'directory has not changed';
   my @new = map { $subdir->child("$_.txt") } qw/test testing/;
-  $_->spurt('whatever') for @new;
+  $_->spew('whatever') for @new;
   is_deeply $morbo->backend->modified_files, \@new, 'two files have changed';
-  $subdir->child('.hidden.txt')->spurt('whatever');
+  $subdir->child('.hidden.txt')->spew('whatever');
   is_deeply $morbo->backend->modified_files, [], 'directory has not changed 
again';
 };
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Mojolicious-9.33/t/mojo/promise.t 
new/Mojolicious-9.34/t/mojo/promise.t
--- old/Mojolicious-9.33/t/mojo/promise.t       2023-03-08 19:43:34.000000000 
+0100
+++ new/Mojolicious-9.34/t/mojo/promise.t       2023-07-06 19:03:59.000000000 
+0200
@@ -482,12 +482,12 @@
 
 subtest 'Map' => sub {
   my (@results, @errors, @started);
-  my $promise = Mojo::Promise->map(sub { push @started, $_; 
Mojo::Promise->resolve($_) }, 1 .. 5)
+  my $promise = Mojo::Promise->map(sub { push @started, $_; 
Mojo::Promise->resolve($_) }, 1 .. 5, undef, 0)
     ->then(sub { @results = @_ }, sub { @errors = @_ });
-  is_deeply \@started, [1, 2, 3, 4, 5], 'all started without concurrency';
+  is_deeply \@started, [1, 2, 3, 4, 5, undef, 0], 'all started without 
concurrency';
   $promise->wait;
-  is_deeply \@results, [[1], [2], [3], [4], [5]], 'correct result';
-  is_deeply \@errors,  [],                        'promise not rejected';
+  is_deeply \@results, [[1], [2], [3], [4], [5], [undef], [0]], 'correct 
result';
+  is_deeply \@errors,  [],                                      'promise not 
rejected';
 };
 
 subtest 'Map (with concurrency limit)' => sub {
@@ -503,10 +503,12 @@
         $n;
       });
     },
-    1 .. 7
+    1 .. 7,
+    undef,
+    0,
   )->then(sub { @results = @_ }, sub { @errors = @_ })->wait;
-  is_deeply \@results, [[1], [2], [3], [4], [5], [6], [7]], 'correct result';
-  is_deeply \@errors,  [],                                  'promise not 
rejected';
+  is_deeply \@results, [[1], [2], [3], [4], [5], [6], [7], [undef], [0]], 
'correct result';
+  is_deeply \@errors,  [],                                                
'promise not rejected';
 };
 
 subtest 'Map (with reject)' => sub {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Mojolicious-9.33/t/mojo/subprocess.t 
new/Mojolicious-9.34/t/mojo/subprocess.t
--- old/Mojolicious-9.33/t/mojo/subprocess.t    2023-03-08 19:43:35.000000000 
+0100
+++ new/Mojolicious-9.34/t/mojo/subprocess.t    2023-08-15 14:29:09.000000000 
+0200
@@ -257,7 +257,7 @@
   my $file       = tempfile;
   my $called     = 0;
   my $subprocess = Mojo::IOLoop::Subprocess->new;
-  $subprocess->on(cleanup => sub { $file->spurt(shift->serialize->({test => 
++$called})) });
+  $subprocess->on(cleanup => sub { $file->spew(shift->serialize->({test => 
++$called})) });
   $subprocess->run(
     sub {'Hello Mojo!'},
     sub {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Mojolicious-9.33/t/mojolicious/static_lite_app.t 
new/Mojolicious-9.34/t/mojolicious/static_lite_app.t
--- old/Mojolicious-9.33/t/mojolicious/static_lite_app.t        2023-03-08 
19:43:38.000000000 +0100
+++ new/Mojolicious-9.34/t/mojolicious/static_lite_app.t        2023-08-15 
17:17:20.000000000 +0200
@@ -315,6 +315,12 @@
     ->header_exists_not('Cache-Control')->content_like(qr/\* foo\.css asset/);
 };
 
+subtest 'File' => sub {
+  my $c = $t->app->build_controller;
+  is $c->url_for_file('/unknown.css')->path, '/unknown.css', 'right file path';
+  is $c->url_for_file('/foo/bar.css')->path, '/foo/bar.css', 'right file path';
+};
+
 done_testing();
 
 __DATA__
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/Mojolicious-9.33/t/mojolicious/static_prefix_lite_app.t 
new/Mojolicious-9.34/t/mojolicious/static_prefix_lite_app.t
--- old/Mojolicious-9.33/t/mojolicious/static_prefix_lite_app.t 1970-01-01 
01:00:00.000000000 +0100
+++ new/Mojolicious-9.34/t/mojolicious/static_prefix_lite_app.t 2023-08-15 
18:00:13.000000000 +0200
@@ -0,0 +1,107 @@
+use Mojo::Base -strict;
+
+BEGIN { $ENV{MOJO_REACTOR} = 'Mojo::Reactor::Poll' }
+
+use Test::Mojo;
+use Test::More;
+use Mojolicious::Lite;
+
+app->static->prefix('/static');
+
+get '/hello.txt' => {text => 'Just an action!'};
+
+get '/helpers';
+
+my $t = Test::Mojo->new;
+
+subtest 'Action for static file path without prefix' => sub {
+  $t->get_ok('/hello.txt')->status_is(200)->content_is('Just an action!');
+};
+
+subtest 'Static file' => sub {
+  $t->get_ok('/static/hello.txt')->status_is(200)->header_is(Server => 
'Mojolicious (Perl)')
+    ->header_exists_not('Cache-Control')->header_is('Accept-Ranges' => 
'bytes')->header_is('Content-Length' => 31)
+    ->content_is("Hello Mojo from a static file!\n");
+};
+
+subtest 'Static asset' => sub {
+  
$t->get_ok('/static/assets/foo.ab1234cd5678ef.css')->status_is(200)->header_is(Server
 => 'Mojolicious (Perl)')
+    ->content_like(qr/\* foo\.css asset/);
+};
+
+subtest 'Bundled static file' => sub {
+  
$t->get_ok('/static/favicon.ico')->status_is(200)->content_type_is('image/x-icon');
+};
+
+subtest 'Bundled template' => sub {
+  
$t->get_ok('/doesnotexist')->status_is(404)->element_exists('link[href=/static/favicon.ico]')
+    ->element_exists('link[href=/static/mojo/mojo.css]');
+};
+
+subtest 'Helpers with prefix' => sub {
+  $t->get_ok('/helpers')->status_is(200)->content_is(<<EOF);
+/foo.png
+/static/foo.png
+/static/assets/foo.png
+/static/assets/foo.ab1234cd5678ef.css
+<link href="/static/favicon.ico" rel="icon">
+<link href="/static/foo.ico" rel="icon">
+<img src="/static/foo.png">
+<script src="/static/foo.js"></script>
+<link href="/static/foo.css" rel="stylesheet">
+<script src="/static/assets/app.js"></script>
+<link href="/static/assets/app.css" rel="stylesheet">
+<img src="/static/assets/app.png">
+<link href="/static/assets/foo.ab1234cd5678ef.css" rel="stylesheet">
+EOF
+};
+
+subtest 'Hidden inline file' => sub {
+  $t->get_ok('/static/hidden')->status_is(404)->content_unlike(qr/Unreachable 
file/);
+};
+
+subtest 'Base64 partial inline file' => sub {
+  $t->get_ok('/static.txt')->status_is(404);
+  $t->get_ok('/static/static.txt' => {Range => 
'bytes=2-5'})->status_is(206)->header_is(Server => 'Mojolicious (Perl)')
+    ->header_is('Accept-Ranges'  => 'bytes')->header_is('Content-Range' => 
'bytes 2-5/15')
+    ->header_is('Content-Length' => 4)->content_is('st 1');
+};
+
+subtest 'UTF-8 encoded inline file' => sub {
+  $t->get_ok('/static_utf8.txt')->status_is(404);
+  $t->get_ok('/static/static_utf8.txt')->status_is(200)->header_is(Server => 
'Mojolicious (Perl)')
+    ->content_is("I ♥ Unicode\n");
+};
+
+subtest 'File' => sub {
+  my $c = $t->app->build_controller;
+  is $c->url_for_file('/unknown.css')->path, '/static/unknown.css', 'right 
file path';
+  is $c->url_for_file('/foo/bar.css')->path, '/static/foo/bar.css', 'right 
file path';
+};
+
+done_testing();
+
+__DATA__
+@@helpers.html.ep
+%= url_for '/foo.png'
+%= url_for_file '/foo.png'
+%= url_for_asset '/foo.png'
+%= url_for_asset '/foo.css'
+%= favicon
+%= favicon '/foo.ico'
+%= image '/foo.png'
+%= javascript '/foo.js'
+%= stylesheet '/foo.css'
+%= asset_tag '/app.js'
+%= asset_tag '/app.css'
+%= asset_tag '/app.png'
+%= asset_tag '/foo.css'
+
+@@ hidden
+Unreachable file.
+
+@@ static.txt (base64)
+dGVzdCAxMjMKbGFsYWxh
+
+@@ static_utf8.txt
+I ♥ Unicode
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Mojolicious-9.33/t/mojolicious/tag_helper_lite_app.t 
new/Mojolicious-9.34/t/mojolicious/tag_helper_lite_app.t
--- old/Mojolicious-9.33/t/mojolicious/tag_helper_lite_app.t    2023-03-08 
19:43:38.000000000 +0100
+++ new/Mojolicious-9.34/t/mojolicious/tag_helper_lite_app.t    2023-08-15 
17:14:07.000000000 +0200
@@ -24,6 +24,8 @@
 
 get 'style';
 
+get 'favicon';
+
 get '/basicform';
 
 post '/text';
@@ -175,6 +177,12 @@
 /*]]>*/</style>
 EOF
 
+# Favicon
+$t->get_ok('/favicon')->status_is(200)->content_is(<<EOF);
+<link href="/favicon.ico" rel="icon">
+<link href="/foo.ico" rel="icon">
+EOF
+
 # Basic form
 $t->get_ok('/basicform')->status_is(200)->content_is(<<EOF);
 <form action="/links">
@@ -613,6 +621,10 @@
   body {color: #000}
 <% end %>
 
+@@ favicon.html.ep
+<%= favicon %>
+<%= favicon '/foo.ico' %>
+
 @@ basicform.html.ep
 %= form_for links => begin
   %= label_for foo => '<Foo>'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Mojolicious-9.33/t/pod_coverage.t 
new/Mojolicious-9.34/t/pod_coverage.t
--- old/Mojolicious-9.33/t/pod_coverage.t       2023-03-08 19:43:39.000000000 
+0100
+++ new/Mojolicious-9.34/t/pod_coverage.t       2023-08-15 14:31:17.000000000 
+0200
@@ -11,4 +11,4 @@
   qw(AWAIT_NEW_FAIL AWAIT_ON_CANCEL AWAIT_ON_READY AWAIT_WAIT)
 );
 
-all_pod_coverage_ok({also_private => ['BUILD_DYNAMIC', @await]});
+all_pod_coverage_ok({also_private => ['BUILD_DYNAMIC', @await, 'spurt']});

Reply via email to