$shibayu36->blog;

クラスター株式会社のソフトウェアエンジニアです。エンジニアリングや読書などについて書いています。

正しくインストールされているモジュールがcarton checkに怒られる時

 今日のcarton進捗情報です。

 今日はcarton checkをしてみたら、正しくインストールされているはずなのに、versionがおかしいと怒られてしまったのでその調査をしました。

carton checkで怒られる原因

 まずcarton checkをしてみると、

$ carton check
Following dependencies are not satisfied.
  LWP::UserAgent has version 0.01. Needs 6.04
Run `carton install` to install them.

 のようにおこられました。しかし、carton installしても変化がありません。

 調べてみると、cpanfile.snapshotのTest::Mock::LWPのところに以下のような記述がされていました。

  Test-Mock-LWP-0.06
    pathname: L/LU/LUKEC/Test-Mock-LWP-0.06.tar.gz
    provides:
      HTTP::Request 0.01
      HTTP::Response 0.01
      LWP::UserAgent 0.01
      Test::Mock::HTTP::Request 0.01
      Test::Mock::HTTP::Response 0.01
      Test::Mock::LWP 0.06
      Test::Mock::LWP::UserAgent 0.01
    requirements:
      ExtUtils::MakeMaker 0
      Test::MockObject 1.08
      Test::More 0.42

 ここにLWP::UserAgentやHTTP::Requestなどが0.01として記述されているせいで、0.01がインストールされていると認識されてしまっているようです。またこのようになっている理由は、このdistributionの中で

package LWP::UserAgent;
# ...

のようにLWP::UserAgentの中身を書き換えているせいのようです。

解決法

 外からいい感じにする方法がわからなかったので、今回はこのモジュールに対してpull reqを送ることにしました。解決するにはCPAN::Meta::Specの仕様に合わせてno_indexを適切に利用するか、hide from PAUSE hackというのをするかどちらかの必要があるようです。おそらくはそれさえも平凡な日々: CPANで意図しない名前空間の取得を防ぐためになどが参考になります。

Module::Installの場合

 https://metacpan.org/module/ADAMK/Module-Install-1.06/lib/Module/Install.pod#no_index のように設定をします。今回の場合だったらMakefile.PLに以下のように記述して、

no_index package => 'HTTP::Request';
no_index package => 'HTTP::Response';
no_index package => 'LWP::UserAgent';

 そしてperl Makefile.PLします。ちなみにModule::Installには暗黙的にauthor modeというのとend user modeというのがあるようで、なんかいい感じにしないとMETA.ymlが更新されずにはまりました。make realcleanを先にやっておくといいみたいです。

$ make realcrean
$ perl Makefile.PL
$ cat META.yml # no_index packageに記述されていた大丈夫

hide from PAUSE hackする場合

 これはpackage記述の後に改行を入れておくと、providesに入らない挙動を利用したhackです。今回だったらそれぞれのところを以下の様な記述に差し替えます。

package # hide from PAUSE
    LWP::UserAgent;

minillaの場合

 ちなみにminillaの場合はminil.tomlに記述してminil releaseするだけです。簡単ですね。確認はminil dist経由で出来ます。

 minil.tomlに以下を記述。ちなみにここでno_indexを記述したい場合はdefaultのno_index directoryの記述を追加しておくほうが良いです。

[no_index]
directory = ['t', 'xt', 'inc', 'share', 'eg', 'examples', 'author', 'builder']
package = ['LWP::UserAgent', 'HTTP::Request', 'HTTP::Response']

 あとはminil distして確認してminil releaseする。

$ minil dist
$ # .tar.gzが出来るはずなので、その中のMETA.ymlを確認
$ minil release

Module::Bulidの場合

調べてないです。

まとめ

 こんなかんじで今回はちゃんと入っているはずのモジュールがcarton checkでこけた時の問題の一つを調べてみました。今のところ少し壊れているdistributionを外からなんとかする方法が見つからなかったので、pull req送って解決したりしてました。メンテナンス放棄しているモジュールとかだとどうしようもない感じもするので、何かしらうまく出来るといいですね。

ログ