Help us understand the problem. What is going on with this article?

セマンティック・バージョニングと、Gemfileのバージョン指定方法 - Gemfileでよく見る`~>`を使いこなす

More than 5 years have passed since last update.

ライブラリを使う時、バージョンが合わなくてうまく動かないという問題は、Rubyに限らず、どのプログラミング言語でも常に悩みの種である。特にDepedencyの多いライブラリをインストール/インクルードするときは、大体この問題で躓く。C++とかでGUI関係のライブラリを入れるときは何度も挫折したし、特に、進化が速く変更の多いPerl,PHPをはじめとしたスクリプト言語では普通にそういう問題に出くわす。

もちろんRubyもその例外ではないのだが、より個人がライブラリ(gem)を作って、githubなどに上げ、公開していくという文化がある割に、あまりこの問題に悩まされないので、Ruby(on Rails)は比較的うまくやっていると思う。

これは、Bundlerというツール自体の功績でもあるけれど、ライブラリを作る個人個人が、ちゃんと一定の規則に従ってバージョン付けして、依存関係を正しくGemfileに書くという文化によるものが大きいと思う。なので、Bundlerを支える文化のセマンティック・バージョニングと、Gemfileの書き方について紹介しようと思う。

今回は、AdventCalendarということで、あんまりRubyを使わない人にも参考になるテーマで書いてみたつもり。
他言語プログラマでも、特に、自分でライブラリを作ってみようかなと思っている人は絶対に知っておくべき。

Semantic Versioning (バージョン付けの規則)

バージョンには付け方があり、基本的にはこの法則に従うべきというガイドラインが存在する。
ちゃんと意味のあるバージョン付けをしましょうということなのだが、それが、Semantic Versioningという名前で以下のURLで公開されている。
http://semver.org/
http://shijimiii.info/technical-memo/semver/ (日本語訳)

ここでは、3.2.8のように、バージョンを常に3つの数字を.で区切った方法(X.Y.Z形式)で、指定する方法のみ説明する。なお、上のURLには1.0.0-alpha.11.3.7+build.11.e0f985aなどのより細かい規則も載っている。

Semantic Versioningの大原則

まず、大原則として以下のルールに則る。

公開APIを定め、それを基にバージョンを付ける。

Semantic Versioningの詳細ルール

あとは、3桁それぞれに意味を持たせ、以下のルールに従ってバージョン付けする。

  • すべての公開される変更でバージョンを上げる
  • 3つの数字X.Y.Zの意味はそれぞれMajor.Minor.Patch
  • Majorをあげるときは後方互換のない変更
    • 新しいAPIの公開など
  • Minorをあげるときは後方互換のある変更
    • APIの追加、サポートを外そうとしているAPIに警告を出すなど
  • Patchをあげるときはバグ修正
    • バグ修正の定義は、正しくない挙動を直すこと
  • 安定した公式APIが定まるまでは、0.y.z形式にしておき、この状況では例外的にいつAPIを変えても良い

ちなみにバージョンは少数ではないので、1.101.91.10の方が新しいバージョンである。

具体例

バージョン付けの例としては、以下のような流れになる。

0.0.1  # Initial Version
0.0.2
0.1.0  # 0.0.2と比べて機能が大きく変わった。

1.0.0  # 多分Stableであろう、公式APIを定めた!

1.0.1
1.0.2
1.0.3
…
1.0.9
1.0.10
1.0.11
…
1.0.17  # バグだらけでいろいろ修正

1.1.0   # 追加APIを導入。ついでにバグも修正(Minorをあげるのと同時にバグ修正してもOK)

2.0.0   # 過去のしがらみを断ち切り、リニューアルしたAPIを公開

GemfileでのVersion指定の仕方

例えばhogeという名前のgemがあったとする

安全に今のバージョンのみ使いたい場合

Gemfile
gem "hoge", "2.1.8"  # 2.1.8のみ使う

今後のバグ修正のみ受け入れたい場合

基本は、後方互換のある修正はすべて受け入れればよいので数字を2つだけ書いて指定する。

Gemfile
gem "hoge", "~> 2.1"  # 2.1.0以上3.0.0未満の最新のものを使用

例えばdeviseなどの大き目のgemだったり、なんだかんだでバグ修正以外の機能追加が入ると動かなくなりそうというようなものは数字3つで指定しておく。ちゃんとガイドラインにしたがって運用されていて、公開APIが変わってなくても、推奨されるディレクトリ構成だったり、設定の仕方だったりが変わるというのもありえる。

Gemfile
gem "hoge", "~> 2.1.8"   # 2.1.8以上2.2.0未満の最新のものを使用

今後の変更は全て受け入れ最新に追従したい場合

基本は、以下のように何も指定しないでOK

Gemfile
gem "hoge"

公開するgemなどを作っていて、見知らぬユーザーの環境に古いhogegemが入っていると困るなどという場合は以下のように>=を使う。

Gemfile
gem "hoge", ">= 2.1.3"  # 2.1.3以上の最新のものを使う

2.1.3の部分は頑張って自分の書いたものがhogegemのどのバージョンからなら動くかを調べて埋める。">= 2.1"かもしれないし、">= 1"かもしれない。

参照

http://gembundler.com/gemfile.html

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away