Archive::Any::Lite

既存のArchive::Anyがパラレルに動作させるとおかしなことになっていたので、ちょいと作ってみました。使い方はこんな感じで。

use strict;
use warnings;
use Parallel::ForkManager;
use Archive::Any::Lite;
use File::Temp qw/tempdir/;

my $pm = Parallel::ForkManager->new(5);

for my $i (1..100) {
  $pm->start and next;
  my $dir = tempdir(DIR => './tmp', CLEANUP => 1);
  my $type = qw(lib)[int(rand(1))];
  my $ext = qw(tar.gz tar.bz2 tgz zip)[int(rand(4))];

  if (my $archive = Archive::Any::Lite->new("$type.$ext")) {
    $archive->extract($dir);
    my @files = $archive->files;
  }
  $pm->finish;
}
$pm->wait_all_children;

もとのArchive::Anyはプラグインを書けばいろんなアーカイブに対応できるようになっているのですが、どうせCPAN関係のツールをつくるときにしか使わないので割り切ってCPANが対応している形式のみ対応としています。あと、内部的にはArchive::TarとArchive::Zipを使っているのですが、Archive::Tarは単純に使うと大きなtarballをまるごとメモリに読み込もうとするので、ファイルをひとつひとつ取り出すようにしてメモリの使用量を多少抑えています。/bin/tarなどを使うオプションはとりあえずなし。Archive::Anyは内部でFile::MMagicを使ってアーカイブの形式を確認しているのですが、これがどうも悪さをしているようだったので、その機能はざっくり削りました。ニーズがあれば対応している形式のみ自前でチェックするようにするかもしれません。