Introducing Platform
So, what's the big idea?
Perl projects have all manner of ways of declaring their dependencies. CPAN releases usually include a file called META.yml or META.json listing their dependencies (though Makefile.PL or Build.PL is also supposed to generate a list of dependencies when it runs; this allows the release to dynamically decide on different dependencies based on the machine it's running on). Non-CPAN projects can declare their CPAN dependencies using cpanfile too.
Once the dependencies are declared, this information is used by CPAN clients, by metacpan.org (to show the list of a release's dependencies), by http://deps.cpantesters.org/ and so on.
However, this only works where you want to declare dependencies on CPAN modules, or on a minimum version of Perl itself.
There's another few important types of dependency - your project may depend on external libraries or binaries, or may depend on a particular platform (e.g. code that only works, or only makes sense to use on Windows).
For external libraries, there is good work going on in the Alien namespace on CPAN. And it seems reasonable to extend this approach to binaries.
For platforms, the solution to this has often been to include code in Makefile.PL to check $^O
looks OK and die otherwise:
die "Windows only!" unless $^O eq "MSWin32";
However, this approach doesn't leave any indication of the required platform in META.yml; it's invisible to services performing automated analysis of CPAN; metacpan.org's dependency listings won't show it.
The Platform namespace is designed as a solution to these issues.
What is in the Platform namespace?
Initially three releases. The first is Platform itself - a documentation-only release explaining the concept.
The next is Platform::Unix. This is a module that doesn't "do" anything, but will only install and only run on Unix-like platforms. So if your Perl project requires a Unix-like OS, just add a dependency on Platform::Unix, and Bob's your uncle. Having Platform::Unix listed in your META.yml and on your metacpan.org page makes it really explicit to your users that your release requires a Unix-like operating system.
The third release is Platform::Windows which is much the same thing for Windows.
Any more planned?
No, but if you have any requests, let me know. I've got a template for building new Platform releases in the Platform repository.
Nice trick. And a long time coming.
It looks like you would only be able to have a single Platform::Whatever requirement. What do I do to say "I can run on Platform A or Platform B"?
Adding to Andy's question... How would you indicate that it works on *nix and cygwin? I think you'll want Platform::Windows::MSWin32 and Platform::Windows::Cygwin.
It's about the same as saying "I can run with LWP::UserAgent or HTTP::Tiny". (i.e. not pretty.)
With Module::Install that would be something like:
If you thought it was a relatively common combination of platforms to support (e.g. Linux, BSD, Solaris, Darwin and Windows) you could create your own Platform::NotSomethingWeird release, and depend on that.
In related modules, there is also Devel::AssertOS and its Dist::Zilla plugin.
So is there any work already done on the external binaries side? I'm writing a module that uses an external hg (there don't seem to be production-ready modules on CPAN to talk to a local Mercurial binary, or they're all read-only) and I'd like the installation to fail if there isn't a usable "hg" binary, with a suitable warning.
You could take a look at GETTY's Alien::ffmpeg and Alien::mpg123.
These distributions will actually build the relevant binary and stash it somewhere in @INC. You can then query the module to get the path to the binary.
Of course you might want to be able to use "hg" found in the user's $PATH if it exists, and only fall back to compiling your own. But there are some advantages to building your own - you can rely on a known version of "hg"; and you can rely on "hg" actually being Mercurial, and not some other random binary that just happens to be called "/usr/bin/hg".
Those aren’t just related, Yanick, they are the right approach. This Platform::* stuff does not appear particularly well thought out to me.
I should mention. Getty is taking my Alien::Base module further than it is intended in applying it to executables. I have warned him explicitly that I may change things that might break what he is doing, so on his head be it. I DO hope to add executable support to Alien::Base, but it hasn't been given much thought yet, and it will need MUCH thought to do it right (though hopefully less than dynamic libraries have needed).
Instead of having a hard-coded list of osnames you might want to rely on Perl::OSType. Though as Mr. Muskrat said there are some tricky bits such as cygwin.
I think this would be better indicated as metadata, rather than as a placeholder module.