2013-08-16 19 views
4

給定一個CPAN DIST文件(例如像Acme-Chef-1.01.tar.gz),什麼是該算法,以確定哪些模塊版本「定義」(或存在)在dist文件?從CPAN dist文件中獲取「已定義」模塊?

例如,在02packages.details.txt文件中,有四條線對應於該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 

我基本上是想知道這些線路是如何產生的。

的程序是這樣的:

  1. 找到所有的.pm文件在dist文件
  2. 負載每個.pm文件,並打印出${ "${pkg}::VERSION"}其中$pkg是對應於.pm文件的包名名(即,如果.pm文件名Foo/Bar.pm然後$pkgFoo::Bar。)

是否存在執行此索引過程的代碼?

你真的有加載模塊,以確定它的版本是什麼?

+0

它不執行模塊;只是包含$ VERSION – ikegami

+2

的行你有沒有看到[關於暫停](http://pause.perl.org/pause/query?ACTION=pause_04about)? – ikegami

回答

4

實際的代碼,它會爲暫停on GitHub here。解析包和版本聲明的子例程位於lib/PAUSE/pmfile.pm(packages_per_pmfileparse_version)中。對於CPAN的工作原理來說,這是權威性的,但它不是您想要爲自己使用的代碼 - 暫停時間已近20年,甚至在最近一次清理後仍然非常嚴重。

相反,看Module::Metadata。你給它一個文件,它提供了一個非常簡單的界面來發現該文件中的軟件包名稱以及它們的版本。

它是關於簡單:

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

事實上這種 「一個班輪」 作品:

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 

和輸出:

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

還有[Dist :: Metadata](http://metacpan.org/module/Dist::Metadata),它(大部分)只是'Module :: Metadata.'的一個包裝。根據你的需要,'Dist: :元數據'可能有一個更友好的界面。但要注意,這些工具都不會像PAUSE一樣產生一個完全**的索引。除了實現中的細微差異之外,當前的PAUSE索引依賴於之前索引的所有分佈。但是在大多數情況下,'Module :: Metadata'就足夠了。這就是[Pinto](http://metacpan.org/module/Pinto)所使用的。 –