The Perl::Maven project has a .perlcriticrc file in which we have an entry:

[TestingAndDebugging::RequireUseStrict] equivalent_modules = Moo Dancer [TestingAndDebugging::RequireUseWarnings] severity = 5 equivalent_modules = Moo Dancer

This tells Perl::Critic, to accept having use Moo, or use Dancer instead of having use strict; and use warnings;. That's correct, because use Dancer; indeed loads both the strict and warnings pragma.

The same is true for use Dancer2 so we also need to tell Perl::Critic to stop complaining. I added Dancer2 in the list of equivalent_modules for both entries.

With that noise out of the way it is much easier to focus on the real issues.

Which is still having use Dancer in some places as the Travis report shows.

use Dancer ':test';

The next issue I encountered were in some of the test files where I had code like this: (showing only the relevant part)

use Dancer qw(:tests); Dancer::set( appdir => getcwd() ); is Dancer::config->{'appdir'}, getcwd(), 'appdir'; is Dancer::config->{'mymaven_yml'}, 'config/mymaven.yml', 'mymaven'; use Perl::Maven; my $app = Dancer::Handler->psgi_app;

Here Dancer was loaded for testing and the appdir was set manually using the Dancer::set function. In the next line I checked if the this setting really worked (apparently the result of some failed experiments during the development), and then checking if the mymaven_yml key was found in config.yml and loaded properly. Probably these tests are not important for the application itself, they only check if the testing environment was set up correctly. Then I used the Dancer::Handler->psgi_app to fetch the PSGI application created by Dancer. In Dancer2 this code will be replaced by the following:

use Dancer2; # importing: set, config set( appdir => getcwd() ); is config->{'appdir'}, getcwd(), 'appdir'; is config->{'mymaven_yml'}, 'config/mymaven.yml', 'mymaven'; use Perl::Maven; my $app = Dancer2->psgi_app;

There is no need to add :tests to the use-statement of Dancer2 and it imports both the set and the config keywords so I don't need to prefix them any more. (I listed them after the use-statement of Dancer2 in comments just to make it easier for a reader to locate the source of these keywords.) Finally, the PSGI application created by Dancer 2 is not returned directly from Dancer2, instead of Dancer::Handler.

referer and user_agent in list context

Then I encountered an exception related to logging code inserting data into MongoDB. It complained about . not being valid part of a key in MongoDB. It boiled down to this piece of code:

my %details = ( sid => setting('sid'), time => $time, host => request->host, page => request->uri, referrer => request->referer, ip => $ip, user_agent => request->user_agent, status => $response->status, ); log_to_mongodb( \%details );

This is actually a well known and painful issue with Perl. The problem was that the behavior of request->referer and request->user_agent has changed. If they did not have a proper value, in Dancer 1 they always returned undef. Both in scalar context and in list context.

In Dancer 2 the behavior changed. In scalar context they still return undef, but in list context they return an empty list. In the above code, the right-hand-side of the fat-comma operator (=>) creates list context. This means that the empty lists were squashed, and the value of the 'referer' key became the string 'ip'. Which had a cascading effect and the content of $ip became the next key which contains the . characters the exception was about.

I have submitted a bug report, or you might call in request for clarification, but I also wanted to fix this issue in the Perl Maven codebase. (The response to my report was that the change was intentional.)

This can be done by forcing scalar context, using the scalar function:

my %details = ( sid => setting('sid'), time => $time, host => request->host, page => request->uri, referrer => scalar( request->referer ), ip => $ip, user_agent => scalar( request->user_agent ), status => response->status, );

Depending on the response to that bug report I might have to update the code later and maybe I'll need to check my whole application. I can say that it was actually lucky this happened during the migration process and not only in the production code.

public/ files

In the public/ directory of the project there were 4 files that I think are not used by the Perl Maven application: 404.html, 500.html, dispatch.cgi and dispatch.fcgi. I don't need to migrate them, but because the scripts load Dancer, I thought it would be better to get rid of them. So I temporarily switched back to the master branch of the Git repository. Removed these 4 files there. Ran the tests of the Dancer 1 version of the application and committed the changes.

Then I switched back to the dancer2 branch of the repository and rebased the branch to the new master using git rebase master.

bin/app.pl