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

$shibayu36->blog;

株式会社はてなでエンジニアをしています。プログラミングや読書のことなどについて書いています。

社内Cartonコードリーディング会第二回のメモ

社内Cartonコードリーディング会第一回のメモ - $shibayu36->blog; に引き続き、第二回を開催したので、その時の内容をメモしておきます。そのままメモを公開しただけなのでかなり雑です。間違ってることも多いと思います。

今回の趣旨

今回は、cpanfile.snapshotがどのように作られるのか、という点に絞ってコードリーディングをしていきました。

cpanfile.snapshotとMYMETA.json, install.jsonの関係

  • 各モジュールのMYMETA.jsonやinstall.jsonを使ってcpanfile.snapshotを作成している
  • MYMETA.json にはそのモジュールの cpanfile とか pod とかから得られそうな情報が載ってる
    • モジュール名、作者、build requires、runtime requires、test requires、etc.
  • install.json にはそのモジュールが提供するパッケージの情報が載ってる。
    • 例えば DateTime モジュールなら DateTime、DateTime::Duration、DateTime::Helpers、etc.
  • これらのファイルは誰が作っている?
    • おそらくcpanm?
  • cpanfile.snapshot の provides には install.json から得られる情報が、requirements には MYMETA.json から得られる情報が載っているっぽい?

cartonがcpanfile.snapshotに必要なモジュールを集める手順

  1. local/以下にモジュールがインストールされているはずなので、ディレクトリをrecursiveにたどり、入っているモジュールのメタデータを集める
  2. そのなかでCPAN::Meta::Requirementsなどを利用し、snapshotに利用するモジュールを抽出する

snapshotに利用するモジュールを抽出する

https://github.com/miyagawa/carton/blob/master/lib/Carton/Snapshot.pm#L134..L146 このあたりの処理がやっている

accepts_module

my $bool = $req->accepts_modules($module => $version);

...
For modules that do not appear in the requirements, this method will return true.
  • また複数versionに対する依存があった時は、条件を満たす一番最新のモジュールを選択する


以上の条件から

  • cpanfileに記述されたモジュールはsnapshotに含まれる
  • 依存の依存などの関係から複数バージョンのメタデータが見つかった場合は、cpanfileを満たすversion rangeの中で最新の物が選択される
  • ただしlocalにこれまでインストールされてしまっていて、cpanfileに書かれていないものや、cpanfileに書かれたもののさらなる依存などは、CPAN::Meta::Requirementsに登録されていないので、snapshotに含まれてしまう
    • そのため依存を消した時などはlocalを一度消してinstallし直さないと厳密なsnapshotが作れない
    • 環境によっては少しずつ違うsnapshotが出来てしまう

さらなる疑問点

  • snapshotの前段階で、carton installがどういうロジックでlocal以下にcpanモジュールを入れていくか
  • carton installのときにglobalに入っているモジュールによって、インストールされるモジュールが変わったりするのか
    • globalというのはlocal/libではなく、使っているperlのsite_perl的なとこに入っているモジュール

次回見ようと思っているところ

 次回はcarton installとcpanmの関係で、どのようなロジックでモジュールを入れていくかについて見ようと思っています。