読者です 読者をやめる 読者になる 読者になる

ExtUtils::Installedを使ってインストールされているモジュール一覧を得る

perl

App::cpanmigrate - search.cpan.org


のソースを見ていたら, ExtUtils::Installedを使うことで
インストールされているモジュールを知ることができるということを知りました。


ExtUtils::Installedは標準モジュールです。以下のようなワンライナーで一覧が得られます。
App::cpanmigrateで使われているものそのものです。

   perl -MExtUtils::Installed -E 'say for ExtUtils::Installed->new->modules'

サンプル

インストールされている Perlそれぞれについて、インストール済みモジュール一覧を
出力する Perlコード。強引な感じなのでシェルスクリプトで良さそうです。

#!perl
use strict;
use warnings;

use ExtUtils::Installed;
use File::Which qw(which);

use File::Spec;
use File::Path qw(make_path);

my $installed_dir = File::Spec->catfile($ENV{HOME}, 'perl5', 'modules');
main() unless caller;

sub main {
    init();
    my @perls = get_installed_perl();

    for my $perl (@perls) {
        my @cmd = ('perlbrew', 'use', $perl);
        my $status = system(@cmd);
        die "Can't exec '@cmd'" if $status != 0;

        my $output_file = File::Spec->catfile($installed_dir, "${perl}.list");
        open my $out_fh, '>', $output_file or die "Can't open $output_file";

        my @cmd2 = ('perl', '-MExtUtils::Installed', '-E',
                'say $_ for ExtUtils::Installed->new->modules');
        open my $cmd_fh, "-|", @cmd2 or die "Can't exec @cmd2";
        print $out_fh $_ while <$cmd_fh>;
        close $cmd_fh;
        close $out_fh;
    }
}
l
sub init {
    unless ( which('perlbrew') ) {
        die "Not installed perlbrew\n";
    }

    unless (-d $installed_dir) {
        make_path($installed_dir);
    }
}

sub get_installed_perl {
    my @cmd = qw{perlbrew list};

    my @perls;
    open my $fh, "-|", @cmd or die "Can't open '@cmd'";
    while (my $line = <$fh>) {
        chomp $line;
        $line =~ s{^[*\s]+}{};

        push @perls, $line unless $line =~ m{^/usr}; # remove system perl
    }

    close $fh;

    return @perls;
}