Any CPAN author has to interact with PAUSE, the website you go to to upload files if you want to publish your work on CPAN. There is no API provided, so you have to use a browser to upload files manually.

Well, not really. There are some modules you can use, like CPAN::Uploader to upload files or WWW::PAUSE::CleanUpHomeDir to delete old releases in your PAUSE home directory. And if you use Dist::Zilla, by default you will use CPAN::Uploader when you release your distribution, so you don’t have to go to PAUSE manually. These modules all work by scraping the website since, like it is said above, there is no API.

WWW::PAUSE::Simple is another module you can use which: 1) provides more functions (aside from uploading, currently can also list/delete/undelete/reindex files, as well as list distributions and cleanup older releases, more functions will be added in the future); 2) comes with a handy CLI utility called pause (distributed in App::pause) to do everything via the command-line.

To use this utility, first install the CPAN module:

If you want the Perl API (module):

% cpanm -n WWW::PAUSE::Simple

If you want the CLI:

% cpanm -n App::pause

After that, configure it by creating a file ~/pause.conf (or ~/.config/pause.conf ):

username=(your PAUSE ID) password=(your password)

and you’re ready to go.

Uploading files. To upload some files:

% pause upload *.tar.gz

This is the subcommand I use most often. Even though I use Dist::Zilla daily, there are routinely times when I need to upload manually, for example when I develop on my laptop in places with no or flaky Internet connection. I still do the releases, but skip uploading to CPAN. Later when Internet connection is available again, I upload the tarballs using pause .

To see log/debug messages as each file is uploaded, give it a --debug option.

This utility is very much similar to the cpan-upload script provided by CPAN::Uploader, except by default pause will continue to the next file when uploading a file fails, instead of bailing out (cpan-upload can already behave like this now, by using the new --ignore-errors option).

Listing files. Simple enough:

% pause ls

% pause ls -l

You can also give it some wildcard arguments to match the files. But since matching is done by the script to match files on the server, you have to quote the wildcards to prevent them from being expanded by the shell to match files on your local directory:

% pause ls -l 'App-*'

Since some files can also be scheduled for deletion if they have been recently deleted, you can filter whether you want to see these files or not via --nodel . To see only files scheduled for deletion, use --del .

Deleting files. Also using subcommand familiar to Unix fans:

% pause rm 'App-*' '*TRIAL*'

% pause rm '*'; # delete everything!

Again, you should quote your wildcard arguments to protect them from being accidentally expanded by the shell.

When deleting files on PAUSE, the files are not actually deleted immediately but instead put into a schedule of 72 hours. During this period, you can cancel your deletion instruction by using the undelete subcommand:

% pause undelete '*'; # bring back everything

Once the period expires, the files will actually be deleted and cannot be recovered anymore on PAUSE. (They are still available on BackPAN though, so you can upload them again to PAUSE if you want to.)

Reindexing files. Sometimes you have to reindex your files so it can appear on the indexes (02packages.details.txt.gz et al). For example, if you happen to lack permission during the first upload (you were not yet given a co-maint status for a module). Or sometimes the PAUSE indexer does choke up. This happens to me once or twice, usually because I upload too many files at once causing the SQLite database to get locked and the indexer to fail. To do this:

% pause reindex 'App-*'

% pause reindex '*'; # reindex everything!

Cleaning older releases. I’ve used WWW::PAUSE::CleanUpHomeDir for a few years, but since I’ve written pause last month, I thought why not add this functionality too into the tool. So:

% pause cleanup

will delete older releases on your PAUSE home directory. Trial/dev releases are skipped. There is an option -n to let you specify how many old versions you want to keep for each distribution. The default is 1, meaning to only keep the latest version.

I now do this routine every week or so to keep my home dir clean.

The other stuffs. I also plan to add subcommands for other PAUSE functionality, like changing password, setting forwarding email, and setting permissions. But since I do this very seldomly, I haven’t bothered to add them yet.

Dry-run mode. Some subcommands, especially those which can modify your files like rm and reindex , have a --dry-run option to let you try without actually do the action. They only will show the files that will be affected. Useful particularly if you use wildcards or with the cleanup subcommand.

Tab completion. pause comes with tab completion feature under Unix shells, which you can activate via complete -C pause pause (or via shcompgen, see the manpage for more details).

I haven’t tested this under Windows, please drop me a message if things don’t work as advertised.

But what about the API? Aside from the CLI, WWW::PAUSE::Simple is the module you can use from Perl directly. For example:

use WWW::PAUSE::Simple qw(list_dists); my @dists = list_dists(username=>"your PAUSE ID", password=>"your pass");

Couldn’t be simpler.

Additional reading