Hello community,

here is the log from the commit of package perl-Mojolicious for 
openSUSE:Factory checked in at 2019-08-13 13:28:03
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/perl-Mojolicious (Old)
 and      /work/SRC/openSUSE:Factory/.perl-Mojolicious.new.9556 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "perl-Mojolicious"

Tue Aug 13 13:28:03 2019 rev:114 rq:723031 version:8.23

Changes:
--------
--- /work/SRC/openSUSE:Factory/perl-Mojolicious/perl-Mojolicious.changes        
2019-07-21 11:34:32.884775234 +0200
+++ 
/work/SRC/openSUSE:Factory/.perl-Mojolicious.new.9556/perl-Mojolicious.changes  
    2019-08-13 13:28:05.365310623 +0200
@@ -1,0 +2,12 @@
+Tue Aug 13 05:17:36 UTC 2019 - Stephan Kulow <[email protected]>
+
+- updated to 8.23
+   see /usr/share/doc/packages/perl-Mojolicious/Changes
+
+  8.23  2019-08-12
+    - Updated Cpanel::JSON::XS requirement to 4.09 for duplicate keys support.
+      (Grinnz)
+    - Added head and tail methods to Mojo::Collection. (Grinnz)
+    - Improved Mojo::File not to allow undefined values in paths.
+
+-------------------------------------------------------------------

Old:
----
  Mojolicious-8.22.tar.gz

New:
----
  Mojolicious-8.23.tar.gz

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

Other differences:
------------------
++++++ perl-Mojolicious.spec ++++++
--- /var/tmp/diff_new_pack.inAp2M/_old  2019-08-13 13:28:06.261310387 +0200
+++ /var/tmp/diff_new_pack.inAp2M/_new  2019-08-13 13:28:06.261310387 +0200
@@ -17,7 +17,7 @@
 
 
 Name:           perl-Mojolicious
-Version:        8.22
+Version:        8.23
 Release:        0
 %define cpan_name Mojolicious
 Summary:        Real-time web framework

++++++ Mojolicious-8.22.tar.gz -> Mojolicious-8.23.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Mojolicious-8.22/Changes new/Mojolicious-8.23/Changes
--- old/Mojolicious-8.22/Changes        2019-07-17 12:36:08.000000000 +0200
+++ new/Mojolicious-8.23/Changes        2019-08-12 23:54:23.000000000 +0200
@@ -1,4 +1,10 @@
 
+8.23  2019-08-12
+  - Updated Cpanel::JSON::XS requirement to 4.09 for duplicate keys support.
+    (Grinnz)
+  - Added head and tail methods to Mojo::Collection. (Grinnz)
+  - Improved Mojo::File not to allow undefined values in paths.
+
 8.22  2019-07-17
   - Fixed a bug where Mojo::Exception would not stringify correctly for error
     messages that end with a newline.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Mojolicious-8.22/MANIFEST 
new/Mojolicious-8.23/MANIFEST
--- old/Mojolicious-8.22/MANIFEST       2019-07-17 12:45:49.000000000 +0200
+++ new/Mojolicious-8.23/MANIFEST       2019-08-13 00:50:48.000000000 +0200
@@ -149,6 +149,7 @@
 LICENSE
 Makefile.PL
 MANIFEST                       This list of files
