There are many modules on CPAN with a plug-in system, and all the plugins are usually in a specific name-space.

As far as I know even the Meta CPAN web site does not provide an easy way to list all the distributions in a given name-space.

Even though, using the MetaCPAN API it is quite easy to get this information.

The solution

The script which is included in the MetaCPAN-Clients distribution can provide the listing.

Let's see parts of the script:

List all the distributions under a name-space (with a given prefix)

use strict;
use warnings;
use Data::Dumper   qw(Dumper);
use MetaCPAN::API;
my $mcpan = MetaCPAN::API->new;

my $r = $mcpan->post(
    'release',
    {
        query  => { match_all => {} },
        filter => { "and" => [
                { prefix => { distribution => 'Perl-Critic' } },
                { term   => { status => 'latest' } },
        ]},
        fields => [ 'distribution', 'date' ],
        size => 2,
    },
);
#print Dumper $r;
print Dumper [map {$_->{fields}} @{ $r->{hits}{hits} }];

This query will fetch all the releases (we usually also call distributions) for which the distribution field starts with Perl-Critic and which are the latest releases of the given distribution. (This just filters out multiple versions of the same distribution.) We limit the retrieved fields to the name of the distribution and the date. (The date is not used in our example.)

The returned hash has some meta-meta data in it, so we need to got a bit deeper - two levels of 'hits' and then we get a array with more meta-data and the the fields sub-key. I left in the call to Dumper on the original hash, to make it easy for you to see what's going on.

List all the modules under a name::space (with a given prefix)

use strict;
use warnings;
use Data::Dumper   qw(Dumper);
use MetaCPAN::API;
my $mcpan = MetaCPAN::API->new;

my $r = $mcpan->post(
    'module',
    {
        query  => { match_all => {} },
        filter => { "and" => [
                { prefix => { 'module.name' => 'Perl::Critic::Policy' } },
                { term   => { status => 'latest' } },
        ]},
        fields => [ 'distribution', 'date', 'module.name' ],
        size => 2,
    },
);
#print Dumper $r;
print Dumper [map {$_->{fields}} @{ $r->{hits}{hits} }];

In this request we fetch the list of modules. In the filter we use the prefix of the module.name field. The resulting data structure is quite similar to the earlier one.

Generating HTML

It is simple to use Data::Dumper to just show the results, but it does not really look good. So in order to make it a bit easier to use the results as part of a web page, I added an extra flag --html that can generate a very simple unordered list from the distributions.

The code looks like this:

my $html = join "\n",
    map { sprintf(q{<li><a href="http://metacpan.org/release/%s">%s</a></li>}, $_, $_) }
    map { $_->{fields}{distribution} }
    @{ $r->{hits}{hits} };
print "<ul>\n$html\n</ul>\n";

The result

Running this:

perl bin/metacpan_namespace.pl --distro MetaCPAN --size 10 --html

Will generate the html that I embedded below, listing all the modules in the MetaCPAN name spaces:

Other uses

This script, or something similar could be used to provide a list of all the plugins for Perl Dancer, or Perl::Critic, or for any other module on CPAN.