社内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に必要なモジュールを集める手順
- local/以下にモジュールがインストールされているはずなので、ディレクトリをrecursiveにたどり、入っているモジュールのメタデータを集める
- install.jsonがあるディレクトリにMYMETA.jsonもあるので、それを利用
- https://github.com/miyagawa/carton/blob/master/lib/Carton/Snapshot.pm#L124..L131
- そのなかでCPAN::Meta::Requirementsなどを利用し、snapshotに利用するモジュールを抽出する
snapshotに利用するモジュールを抽出する
https://github.com/miyagawa/carton/blob/master/lib/Carton/Snapshot.pm#L134..L146 このあたりの処理がやっている
- accepts_moduleは http://search.cpan.org/~dagolden/CPAN-Meta-Requirements-2.125/lib/CPAN/Meta/Requirements.pm#accepts_module に委譲している
- CPAN::Meta::Requirementsのaccepts_moduleは、指定したモジュールが指定したversion rangeの中に含まれていればtrue, そうでなければfalseを返す
- ただしCPAN::Meta::Requirementsのオブジェクトに指定されていないモジュールは、このaccepts_moduleが真を返す
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が出来てしまう
さらなる疑問点
次回見ようと思っているところ
次回はcarton installとcpanmの関係で、どのようなロジックでモジュールを入れていくかについて見ようと思っています。