Sometimes, we need to deploy non-Perl files alongside a distribution. For that, we have File::ShareDir and its friends, which are lovely. But alas, as the installation of the shared files follows the same rules as the installation of module files, it has the same weakness: Upon installation, CPAN clients will install files, but won’t remove any that aren’t relevant anymore.
That means that if, for example, version 1.0 of the distribution was having
and version 1.1 changed that to
then a user installing first version 1.0 then 1.1 will end up with
share/foo share/bar share/baz
which, depending on what you’re using these files for, might be a problem.
Let’s be sneaky
Fortunately, there is a clever little workaround for when you don’t want the files of past distributions to linger around. The trick is simple: Bundle all the files to be shared into a tarball called shared-files.tar.gz. Since there is now only that one file, which always keeps the same name, any new installation is conveniently clobbering the old version.
But that’s WORK!
Manually archiving the content of the share directory before any release is no fun. So I wrote Dist::Zilla::Plugin::ShareDir::Tarball which, upon the file munging stage, gathers all files in the share directory and builds the shared-files.tar.gz archive with them. If there is no such files, the process is simply skipped.
Basically, adding this one plugin in the dist.ini of a project is all that is required on the package generation side. On the other end, you will be able to access that tarball the regular way:
use File::ShareDir qw/ dist_dir /; my $tarbar = dist_dir('My-Dist').'/'.'shared-files.tar.gz';
So I have to extract the tarball? But that’s work too!
Well, okay, fine. If there’s something I can understand, it’s laziness. That’s why I also wrote File::ShareDir::Tarball, which aims to behave exactly like good ol’
File::ShareDir, but with some added magic. It’ll automatically extract the tarball for you, and return the path to the resulting extracted directory. So all you would need to do is:
use File::ShareDir::Tarball qw/ dist_dir /; my $dir = dist_dir('My-Dist');
File::Sharedir::Tarball only accepts
dist_dir() because, well, Elementary is starting in 10 minutes, but that’s nothing I can’t solve in the next 15 minutes if I feel mildly bored.
In the meantime, enjoy. :-)
Leave a Reply