Memento memo.

Today I Learned.

Gemfileとpackage.jsonでみるバージョン指定の読み方

Semantic Versioning 2.0.0

セマンティック・バージョニング(SemVer)によると

バージョンナンバーは、メジャー.マイナー.パッチとし、バージョンを上げるには、

  • APIの変更に互換性のない場合はメジャーバージョンを、
  • 後方互換性があり機能性を追加した場合はマイナーバージョンを、
  • 後方互換性を伴うバグ修正をした場合はパッチバージョンを上げます。
  • プレリリースやビルドナンバーなどのラベルに関しては、メジャー.マイナー.パッチの形式を拡張する形で利用することができます。

SemVerはバージョニングのルールみたいなものですね。

Gemfile(Ruby)やpackage.json(Node.js)等で依存関係を記述する時、 チルダ(~)やキャレット(^)を使って指定するかと思いますが、自分の中での解釈が曖昧だったのでまとめます。

Gemfile

Rubyの場合は ~> の記法が使われます。

これはpessimistic operator(悲観的バージョン演算子)というそうです。

解釈は以下のようになります。

  • 指定バージョンの一番右の数字を取り除く
  • 次に、一番右の数字をインクリメントしたものを上限とする
# e.g.
gem 'hoge', '~> 5.1.1'
# 次と等価
gem 'hoge', '>= 5.1.1', '< 5.2.0'

参考: Ruby's Pessimistic Operator

package.json

package.jsonではチルダ(~)とキャレット(^)を使います。

参考: semver | npm Documentation

Tilde Ranges

Allows patch-level changes if a minor version is specified on the comparator. Allows minor-level changes if not.

とのことで

  • 基本的にはマイナーバージョンまで固定
  • マイナーバージョンが指定されてない場合はメジャーバージョン固定

です。

e.g.
~1.2.3 := >=1.2.3 <1.(2+1).0 := >=1.2.3 <1.3.0
~1.2 := >=1.2.0 <1.(2+1).0 := >=1.2.0 <1.3.0
~1 := >=1.0.0 <(1+1).0.0 := >=1.0.0 <2.0.0

Caret Ranges

Allows changes that do not modify the left-most non-zero digit in the [major, minor, patch] tuple. In other words, this allows patch and minor updates for versions 1.0.0 and above, patch updates for versions 0.X >=0.1.0, and no updates for versions 0.0.X.

  • 基本的にはメジャーバージョン固定(メジャーバージョンが0でない場合)
  • メジャーバージョンが0の場合マイナーバージョン固定
  • メジャー・パッチバージョンが0の場合はアップデートしない
^1.2.3 := >=1.2.3 <2.0.0
^0.2.3 := >=0.2.3 <0.3.0
^0.0.3 := >=0.0.3 <0.0.4

大抵の場合はメジャーバージョン固定のCaret(^)指定で問題ないかと思います。