The actual code that does this for PAUSE is on GitHub here . Routines that parse package and version declarations are located in the lib / PAUSE / pmfile.pm folder ( packages_per_pmfile and parse_version ). This is authoritative as far as CPAN does, but it is not the code that you would ever want to use for yourself - PAUSE is almost 20 years old, and even after a recent cleanup it is still pretty rude.
Instead, check out Module :: Metadata . You give it a file, and it provides a fairly simple interface for detecting package names inside this file and their versions.
It is about as simple:
my $mm = Module::Metadata->new_from_file("My/Module.pm"); for my $package ($mm->packages_inside) { print "$package: ", $mm->version($package), "\n"; }
And really, this "one-line" works:
find Acme-Chef-1.01 -name \*.pm \ | perl -MModule::Metadata -ln \ -e 'my $mm = Module::Metadata->new_from_file($_); ' \ -e 'print "$_: ", $mm->version($_) for $mm->packages_inside' \ | sort
and outputs:
Acme::Chef: 1.01 Acme::Chef::Container: 1.00 Acme::Chef::Ingredient: 1.00 Acme::Chef::Recipe: 1.00
source share