Reputation: 52039
Given a CPAN dist file (e.g. like Acme-Chef-1.01.tar.gz
), what is the algorithm to determine what module-versions are "defined" (or present) in the dist file?
For instance, in the 02packages.details.txt
file, there are four lines which correspond to this dist file:
Acme::Chef 1.01 S/SM/SMUELLER/Acme-Chef-1.01.tar.gz
Acme::Chef::Container 1.00 S/SM/SMUELLER/Acme-Chef-1.01.tar.gz
Acme::Chef::Ingredient 1.00 S/SM/SMUELLER/Acme-Chef-1.01.tar.gz
Acme::Chef::Recipe 1.00 S/SM/SMUELLER/Acme-Chef-1.01.tar.gz
I basically want to know how those lines are generated.
Is the procedure something like:
.pm
files in the dist file.pm
files and print out ${ "${pkg}::VERSION"}
where $pkg
is the package name corresponding to the .pm
file name (i.e. if the .pm
file name is Foo/Bar.pm
then $pkg
is Foo::Bar
.)Is there code which does this indexing procedure?
Do you really have to load the module in order to determine what its version is?
Upvotes: 4
Views: 73
Reputation: 239871
The actual code that does it for PAUSE is on GitHub here. The subroutines that parse package and version declarations are in lib/PAUSE/pmfile.pm (packages_per_pmfile
and parse_version
). This is authoritative as far as what happens to make CPAN work, but it's not code that you'd ever want to use for yourself — PAUSE is almost 20 years old and even after some recent cleanup it's still pretty gross.
Instead, look at Module::Metadata. You give it a file, and it provides a pretty simple interface to discover the names of the packages inside of that file and what their versions might be.
It's about as simple as:
my $mm = Module::Metadata->new_from_file("My/Module.pm");
for my $package ($mm->packages_inside) {
print "$package: ", $mm->version($package), "\n";
}
And indeed this "one-liner" 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
Upvotes: 4