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

はむはむエンジニアぶろぐ

このブログのコンセプトは"ハッキングの為なら愛する家族を傷つけることをいとわない" 自分にとってエンジニアリングは "手段ではなく生きる目的" である

Comporserのバージョン指定にdev-masterしてるけど大丈夫なの?

f:id:secret_hamuhamu:20160421000612j:plain
Comporserでライブラリをインストールをする際にバージョンを指定できます。
というより、今後も安定して使いたいのであればバージョンを指定してインストールしたほうが良いと思います。
なんでもかんでも、最新版がいいと思い込んでいる人はバージョン指定に dev-master を指定します。
ほんとに、 dev-master 使って大丈夫なのか検証してみた。

dev-masterとは?

masterブランチのことで、comporser.jsonのバージョニングに指定するとmasterの最新コミット(Packgistに同期されている)で取り込みます。
ということは、バージョニングされる前の最新機能が実装されているが不安定なものをインストールすることになります。

セキュリティホールになるかもしれないし、バグっているかもしれません。

検証してみた

hamuhamu/composer_dev-master_test
Packagistにライブラリを公開しました。

composer_dev-master_testを dev-master でcomporser install。

  • comporser.json
{
    "require": {
        "hamuhamu/composer_dev-master_test": "dev-master"
    }
}


検証コードなので適当です。
最新コミット番号が 0387c8f だとしてcomposer_dev-master_test/A.phpを利用します。

<?php

require_once 'vendor/hamuhamu/composer_dev-master_test/A.php';

$a = new A();
$a->test();
// composer_dev-master_testと出力される

バグなく利用できました。


では、バグを埋め込んでコミットしましょう。
ライブラリ側のコードから必要なセミコロンを削除しました。
最新コミット番号が 7e43ade になります。

composer update をします。

<?php

require_once 'vendor/hamuhamu/composer_dev-master_test/A.php';

$a = new A();
$a->test();
// Parse error: parse error, expecting `','' or `';'' と出力される

はい、バグりました。
バージョン指定に dev-master を指定しているとこのようなことが起きます。
怖いですね。
お仕事で使っているコードなら安心して夜も眠れません。

もうすでにdev-master使って運用してるんだけど?

そのまま dev-master を使い続けるのはナンセンスです。
対象のライブラリを使っているテストコードがあるのであれば、直近のメジャーバージョンに戻してしまったほうが良いかと思います。
テストが落ちなければバージョン固定でcomporser.jsonを書きなおせばいいと思います。

テストもねーよ糞が!!って場合は、どこまで戻して大丈夫かわかりません。
目視のE2Eテストで網羅できるのであればそれでよし。
そうでないのであれば、 dev-master にコミット番号を指定します。
バグが発生する前のコミット番号を指定。

  • comporser.json
{
    "require": {
        "hamuhamu/composer_dev-master_test": "dev-master#0387c8fc9dcffd247a8d12dfeaf884c02db08c74"
    }
}


この状態でcomposer updateします。

$ composer update

Loading composer repositories with package information
Updating dependencies (including require-dev)
  - Updating hamuhamu/composer_dev-master_test dev-master (7e43ade => 0387c8f)
    Checking out 0387c8fc9dcffd247a8d12dfeaf884c02db08c74

Writing lock file
Generating autoload files


プログラムを実行してみる。

<?php

require_once 'vendor/hamuhamu/composer_dev-master_test/A.php';

$a = new A();
$a->test();
// composer_dev-master_testと出力される

バグが発生する前に戻りました。


もうすでに dev-master で運用されているのであれば、composer.lockに書いてあるコミット番号を使えば良いと思います。
パッケージごとにreferenceというキー名でコミット番号が書いてあります。

  • composer.lock(一部抜粋
    "packages": [
        {
            "name": "hamuhamu/composer_dev-master_test",
            "version": "dev-master",
            "source": {
                "type": "git",
                "url": "https://github.com/hamuhamu/composer_dev-master_test.git",
                "reference": "7e43ade7dc85ffb64ab7ba949ef2bd0dc1647e8d"
            },

コミット番号指定は苦肉の策なので、テストを書いたらバージョン指定にするのが良いと思います。

dev-masterを仕事で使わないこと

dev-master は、仕事では使ってはいけません。

じゃあ、 dev-master 何のためにあるの?というと、暫定的な実装を多くの人に共有するためです。
バージョニングされるまでの間は、暫定的な実装案でありライブラリの作者がライブラリを扱うユーザからヒアリングをもらうための期間です。
その期間中にライブラリの作者は、ライブラリをブラッシュアップします。

いきなりバージョニングしてリリースしてしまうと後で変更することが難しくなります。
例えば、ライブラリを扱うユーザが目にするインターフェースであるメソッドシグネチャをリリース後に変更してはいけません。
これまで動いていたコードが動かなくなります。

どうしても変更せざる得ない場合は、Deprecated警告でユーザに告知するなど対応が必要です。

まとめ

  • dev-master は、仕事では使わない
  • プライベートは、積極的に dev-master を使いライブラリ作者にPRやissueで提案しよう
  • ツールはちゃんと理解して使おう