CPANモジュールのアンインストール

エントリの続きはこちら→CPANモジュールのアンインストール(改良版) - ヒルズで働く@robarioの技ログ
あるCPANモジュール(以下ディストリビューションと呼びます)をアンインストールしてみます。
まずは色々紹介しながら回りくどくやってみます。最後に簡単な方法を紹介します。

消したいディストリビューションを確認

自分が消したいディストリビューションが分からなかったら、

% perldoc -tT perllocal | grep Module

# 見た目より速さ優先ならこっち
% grep Module `perldoc -l perllocal`

でインストール履歴が出ます。perllocal.podにはインストールしたディストリビューションの一覧が時刻と共に記録されていて「昨日インストールしたアレアレ…何だっけ?」という時には割と使えます。

モジュール名とディストリビューション名は一致しないこともあります。例えばApp::CLIディストリビューションは"App-CLI"ですが、App::Ackディストリビューションは"App-Ack"ではなく"ack"です(リンク先のヘッダ部分に注目)。

ディストリビューション名が分からなければ、上記のようにCPAN Seachを使ったり、

% cpan -D モジュール名

% cpan
cpan> i モジュール名

% perl -MCPAN -MData::Dump=dump -e 'dump CPAN::Shell->expand(Module=>"モジュール名")'

で出てくるファイル名を見ると分かります。

ビルドディレクトリへ移動

% cd ${build_dir}/ディストリビューション名-バージョン番号-もにゅもにゅ/

でビルドディレクトリへ移動します。

${build_dir}はデフォルトでは ${HOME}/.cpan/build/ ですが、

% grep build_dir `perldoc -ml CPAN::Config`

CPANの設定から確認できます。


ビルドキャッシュの関係から、該当するビルドディレクトリが無い場合があります。(なお、筆者はscan_cacheを'never'にして全部残しています。)

そういう時は

% cpan
> look モジュール名

とすればビルドディレクトリを作成してそこに移動してくれます。
また、この方法だとディストリビューション名が分からなくてもモジュール名から勝手に探してくれるので楽チンです。

アンインストール

Makefileが無い場合は

% perl Makefile.PL

Makefileを作成します。そして

% make uninstall

# 間違ってvendor_perl/に入れちゃった!って時に使うための make uninstall_from_vendordirs というのもあります。

とすると

Uninstall is unsafe and deprecated, the uninstallation was not performed.
We will show what would have been done.

unlink ...
unlink ...
unlink ...

Uninstall is unsafe and deprecated, the uninstallation was not performed.
Please check the list above carefully, there may be errors.
Remove the appropriate files manually.
Sorry for the inconvenience.

と出ます。これは実際にはアンインストールされません(後で説明します)ので、「unlink ...」を全てコピペ実行します。

ディレクトリは残ってしまうので、手作業でチマチマ消すとか、
find使うとか

% find /usr/lib/perl5/site_perl -depth -type d -exec rmdir {} \;

perl使うとか

% perl -MFile::Find -e 'finddepth({wanted=>sub {`rmdir $_` if -d}, no_chdir=>1}, "/usr/lib/perl5/site_perl");'

して消します。



色々面倒くさいことをしましたが、結局ファイルの一覧を取得してそれらを消せば良いだけなので、もっと簡単にできます。

上記のmake uninstallした時に「unlink ...」が出てきましたが、それはExtUtils::Command::MM#uninstallが.packlistというファイルに書かれているものを出しているだけなのです。
インストールされているディストリビューションの.packlistは、以下の場所に格納されています。

% perl -MConfig -e 'print "$Config{sitearchexp}/auto/$FULLEXT/.packlist"'

ここで$FULLEXTは「ディストリビューション名 =~ s{-}{/}」したやつです。

で、ExtUtils::Command::MM#uninstallはmake uninstallした時に見たように、.packlistを渡しても表示するだけで実際に削除してくれません。しかしExtUtils::Install#uninstallを使えば削除までしてくれるのです。

# ExtUtils::Install#uninstall($packlist_file, $verbose, $dont_execute)

# 確認だけ
% perl -MConfig -MExtUtils::Install -e '($FULLEXT=shift)=~s{-}{/}g;uninstall "$Config{sitearchexp}/auto/$FULLEXT/.packlist", 1, 1' ディストリビューション名

# 本当に削除
% perl -MConfig -MExtUtils::Install -e '($FULLEXT=shift)=~s{-}{/}g;uninstall "$Config{sitearchexp}/auto/$FULLEXT/.packlist", 1' ディストリビューション名

これを cpan-uninstall とかで実行できるようにしておくと簡単ですね。

alias cpan-uninstall='perl -MConfig -MExtUtils::Install -e '"'"'($FULLEXT=shift)=~s{-}{/}g;uninstall "$Config{sitearchexp}/auto/$FULLEXT/.packlist",1'"'"