Vector::QRCode::EPS+cartonの深淵から脱出した話
以前、EPS形式でQRコードを出力するPerlモジュールVector::QRCode::EPSを公開したが、これを利用したアプリの依存関係をcarton install --deploymentで解決しようとした際、どういうわけかTest::Simple 0.18という低いバージョンが強制的に入って来てしまうという状況に陥った。
色々調べていると、正しくインストールされているモジュールがcarton checkに怒られる時 - $shibayu36->blog;という記事を見つけ、まったく同じような状況にあることを確認。
原因
cpanfile.snapshotをよーく見てみると、以下のような箇所を発見。
PostScript-Simple-0.07
pathname: M/MC/MCNEWTON/PostScript-Simple-0.07.tar.gz
provides:
PostScript::Simple 0.07
PostScript::Simple::EPS 0.01
Test::More 0.18
Test::Simple 0.18
Test::Utils 0.02
requirements:
ExtUtils::MakeMaker 0
察しの良い方はもう理解したかもしれないが、Vector::QRCode::EPSが依存してるPostScript-Simpleが、Test::MoreをはじめとしたTest系モジュールを「なぜか」内包・提供していることになっており、結果的にこいつが内包しているTest::SimpleやらTest::Moreやらがインストールされてしまった、ということらしい。
付け焼き刃の対策
とりあえずアプリケーションをデプロイするんだ!というだけであれば、cpanfile.snapshotから、PostScript-Simpleが提供していることになっているTest::MoreなどのTest系モジュールの行を削除すれば、carton install --deployment で正しいバージョンのTest::Moreなどがインストールされる。
PostScript-Simple-0.07
pathname: M/MC/MCNEWTON/PostScript-Simple-0.07.tar.gz
provides:
PostScript::Simple 0.07
PostScript::Simple::EPS 0.01
requirements:
ExtUtils::MakeMaker 0
こんな感じ。
PostScript-Simple のどこがヤバいか
さて、PostScript-Simpleがおかしいということであれば、実際どこがマズいか気になる。とはいえ、いくら僕でももうすでにこの時点で何が悪いのか大体見当が付いていた。テストだ。
実際PostScript-Simpleのtディレクトリをみてみると、以下のような具合になっているのがわかる。
t/
├── 01base.t
├── 02text.t
├── 03funcs.t
├── 10file.t
├── 11file.t
├── 12file.t
├── 99cleanup.t
└── lib
└── Test
├── More.pm
├── Simple.pm
└── Utils.pm
もうこの時点で非常にマズいのがよくわかるのだが、t/lib/Test/More.pm などが存在しており、かつ、これらのクラスファイルは
$ head -n 1 t/lib/Test/*.pm
==> t/lib/Test/More.pm <==
package Test::More;
==> t/lib/Test/Simple.pm <==
package Test::Simple;
==> t/lib/Test/Utils.pm <==
package Test::Utils;
このようにCPANやcartonにindexされるように定義されている。
PostScript-Simpleの作者にコンタクトを試みるも・・・
さて、このPostScript-Simpleだが、最終更新が2006年と、非常に長い間メンテナンスが行われておらず、また、issueが9年間も放置されていたりと、なかなか筋金入りの放置モジュールだった模様。もっとよく確認して採用すべきだったと後悔したものの、既に遅い。
とりあえずtwitterに作者とおもわれるアカウントがあったので、念のため最悪の英語力で連絡してみる。が、これはスルーされてしまった。まあ「わけのわからん英語で何か言ってるな~、放置確定!」とでも思われたのかもしれない。
Lingrで相談
こういうときのためのLingrだろう、ということで質問してみると、「つかわなければいいです」とバッサリ。まあそりゃそうなんだけど、実際のところそうも行かないので、「まあアレなのは承知の上です」と断りを入れてみた。すると、「他のモジュール使うなりforkするといいでしょ」という話だった。
実は最初は見落としていたけど、PostScript-SimpleのライセンスはGPLv2なので、その範囲であればforkはしてよいということになる。
かくして、僕はこの「ワイルド」なモジュールをforkすることにした。
PostScript-Easy
とりあえずPostScript-Simpleを丸パクリして、名前をPostScript-Easyに変えてテストを通してみたら、問題なく通った。
次にminil migrateをした。これは、依存関係を記述するのにわざわざExtUtils::MakeMakerの流儀に則るのが億劫だったのと、後々のメンテナンス性向上のためである。
そして、あの忌々しい t/lib/Test をディレクトリごと削除し、代わりにrequires 'Test::More'をcpanfileに追記した。
最後に、Travisでテストをさせるようにしてみた。(その他、細かいドキュメンテーションの修正なども行った。)
その結果出来上がったのがこちら。
Vector::QRCode::EPS も PostScript::Easy に乗り換えた
一通り問題がなさそうだったので、PostScript::Easyをshipitし、Vector::QRCode::EPSの依存もPostScript::Easyに鞍替えして、こちらもshipitした。
PostScript::Simpleのissueもそのまま継承している状況なので、今後はこれらを潰し込む作業をする予定です。
追記: PostScript::Easyの今後について
先ほどgithub上でご教示いただいたのだが、この様な場合、まず作者へのコンタクトをとってみて、2週間を目安に待ち、それでもレスポンスがなければ、CPANに連絡をするというのが正式な方法?であるらしい。
とくにPostScript::EasyはPostScript::Simpleとは別の新しい機能を実装する予定が無い(そういったissueがあれば考慮するけど)ので、今回の話においては、本来であればco-maintなりの権限さえもらえれば解決する話である。
なので、今後ぼくがPostScript::Simpleをメンテナンスできる状況がでてきたら、PostScript::Easyはその役目を終え、CPANからも削除するつもりである。
あるいは、メンテナが正常に機能し始めた段階で、削除を考慮するだろう。