+MANIFEST.bak
 MANIFEST.SKIP
 README.md
 script/hypnotoad
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Mojolicious-8.22/MANIFEST.bak 
new/Mojolicious-8.23/MANIFEST.bak
--- old/Mojolicious-8.22/MANIFEST.bak   1970-01-01 01:00:00.000000000 +0100
+++ new/Mojolicious-8.23/MANIFEST.bak   2019-07-17 12:45:46.000000000 +0200
@@ -0,0 +1,352 @@
+.perltidyrc
+Changes
+examples/chat.pl
+examples/connect-proxy.pl
+examples/entities.pl
+examples/fast.pl
+examples/hello-template.pl
+examples/hello.pl
+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/Delay.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/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/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/TagHelpers.pm
+lib/Mojolicious/Plugins.pm
+lib/Mojolicious/Renderer.pm
+lib/Mojolicious/resources/public/favicon.ico
+lib/Mojolicious/resources/public/mojo/failraptor.png
+lib/Mojolicious/resources/public/mojo/jquery/jquery.js
+lib/Mojolicious/resources/public/mojo/logo-black-2x.png
+lib/Mojolicious/resources/public/mojo/logo-black.png
+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/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/public/mojo/prettify/prettify-mojo-dark.css
+lib/Mojolicious/resources/public/mojo/prettify/run_prettify.js
+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/delay.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/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/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/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/test_command.pm
+t/mojolicious/lib/MojoliciousTest/Exceptional.pm
+t/mojolicious/lib/MojoliciousTest/Foo.pm
+t/mojolicious/lib/MojoliciousTest/Foo/Bar.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/MojoliciousTestController.pm
+t/mojolicious/lib/PluginWithEmbeddedApp.pm
+t/mojolicious/lib/PluginWithTemplate.pm
+t/mojolicious/lib/SingleFileTestApp.pm
+t/mojolicious/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/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/pod.t
+t/pod_coverage.t
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Mojolicious-8.22/META.json 
new/Mojolicious-8.23/META.json
--- old/Mojolicious-8.22/META.json      2019-07-17 12:45:49.000000000 +0200
+++ new/Mojolicious-8.23/META.json      2019-08-13 00:50:48.000000000 +0200
@@ -62,6 +62,6 @@
       },
       "x_IRC" : "irc://irc.freenode.net/#mojo"
    },
-   "version" : "8.22",
+   "version" : "8.23",
    "x_serialization_backend" : "JSON::PP version 4.04"
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Mojolicious-8.22/META.yml 
new/Mojolicious-8.23/META.yml
--- old/Mojolicious-8.22/META.yml       2019-07-17 12:45:49.000000000 +0200
+++ new/Mojolicious-8.23/META.yml       2019-08-13 00:50:48.000000000 +0200
@@ -34,5 +34,5 @@
   homepage: https://mojolicious.org
   license: http://www.opensource.org/licenses/artistic-license-2.0
   repository: https://github.com/mojolicious/mojo.git
-version: '8.22'
+version: '8.23'
 x_serialization_backend: 'CPAN::Meta::YAML version 0.018'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Mojolicious-8.22/lib/Mojo/Collection.pm 
new/Mojolicious-8.23/lib/Mojo/Collection.pm
--- old/Mojolicious-8.22/lib/Mojo/Collection.pm 2019-06-21 23:11:56.000000000 
+0200
+++ new/Mojolicious-8.23/lib/Mojo/Collection.pm 2019-07-31 20:56:00.000000000 
+0200
@@ -1,6 +1,7 @@
 package Mojo::Collection;
 use Mojo::Base -strict;
 
+use re 'is_regexp';
 use Carp 'croak';
 use Exporter 'import';
 use List::Util;
@@ -30,7 +31,7 @@
 sub first {
   my ($self, $cb) = (shift, shift);
   return $self->[0] unless $cb;
-  return List::Util::first { $_ =~ $cb } @$self if ref $cb eq 'Regexp';
+  return List::Util::first { $_ =~ $cb } @$self if is_regexp $cb;
   return List::Util::first { $_->$cb(@_) } @$self;
 }
 
@@ -38,10 +39,17 @@
 
 sub grep {
   my ($self, $cb) = (shift, shift);
-  return $self->new(grep { $_ =~ $cb } @$self) if ref $cb eq 'Regexp';
+  return $self->new(grep { $_ =~ $cb } @$self) if is_regexp $cb;
   return $self->new(grep { $_->$cb(@_) } @$self);
 }
 
