How many Perl programmers does it take to change a lightbulb?
Wait, I thought that was a hardware problem. Well, it used to be; now it's a new module to contribute to CPAN, a new web service, or maybe something not dreamed up yet. Thanks to a proliferation of inexpensive SBCs (Single Board Computers), such as Arduino and Raspberry Pi, and an amazing array of easy-to-use sensors and actuators, the lines between programming and hardware are blurring fast.
In these early days of the Internet of Things, Perl programmers have a special perspective to offer. Among its many virtues…
Before writing about the main topic, let me tell you a little bit about myself, my peers & why I am writing this blog post etc.
How I got into perl?
During my college winter vacations (dec, 2011 to jan, 2012), I was planning to learn something new. I picked up HTML/CSS (because I was quite interested in web development kind of stuff), but soon I realized that front-end stuff is not my forte & I should not spend more of my time on it. I discussed it with my brother & he suggested me to learn Perl.
I started with Beginning perl by Simon Cozens & liked it. Be…
Today, I released my second CPAN module. While writing my first CPAN module, I used Dist::Zilla for uploading my module to CPAN, but when I looked into it today, I had to go through some dzil plugins again. So, I thought that I should write a blog post about this.
Basic directory structured of the module:
Assuming, my module name is X::Y::Z, I need to create a directory with name X-Y-Z. Output of find command should look like this:
lib # all code goes in lib/ lib/X # code for X will go here lib/X/Y # code for Y will go here lib/X/Y/Z.pm # code for Z will go here t/ # all tests will go here dist.ini # explained below
For example : see this module.
Following is my dist.ini. I've pasted it below with comments for explaination.
name = Plack-Middleware-FixMissingBodyInRedirect version = 0.01 author = Upasana <firstname.lastname@example.org> license = Perl_5 copyright_holder = Upasana ; this plugin gathers all files in a dist, ; if root is not given it defaults to where dist.ini is located [GatherDir] ; this plugin will add META.yml file to the dist ; META.yml contains information related to dist like abstract, author, ; which modules are required for building & testing the dist, ; which modules are required during runtime, ; pre-requisites etc. [MetaYAML] ; for removing unwanted files, e.g. files starting a '.' [PruneCruft] ; This plugin builds Makefile.PL, that uses ExtUtils::MakeMaker ; ExtUtils::MakeMaker create a module Makefile. ; (I found this thing very lengthy & very complicated, ; I've myself not understood it well). [MakeMaker] ; will create a META.json, for replacing old style META.yml ; META.json contains same information as META.yml, but in JSON format [MetaJSON] ; adds a LICENSE file containing the full text of dist's license [License] ; adds a README file to the dist, ; citing the dist's name, version, abstract % license [Readme] ; This plugin rip apart your kind of POD & reconstructs it as old real POD ; (I really don't know the difference between the two kinds of PODs though) ; By default, it'll modify the files under: ; :InstallModules - .pm/.pod files under lib/ directory ; :ExecFiles - executable files in the distribution [PodWeaver] ; This plugin will read MANIFEST.SKIP file & ; skip all the files decalred in it, while building the dist ; My MANIFEST.SKIP contains this text: ; ^.*~$ ; because I want to skip backup files, which starts with any character, ; but ends with '~' [ManifestSkip] ; This plugin checks POD coverage of all subs, ; to indicate that some subs should be treated as covered, ; even if no documentation can be found, you can add: ; =for Pod::Coverage sub_name other_sub this_one_too. ; It generates xt/release/pod-coverage.t file [PodCoverageTests] ; for checking POD syntax [PodSyntaxTests] ; This plugin runs before a release happens, ; It'll extract to-be-released archive into a temporary directory, ; run all the tests, if tests fail then it'll abort the release, ; else it'll release the dist to CPAN & clean-up the temporary directory [TestRelease] ; This plugin checks for correct line endings in the dist ; It generates xt/release/eol.t file [EOLTests] ; This plugin allows the "dzil release" command to upload the dist ; to CPAN. It'll look for PAUSE account configuration in dist.ini ; (I would suggest to use the latter options for saving PAUSE configuration) ; or in ~/.dzil/config.ini in the following format: ; [%PAUSE] ; username = YOUR-PAUSE-ID ; password = YOUR-PAUSE-PASSWORD ; If above configuration doesn't exist, then it'll look into ~/.pause ; in the following format: ; user YOUR-PAUSE-ID ; password YOUR-PAUSE-PASSWORD ; If none of the above exists, then it'll prompt you for PAUSE credentials [UploadToCPAN] ; This plugin prompts the author whether or not to continue before ; releasing the distribution to CPAN. It gives authors ; a chance to abort before they upload. ; The default is "no", but you can set the environment variable ; DZIL_CONFIRMRELEASE_DEFAULT to "yes" if you just want to hit enter to release. [ConfirmRelease] ; This plugin will automatically extracts pre-requisties from your modules ; You can manually add pre-requisites by using Prereqs plugin [AutoPrereqs]
Releasing dist to CPAN:
After writing dist.ini, you should test & build your dist & see if everything is fine in resulted tarball. For testing & building your dist, do
dzil test --all dzil build
If everything goes well with the above commands, you can release your dist to CPAN, by doing
I've taken most of the explanation from PODs of various Dist::Zilla::Plugin::* modules.
I did an internship for Moose as part of GNOME's Outreach Program for Women. I was supposed to convert all stringy exceptions in Moose to structured exceptions or exception objects. This is my first major contribution to a FOSS project :).
This is my merged pull request (a bit late, but better late than never).
If you're interested, then you can check out diff stats here…