Masteries

技術的なことや仕事に関することを書いていきます.

最近のplenv/Cartonの運用

最近のplenvとCartonの運用というか, 「こういう感じでやっていっています」という話です.

あらすじ: cpanm --installdeps .

PerlでWebアプリなど開発する場合, cpanfileに必要なライブラリを指定し, Cartonを使ってcarton installで必要なライブラリをインストールして, 開発を進めていくのが一般的だと思います.

...が, 横着な自分は大抵cpanm --installdeps .を使って, cpanfileで指定されたライブラリをそのままPerlにインストールして開発していくことが多かったのですが, 先日それで痛い目に逢いまして, 「ちゃんとCartonを使ってやっていこう」と心に誓いました.

「きれいなPerl」でCartonを使う

というわけで, コアモジュールとApp::cpanminus, Cartonだけ入った「きれいなPerl」の環境をplenvを使って用意して, これを使って開発していくようにします. また, 間違って(いつもの癖で)cpanm --installdeps .してしまわないように, 「きれいなPerl」の環境は「書き込み不可」にしてしまいましょう.

この辺りは, @tsucchi さんの 僕の perlbrew の使い方の話 - tsucchi の日記 2nd season というエントリで, Perlbrewではありますが, 似たようなことをやっていたので参考にさせて頂きました.

「きれいなPerl」環境を作る

今回は, 今日時点の最新版である5.24.0を題材にやっていきます.

$ plenv install 5.24.0 -- as 5.24-pure
$ PLENV_VERSION=5.24-pure plenv install-cpanm
$ PLENV_VERSION=5.24-pure cpanm Carton

plenv install--asオプションを付けて, 5.24.0を5.24-pureという名前でインストールします. pureは, 「きれいなPerl」という意味を持たせている... つもりです.

あとは, その環境にplenv install-cpanmでApp::cpanminusを, cpanm CartonでCartonを, それぞれインストールすれば, 「きれいなPerl」が出来上がります.

「きれいなPerl」環境をロックする

次は, cpanmでライブラリを勝手にインストールできないように, この「きれいなPerl」環境をロックしてしまいます. Macであれば, 次のようにすればOKです.

$ sudo chflags -R uchg ~/path/to/plenv/5.24-pure

「きれいなPerl」の問題点

あとは, Webアプリのルートディレクトリでplenv localなどを使い, 5.24-pureを指定すれば, 「きれいなPerl」環境の上でWebアプリの開発を進めることができます.

...が, この場合, 言うまでもなく, Minillaとか, App::PRTとか, Pod::Cpandoc::Cacheとか, こういった便利ライブラリは「きれいなPerl」では使えません(「きれいなPerl」環境にはこれらのライブラリはインストールされていないし, ロックしていて新たにインストールできないので).

cpanfileに入れて, carton exec --で動かす, という手もありますが, そういった類のライブラリはcpanfileには入れたくありません.

力で解決: carton-wrapper

解決策はいろいろありますが, 自分は別途plenvで5.24をインストールして, これにMinillaとか, App::PRTとか, Pod::Cpandoc::Cacheとか, 諸々のライブラリをインストールするようにしました. そして通常は5.24のPerlを利用するようにして, cartonコマンドを実行した場合のみ, 「きれいなPerl」, すなわち5.24-pureで動かすようにしました.

このような場合における, plenvでインストールした5.245.24-pureという複数のPerl環境の使い分けについては, こんな感じのcarton-wrapperというスクリプトを書いて, パスを通してalias carton="carton-wrapper"みたいな設定をして, 実現しています.

#!/usr/bin/env perl
use strict;
use warnings;

my $CARTON = $ENV{SCRIPT_CARTON} // "$ENV{HOME}/path/to/plenv/shims/carton";

$ENV{PLENV_VERSION} = $ENV{PLENV_VERSION_FOR_CARTON} if $ENV{PLENV_VERSION_FOR_CARTON};
exec($CARTON, @ARGV);

plenv global5.24を使うように設定した上で, Webアプリのルートディレクトリでdirenvなどを使い, PLENV_VERSION_FOR_CARTON環境変数を5.24-pureにセットします.

cartonコマンドを実行するとcarton-wrapperが呼び出されて, PLENV_VERSION_FOR_CARTON環境変数の値(例えば, 5.24-pureなど)がPLENV_VERSIONにセットされ, これによってcartonコマンドのみ5.24-pureを使って実行されるようになる, という感じです.

まとめ

ここ最近の, plenvとCartonの運用というか, 「きれいなPerl」でCartonを使う為に頑張ったアレコレについて記しました. この辺り, もっと良い方法がある気がするので, ご存知の方は是非教えて頂けるとうれしいです.