+sub head {
+  my ($self, $size) = @_;
+  return $self->new(@$self) if $size > @$self;
+  return $self->new(@$self[0 .. ($size - 1)]) if $size >= 0;
+  return $self->new(@$self[0 .. ($#$self + $size)]);
+}
+
 sub join {
   Mojo::ByteStream->new(join $_[1] // '', map {"$_"} @{$_[0]});
 }
@@ -91,6 +99,13 @@
   return $self->new(@sorted);
 }
 
+sub tail {
+  my ($self, $size) = @_;
+  return $self->new(@$self) if $size > @$self;
+  return $self->new(@$self[($#$self - ($size - 1)) .. $#$self]) if $size >= 0;
+  return $self->new(@$self[(0 - $size) .. $#$self]);
+}
+
 sub tap { shift->Mojo::Base::tap(@_) }
 
 sub to_array { [@{shift()}] }
@@ -246,6 +261,20 @@
   # Find all values that are greater than 5
   my $greater = $collection->grep(sub { $_ > 5 });
 
+=head2 head
+
+  my $new = $collection->head(4);
+  my $new = $collection->head(-2);
+
+Create a new collection with up to the specified number of elements from the
+beginning of the collection. A negative number will count from the end.
+
+  # "A B C"
+  c('A', 'B', 'C', 'D', 'E')->head(3)->join(' ');
+
+  # "A B"
+  c('A', 'B', 'C', 'D', 'E')->head(-3)->join(' ');
+
 =head2 join
 
   my $stream = $collection->join;
@@ -331,6 +360,20 @@
   # Sort values case-insensitive
   my $case_insensitive = $collection->sort(sub { uc($a) cmp uc($b) });
 
+=head2 tail
+
+  my $new = $collection->tail(4);
+  my $new = $collection->tail(-2);
+
+Create a new collection with up to the specified number of elements from the
+end of the collection. A negative number will count from the beginning.
+
+  # "C D E"
+  c('A', 'B', 'C', 'D', 'E')->tail(3)->join(' ');
+
+  # "D E"
+  c('A', 'B', 'C', 'D', 'E')->tail(-3)->join(' ');
+
 =head2 tap
 
   $collection = $collection->tap(sub {...});
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Mojolicious-8.22/lib/Mojo/File.pm 
new/Mojolicious-8.23/lib/Mojo/File.pm
--- old/Mojolicious-8.22/lib/Mojo/File.pm       2019-06-21 22:48:54.000000000 
+0200
+++ new/Mojolicious-8.23/lib/Mojo/File.pm       2019-07-31 17:58:31.000000000 
+0200
@@ -24,7 +24,7 @@
 
 sub basename { File::Basename::basename ${shift()}, @_ }
 
-sub child { $_[0]->new(@_) }
+sub child { $_[0]->new(${shift()}, @_) }
 
 sub chmod {
   my ($self, $mode) = @_;
@@ -94,6 +94,7 @@
 
 sub new {
   my $class = shift;
+  croak 'Invalid path' if grep { !defined } @_;
   my $value = @_ == 1 ? $_[0] : @_ > 1 ? catfile @_ : canonpath getcwd;
   return bless \$value, ref $class || $class;
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Mojolicious-8.22/lib/Mojo/JSON.pm 
new/Mojolicious-8.23/lib/Mojo/JSON.pm
--- old/Mojolicious-8.22/lib/Mojo/JSON.pm       2019-06-21 22:49:02.000000000 
+0200
+++ new/Mojolicious-8.23/lib/Mojo/JSON.pm       2019-08-12 23:51:50.000000000 
+0200
@@ -10,7 +10,7 @@
 # For better performance Cpanel::JSON::XS is required
 use constant JSON_XS => $ENV{MOJO_NO_JSON_XS}
   ? 0
-  : eval { require Cpanel::JSON::XS; Cpanel::JSON::XS->VERSION('4.04'); 1 };
+  : eval { require Cpanel::JSON::XS; Cpanel::JSON::XS->VERSION('4.09'); 1 };
 
 our @EXPORT_OK = qw(decode_json encode_json false from_json j to_json true);
 
@@ -33,7 +33,7 @@
   my $BINARY = Cpanel::JSON::XS->new->utf8;
   my $TEXT   = Cpanel::JSON::XS->new;
   $_->canonical->allow_nonref->allow_unknown->allow_blessed->convert_blessed
-    ->stringify_infnan->escape_slash
+    ->stringify_infnan->escape_slash->allow_dupkeys
     for $BINARY, $TEXT;
   monkey_patch __PACKAGE__, 'encode_json', sub { $BINARY->encode($_[0]) };
   monkey_patch __PACKAGE__, 'decode_json', sub { $BINARY->decode($_[0]) };
@@ -339,7 +339,7 @@
 
   "</script>" -> "<\/script>"
 
-For better performance the optional module L<Cpanel::JSON::XS> (4.04+) will be
+For better performance the optional module L<Cpanel::JSON::XS> (4.09+) will be
 used automatically if possible. This can also be disabled with the
 C<MOJO_NO_JSON_XS> environment variable.
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Mojolicious-8.22/lib/Mojolicious/Command/version.pm 
new/Mojolicious-8.23/lib/Mojolicious/Command/version.pm
--- old/Mojolicious-8.22/lib/Mojolicious/Command/version.pm     2019-06-21 
22:49:06.000000000 +0200
+++ new/Mojolicious-8.23/lib/Mojolicious/Command/version.pm     2019-08-12 
23:51:50.000000000 +0200
@@ -26,7 +26,7 @@
   Mojolicious ($Mojolicious::VERSION, $Mojolicious::CODENAME)
 
 OPTIONAL
-  Cpanel::JSON::XS 4.04+  ($json)
+  Cpanel::JSON::XS 4.09+  ($json)
   EV 4.0+                 ($ev)
   IO::Socket::Socks 0.64+ ($socks)
   IO::Socket::SSL 2.009+  ($tls)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/Mojolicious-8.22/lib/Mojolicious/Guides/Contributing.pod 
new/Mojolicious-8.23/lib/Mojolicious/Guides/Contributing.pod
--- old/Mojolicious-8.22/lib/Mojolicious/Guides/Contributing.pod        
2019-04-12 19:39:32.000000000 +0200
+++ new/Mojolicious-8.23/lib/Mojolicious/Guides/Contributing.pod        
2019-08-12 23:51:50.000000000 +0200
@@ -76,9 +76,13 @@
 
 An expressive title and detailed description are invaluable during the review
 process, which usually ends when members of the community have voiced their
-opinions and the core team voted for or against a change. All code changes
-should emulate the style of the surrounding code, include tests that fail
-without them, and update relevant documentation.
+opinions and the core team voted for or against a change. To reach the formal
+voting stage, a member of the core team needs to endorse the pull request and
+call for a vote. You are responsible for securing this endorsement as well as
+the required votes.
+
+All code changes should emulate the style of the surrounding code, include 
tests
+that fail without them, and update relevant documentation.
 
 While the L<Mojolicious> distribution covers a wide range of features, we are
 rather conservative when it comes to adding new ones. So if your contribution
@@ -127,12 +131,26 @@
 The installation process should be as fast and painless as possible. (Less than
 a minute on most common hardware is a good rule of thumb)
 
-The addition and modification of features is decided by majority vote or the
-pumpkin-holder.
+Any member of the core team can call for a vote to decide about the addition 
and
+modification of features (usually with a GitHub comment mentioning the team
+C<@mojolicious/core> and the C<vote> label).
+
+A feature can be added or mofified when at least 3 voting members of the core
+team have cast a vote in favour, or the pumpkin-holder overruled the vote.
+
+A vote ends once enough votes have been cast, or after 14 a day review period
+has passed.
+
+Votes for pull requests on GitHub need to be cast with the final code review
+comment and spelled out as C<+1>, C<-1> or C<neutral>. A C<+1> vote may only be
+cast in combination with an approved code review.
 
-Any core developer may nominate a new one, who must then be accepted by a 2/3
+For especially controversial decisions it is also possible to call for a
 majority vote.
 
+Any core team member may nominate new members, who must then be accepted by a
+2/3 majority vote.
+
 The pumpkin-holder has veto rights and may select their successor.
 
 It's not a feature without a test and documentation.
@@ -154,9 +172,10 @@
 Only add dependencies if absolutely necessary and make them optional if
 possible.
 
-Domain specific languages should be avoided in favor of Perl-ish solutions.
+Emulate the style of the existing code and documentation, but don't be afraid 
to
+adopt newer best practices if you can apply them consistently.
 
-No inline POD.
+Domain specific languages should be avoided in favor of Perl-ish solutions.
 
 Documentation belongs to the guides, module POD is just an API reference.
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/Mojolicious-8.22/lib/Mojolicious/Plugin/HeaderCondition.pm 
new/Mojolicious-8.23/lib/Mojolicious/Plugin/HeaderCondition.pm
--- old/Mojolicious-8.22/lib/Mojolicious/Plugin/HeaderCondition.pm      
2019-06-21 22:49:05.000000000 +0200
+++ new/Mojolicious-8.23/lib/Mojolicious/Plugin/HeaderCondition.pm      
2019-07-31 18:40:08.000000000 +0200
@@ -1,6 +1,8 @@
 package Mojolicious::Plugin::HeaderCondition;
 use Mojo::Base 'Mojolicious::Plugin';
 
+use re 'is_regexp';
+
 sub register {
   my ($self, $app) = @_;
 
@@ -13,8 +15,7 @@
 
 sub _check {
   my ($value, $pattern) = @_;
-  return 1
-    if $value && $pattern && ref $pattern eq 'Regexp' && $value =~ $pattern;
+  return 1 if $value && $pattern && is_regexp($pattern) && $value =~ $pattern;
   return $value && defined $pattern && $pattern eq $value;
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Mojolicious-8.22/lib/Mojolicious.pm 
new/Mojolicious-8.23/lib/Mojolicious.pm
--- old/Mojolicious-8.22/lib/Mojolicious.pm     2019-07-14 19:09:27.000000000 
+0200
+++ new/Mojolicious-8.23/lib/Mojolicious.pm     2019-07-31 16:18:42.000000000 
+0200
@@ -59,7 +59,7 @@
 has validator => sub { Mojolicious::Validator->new };
 
 our $CODENAME = 'Supervillain';
-our $VERSION  = '8.22';
+our $VERSION  = '8.23';
 
 sub BUILD_DYNAMIC {
   my ($class, $method, $dyn_methods) = @_;
@@ -865,14 +865,12 @@
 
 =head1 CORE DEVELOPERS
 
-Current members of the core team in alphabetical order:
+Current voting members of the core team in alphabetical order:
 
 =over 2
 
 CandyAngel, C<[email protected]>
 
-Christopher Rasch-Olsen Raa, C<[email protected]>
-
 Dan Book, C<[email protected]>
 
 Jan Henning Thorsen, C<[email protected]>
@@ -889,6 +887,8 @@
 
 Abhijit Menon-Sen, C<[email protected]>
 
+Christopher Rasch-Olsen Raa, C<[email protected]>
+
 Glen Hinkle, C<[email protected]>
 
 =back
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Mojolicious-8.22/t/mojo/collection.t 
new/Mojolicious-8.23/t/mojo/collection.t
--- old/Mojolicious-8.22/t/mojo/collection.t    2019-06-21 23:13:03.000000000 
+0200
+++ new/Mojolicious-8.23/t/mojo/collection.t    2019-07-31 20:54:52.000000000 
+0200
@@ -163,4 +163,28 @@
 # TO_JSON
 is encode_json(c(1, 2, 3)), '[1,2,3]', 'right result';
 
+# head
+$collection = c(1, 2, 5, 4, 3);
+is_deeply $collection->head(0)->to_array, [], 'right result';
+is_deeply $collection->head(1)->to_array, [1], 'right result';
+is_deeply $collection->head(2)->to_array, [1, 2], 'right result';
+is_deeply $collection->head(-1)->to_array, [1, 2, 5, 4], 'right result';
+is_deeply $collection->head(-3)->to_array, [1, 2], 'right result';
+is_deeply $collection->head(5)->to_array, [1, 2, 5, 4, 3], 'right result';
+is_deeply $collection->head(6)->to_array, [1, 2, 5, 4, 3], 'right result';
+is_deeply $collection->head(-5)->to_array, [], 'right result';
+is_deeply $collection->head(-6)->to_array, [], 'right result';
+
+# tail
+$collection = c(1, 2, 5, 4, 3);
+is_deeply $collection->tail(0)->to_array, [], 'right result';
+is_deeply $collection->tail(1)->to_array, [3], 'right result';
+is_deeply $collection->tail(2)->to_array, [4, 3], 'right result';
+is_deeply $collection->tail(-1)->to_array, [2, 5, 4, 3], 'right result';
+is_deeply $collection->tail(-3)->to_array, [4, 3], 'right result';
+is_deeply $collection->tail(5)->to_array, [1, 2, 5, 4, 3], 'right result';
+is_deeply $collection->tail(6)->to_array, [1, 2, 5, 4, 3], 'right result';
+is_deeply $collection->tail(-5)->to_array, [], 'right result';
+is_deeply $collection->tail(-6)->to_array, [], 'right result';
+
 done_testing();
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Mojolicious-8.22/t/mojo/file.t 
new/Mojolicious-8.23/t/mojo/file.t
--- old/Mojolicious-8.22/t/mojo/file.t  2019-06-05 01:05:07.000000000 +0200
+++ new/Mojolicious-8.23/t/mojo/file.t  2019-07-31 17:58:20.000000000 +0200
@@ -295,6 +295,12 @@
 is $file->stat->mtime, $future, 'right mtime';
 isnt $file->touch->stat->mtime, $future, 'different mtime';
 
+# Dangerous paths
+eval { path('foo', undef, 'bar') };
+like $@, qr/Invalid path/, 'right error';
+eval { path(undef) };
+like $@, qr/Invalid path/, 'right error';
+
 # I/O
 $dir  = tempdir;
 $file = $dir->child('test.txt')->spurt('just works!');
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Mojolicious-8.22/t/mojo/json_xs.t 
new/Mojolicious-8.23/t/mojo/json_xs.t
--- old/Mojolicious-8.22/t/mojo/json_xs.t       2019-05-31 21:28:49.000000000 
+0200
+++ new/Mojolicious-8.23/t/mojo/json_xs.t       2019-08-12 23:51:50.000000000 
+0200
@@ -4,7 +4,7 @@
 use Mojo::JSON qw(decode_json encode_json false from_json j to_json true);
 
 BEGIN {
-  plan skip_all => 'Cpanel::JSON::XS 4.04+ required for this test!'
+  plan skip_all => 'Cpanel::JSON::XS 4.09+ required for this test!'
     unless Mojo::JSON->JSON_XS;
 }
 
@@ -22,7 +22,7 @@
 
 # Basics
 my $array = decode_json '[]';
-is_deeply $array, [], 'decode_jsom';
+is_deeply $array, [], 'decode_json';
 my $bytes = encode_json [];
 is $bytes, '[]', 'encode_json';
 $array = from_json '[]';
@@ -72,4 +72,8 @@
 # "escape_slash"
 is_deeply encode_json('/test/123'), '"\/test\/123"', 'escaped slash';
 
+# "allow_dupkeys"
+is_deeply decode_json('{"test":1,"test":2}'), {test => 2},
+  'no duplicate keys error';
+
 done_testing();
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Mojolicious-8.22/t/mojo/util.t 
new/Mojolicious-8.23/t/mojo/util.t
--- old/Mojolicious-8.22/t/mojo/util.t  2019-05-31 21:28:58.000000000 +0200
+++ new/Mojolicious-8.23/t/mojo/util.t  2019-07-31 21:08:53.000000000 +0200
@@ -7,6 +7,7 @@
 use Mojo::ByteStream 'b';
 use Mojo::File 'path';
 use Mojo::DeprecationTest;
+use Sub::Util 'subname';
 
 use Mojo::Util
   qw(b64_decode b64_encode camelize class_to_file class_to_path decamelize),
@@ -486,14 +487,8 @@
 is MojoMonkeyTest::yang(), 'yang', 'right result';
 
 # monkey_patch (with name)
-SKIP: {
-  skip 'Sub::Util required!', 2
-    unless eval { require Sub::Util; !!Sub::Util->can('set_subname') };
-  is Sub::Util::subname(MojoMonkeyTest->can('foo')), 'MojoMonkeyTest::foo',
-    'right name';
-  is Sub::Util::subname(MojoMonkeyTest->can('bar')), 'MojoMonkeyTest::bar',
-    'right name';
-}
+is subname(MojoMonkeyTest->can('foo')), 'MojoMonkeyTest::foo', 'right name';
+is subname(MojoMonkeyTest->can('bar')), 'MojoMonkeyTest::bar', 'right name';
 
 # tablify
 is tablify([["f\r\no o\r\n", 'bar']]),     "fo o  bar\n",      'right result';


Reply via email to