4 votes

obtenir des modules "définis" à partir d'un fichier CPAN dist ?

Étant donné un fichier CPAN dist (par exemple, comme Acme-Chef-1.01.tar.gz ), quel est l'algorithme permettant de déterminer quelles versions de modules sont "définies" (ou présentes) dans le fichier dist ?

Par exemple, dans le 02packages.details.txt il y a quatre lignes qui correspondent à ce fichier dist :

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

Je veux essentiellement savoir comment ces lignes sont générées.

Est-ce que la procédure est quelque chose comme :

  1. trouver tous les .pm dans le fichier dist
  2. charger chacun des .pm et imprimer les fichiers ${ "${pkg}::VERSION"} donde $pkg est le nom du paquet correspondant au .pm nom du fichier (c'est-à-dire que si le .pm le nom du fichier est Foo/Bar.pm puis $pkg es Foo::Bar .)

Existe-t-il un code qui effectue cette procédure d'indexation ?

Faut-il vraiment charger le module pour déterminer sa version ?

4voto

hobbs Points 71946

Le code qui le fait pour PAUSE est le suivant sur GitHub ici . Les sous-routines qui analysent les déclarations de paquetage et de version se trouvent dans lib/PAUSE/pmfile.pm ( packages_per_pmfile y parse_version ). Cela fait autorité en ce qui concerne ce qui se passe pour faire fonctionner CPAN, mais ce n'est pas un code que vous voudriez utiliser pour vous-même - PAUSE a presque 20 ans et même après un nettoyage récent, il est encore assez grossier.

Au lieu de cela, regardez Module::Metadata . Vous lui donnez un fichier, et il fournit une interface assez simple pour découvrir les noms des paquets contenus dans ce fichier et leurs versions.

C'est aussi simple que ça :

my $mm = Module::Metadata->new_from_file("My/Module.pm");
for my $package ($mm->packages_inside) {
    print "$package: ", $mm->version($package), "\n";
}

Et en effet, ce "one-liner" fonctionne :

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

et les sorties :

Acme::Chef: 1.01
Acme::Chef::Container: 1.00
Acme::Chef::Ingredient: 1.00
Acme::Chef::Recipe: 1.00

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X