Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer
 
PerlMonks  

Re: What do I use to release a module to CPAN for the first time?

by davido (Cardinal)
on Oct 10, 2020 at 20:23 UTC ( #11122673=note: print w/replies, xml ) Need Help??


in reply to What do I use to release a module to CPAN for the first time?

The following is one of many ways to do it. It happens to be a pretty straightforward way. I don't recommend getting mired in other alternatives until you understand every step in this example.

  1. Understand the shape of a distribution. A distribution lives within a filesystem tree that looks like this:

    tree Foo-Bar/ Foo-Bar/ Changes .gitignore lib Foo/ Bar.pm LICENSE Makefile.PL MANIFEST README t/ 00-load.t manifest.t pod-coverage.t pod.t xt/ boilerplate.t

    The names of some of the files will differ. And in your final, shippable distribution, there will be some additional files not shown here. And there are some files above that you won't ship in the distribution, but will put into your GitHub repo (or maybe both if you want). We'll get to that in a minute.

    The crux is you need a Makefile.pl, a MANIFEST, LICENSE, README, Changes, lib/ (directory containing your module code), and t/ (directory containing your tests). "Need" is a little bit of a white lie, because you can ship a distribution without some of these files, but this is a really good starting point.

  2. Generate your distribution framework. You can do this by hand, or by copying some other similarly laid out distribution, or by using a tool such as Module::Starter, which installs a module-starter command. Let's do that:

    module-starter --author='David Oswald' --email='xxxxxx@cpan.org' --module='Foo::Bar' --eumm --license=artistic2 --genlicense --verbose --ignores=git

    This produces the following output on your display:

    Created Foo-Bar Created Foo-Bar/lib/Foo Created Foo-Bar/lib/Foo/Bar.pm Created Foo-Bar/t Created Foo-Bar/t/manifest.t Created Foo-Bar/t/pod.t Created Foo-Bar/t/00-load.t Created Foo-Bar/t/pod-coverage.t Created Foo-Bar/xt Created Foo-Bar/xt/boilerplate.t Created Foo-Bar/.gitignore Created Foo-Bar/Makefile.PL Created Foo-Bar/Changes Created Foo-Bar/README Created Foo-Bar/LICENSE Added to MANIFEST: Changes Added to MANIFEST: lib/Foo/Bar.pm Added to MANIFEST: LICENSE Added to MANIFEST: Makefile.PL Added to MANIFEST: MANIFEST Added to MANIFEST: README Added to MANIFEST: t/00-load.t Added to MANIFEST: t/manifest.t Added to MANIFEST: t/pod-coverage.t Added to MANIFEST: t/pod.t Added to MANIFEST: xt/boilerplate.t Created Foo-Bar/MANIFEST Created starter directories and files

    If you look closely, you'll see that matches the tree output I showed earlier. It created everything in the distribution tree for you. You are now done with Module::Starter. That's the extent of its involvement. If you were using Dist::Zilla (which you shouldn't be using for your first module, or maybe even your first ten modules), you would continue using it past this point. But we're using Module::Starter in this explanation, and it has finished its work.

  3. Add your module code into lib/. Hopefully your module code follows the naming convention that you used when invoking Module::Starter. Otherwise, just start over.

  4. Now you add your code tests to t/, and your author tests to xt/. While you're at it, you investigate the tests that were included automatically by Module::Starter. Some of them you may want to keep, some you may want to remove.

  5. Next you add the following two lines to your module:

    our $VERSION = '0.01'; $VERSION = eval $VERSION;

    The second line is mostly useful if you intend to use the underscore in version numbers to designate a CPAN upload as being a testing release only; '0.01_01' for example, containing an underscore, would not be indexed by the PAUSE indexer, so people wouldn't download it by mistake. Worry about that later. Read perlmodstyle for a better understanding of this.

    Remember that any time you release a module to CPAN you need to bump the version number by one.

  6. Now you run all your tests and get them passing: prove -lv

  7. Next edit Makefile.PL to add your module's prerequisites unto the PREREQ_PM hash. Add your testing prerequisites into the TEST_REQUIRES hash, and any build prerequisites (which you shouldn't need to worry about) into the CONFIGURE_REQUIRES hash. Set your MIN_PERL_VERSION appropriately. Verify everything else in Makefile.PL looks right.

  8. Add all files that you have added to your distribution manually to MANIFEST

  9. Edit README to your liking.

  10. Edit Changes to reflect the initial release of the module. See examples of how others set up their Changes file, and pick a format you like.

  11. Make your distribution:

    perl Makefile.PL make make test

    Now you have verified that the distribution, as built into a temporary blib/ folder, still passes its tests.

  12. Build a test distribution:

    make disttest
  13. Copy META.json and META.yaml out of your test distribution path (something like Foo-Bar-0.01/META.json) into your top level directory. Then remove the Foo-Bar-0.01/ directory, and add the two META.* files to your MANIFEST.

  14. Optionally, if you think you may have missed something, make manifest, though it might be worth backing up the original MANIFEST first and comparing them afterwards.

  15. Now you can make your distribution:

    make dist

    At this point you'll have a tarball that you can upload to CPAN, named something like Foo-Bar-0.01.tar.gz

  16. Upload your distribution through PAUSE. Watch the CPAN testers after a few hours to see if there are any test failures. This is why I like to start with a "development release" (a release that has an underscore in the version number); that way nobody starts downloading my module on accident before it's ready. Once you're happy with the test results, bump your version number to a non-development number, and repeat all the steps to testing and releasing the new version. This includes copying down a new version of META.* from the make disttest output.

That's it. You've spent an hour or two your first time through it, and made a few mistakes, but it's ok because you used a developer's release version number at first, and you can always delete uploads through PAUSE. Optionally, but highly encouraged, would be to put your distribution on GitHub, and to add links to the repo in the meta hash within Makefile.PL There are plenty of examples of people doing this on CPAN, so you can do some research and see how it's done. It's easy.

There have been a lot of details glossed over here; things that maybe can be done more optimally, or automated even more, but this is your first module. You should be keeping it simple at first. We could have used Dist::Zilla, and we could have used Module::Build, or another framework. But the way I enumerated here is pretty straightforward, and commonly used.

I consider the following to be required reading: ExtUtils::MakeMaker, ExtUtils::MakeMaker::Tutorial, ExtUtils::MakeMaker::FAQ, Module::Starter and perldoc module-starter, and perlmodstyle. There are a lot of other things you can read, but these are good starting points. Ignore most other options for now. Your first release is hard enough that you don't need to get distracted by a bunch of other ways to do it. You want one way; a way that allows you to see what's going on so that you can learn how the other ways streamline the process (if you can call it that; I still use the basic "by hand" approach outlined here).

One last point is whether it makes sense to upload anything at all. I would opt for keeping the distribution small; make several small stand-alone distributions rather than one kitchen sink distribution. Ask, are others going to use this? If you believe they are, upload it. If you believe only you will use it, don't. People are more likely to use small single-purpose modules that do one thing well than to use a module that provides everything you've ever written, the sum of which is only useful to your own project. But definitely, if you're providing utilities that are otherwise absent from CPAN, or that you're doing better than what's already up there, or filling a use case that isn't ideally covered already, upload.

Make this experience pleasant by taking your time to understand the process. You may be feeling the pressure of trying to rush through the learning curve. Nobody's life depends on your module getting onto CPAN, so realize that it's ok to take as long as you want, or even to never upload it. But if you do want to do this, understand that it's not only possible, but also well documented. People with less experience than you have managed it with less aptitude for it than you have. You'll get it, too. The book Intermediate Perl, 2nd Edition is sort of what I think you need for that next step in your journey with Perl and the Perl ecosystem. It contains a chapter on contributing to CPAN, that explains PAUSE, the indexer, the basic components of a CPAN distribution, and how to build one. The reading I linked to above might be "next steps" reading after spending an hour with this chapter in Intermediate Perl. But this book is good for other reasons too. I recommend it for you; the whole book. It is unfortunate that a portion of the chapter on contributing to CPAN starts you down the Build.PL path instead of the ExtUtils::MakeMaker / Makefile.PL path. It's not that Build.PL isn't great; I just wish that we could agree on teaching one way first, and by popularity the EU::MM / Makefile.PL way is the most common. Nevertheless, the explanations in the book are useful.


Dave

Replies are listed 'Best First'.
Re^2: What do I use to release a module to CPAN for the first time?
by Lady_Aleena (Curate) on Oct 15, 2020 at 18:27 UTC

    I got to step 14, but I have a mess in the directory. What do I delete and what do I keep? I uploaded the entire mess to its new repository.

    My OS is Debian 10 (Buster); my perl versions are 5.28.1 local and 5.16.3 or 5.30.0 on web host depending on the shebang.

    No matter how hysterical I get, my problems are not time sensitive. So, relax, have a cookie, and a very nice day!
    Lady Aleena

      blib/ and its subdirs are "build lib", and are throwaway. make clean will remove blib/, and will remove a few other things.

      pm_to_blib is also build output, and goes away with make clean.

      File-Slurp-Affix-0.01_01/ and its subdirs are the output of make disttest. After you've pulled out the META.* files that it provides, you can safely delete it.

      Your .gitignore should also be configured to ignore most of the generated files, except the META.yaml and META.json files that you'll pull into the top level. And if the make distcheck command is reporting files that you don't want to add to your distribution, you can set up a custom MANIFEST.SKIP (but will need to add to it the defaults that you are getting for free when that file doesn't exist).

      Don't bundle MYMETA.* with the distribution. Those are generated just in time. But META.* are useful to the CPAN indexers. I think the man\d/ directories are generated and will be removed by make clean, or make realclean, so don't bundle them.


      Dave

        I would love a few sets of eyeballs looking over what I have so far before running make dist.

        I am having a hard time finding documentation on the values in the META.yml file. I found documentation for META.json easily enough. I am specifically looking for the yml settings for the resources I have in the json file.

        "resources" : { "repository" : { "url" : "https://github.com/LadyAleena/File-Slurp-Affix", "web" : "https://github.com/LadyAleena/File-Slurp-Affix", "type" : "git" }, "bugtracker" : { "web" : "https://github.com/LadyAleena/File-Slurp-Affix/issues" }, "x_twitter" => 'http://twitter.com/Lady_Aleena', },

        Also, should I ask in a git channel or forum about how to manage versioning? Either way, I am not sure where to go after the testing release. Also, what files in the repo should I add to .gitignore? make clean cleansed the directory structure well.

        My OS is Debian 10 (Buster); my perl versions are 5.28.1 local and 5.16.3 or 5.30.0 on web host depending on the shebang.

        No matter how hysterical I get, my problems are not time sensitive. So, relax, have a cookie, and a very nice day!
        Lady Aleena

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://11122673]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others drinking their drinks and smoking their pipes about the Monastery: (4)
As of 2021-01-21 07:51 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    Notices?