Subject: | custom prerequisite handling breaks automated installs |
When I try to install Net::FTPServer using 'cpan Net::FTPServer', it aborts because I don't have IO::Scalar, and instead of treating it as a normal prerequisite and pulling it from CPAN automatically, installation just dies. That means no automated install. A failing Makefile.PL is a hard error: If you do this in an interactive cpan shell, then install IO::Scalar manually, then try installing Net::FTPServer again, it will still fail because cpan doesn't even bother retrying a Makefile.PL that already failed within the same session. (So the workaround is: Install IO::Scalar manually, then quit and restart cpan.)
On the other hand, the nominally "highly recommended" (i.e. not required) BSD::Resource gets pulled it automatically, like a normal prerequisite.
This is because of the special snowflake code in https://metacpan.org/source/RYOCHIN/Net-FTPServer-1.125/Makefile.PL#L39-187, which does a hard 'exit 1' if any "required" modules are not found. This is a very bad idea. It's effectively a reimplementation of PREREQ_FATAL from ExtUtils::MakeMaker, whose documentation says:
| If this parameter is true, failing to have the required modules (or
| the right versions thereof) will be fatal. perl Makefile.PL will die
| instead of simply informing the user of the missing dependencies.
|
| It is extremely rare to have to use PREREQ_FATAL. Its use by module
| authors is strongly discouraged and should never be used lightly.
|
...
|
| Module installation tools have ways of resolving unmet dependencies
| but to do that they need a Makefile. Using PREREQ_FATAL breaks this.
| That's bad.
:-(
On the other hand, the custom code treats BSD::Resource as optional, so it doesn't abort. It does, however, list it in PREREQ_PM: https://metacpan.org/source/RYOCHIN/Net-FTPServer-1.125/Makefile.PL#L242
That's why BSD::Resource works like a normal prerequisite and gets installed as expected.
My recommendation would be to just delete that custom code. It breaks things (and is infuriatingly slow if you don't know what's going on because of all those sleep 1 / sleep 5 calls).
Optional and recommended dependencies can be handled by adding them to META.json (via https://metacpan.org/pod/ExtUtils::MakeMaker#META_MERGE).
While you're at it, https://metacpan.org/source/RYOCHIN/Net-FTPServer-1.125/Makefile.PL#L32-37 can be replaced by 'os_unsupported if $^O eq "MSWin32";' (available since ExtUtils::MakeMaker 7.27).