pubspec.yamlの「^2.4.0」はどういう意味か?【caret syntaxについて解説】

Flutter

こんにちは、教育系エンジニアのひらまつ(@hiramatsuu)です。

ひらまつの簡単な自己紹介

書籍「ゼロからわかる Linuxコマンド200本ノック(技術評論社)」の著者。Udemy受講者8万人。
プログラミング教育をメインに活動するエンジニアとして、動画教材の作成・技術書の執筆・学習アプリの開発などを行なっています(詳しくはこちら)。

本記事では、pubspec.yamlにおけるバージョンの範囲の指定方法について解説します。

version constraints(バージョン制約)の2つの記法

pubspec.yamlにおいて、互換性のあるバージョンの範囲を指定する方法には、

  • traditional syntax(以下の例のsdkの値部分)
  • caret syntax(以下の例のflutter_native_splashの値部分)

の2つがある。

environment:
  sdk: '>=3.0.0 <4.0.0'

dependencies:
  flutter_native_splash: ^2.4.0

traditional syntax(トラディショナルシンタックス)

  • 「>」や「=」などの記号を使って、バージョンの範囲を指定する方法
  • 「’>=3.0.0 <4.0.0’」なら「バージョン3.0.0以上、4.0.0未満」という意味になる。条件式のような形で書けるので、見て意味がわかりやすい
  • 「>」という記号は、YAMLにおいて特別な意味を持つので、traditional syntaxで「あるバージョン以上(より大きい)」を指定する際には、「’>=3.0.0’」のようにクォーテーションなどでエスケープが必要。YAMLの構文について詳しくは、【速習】YAML1.2の概要と基本構文【練習問題付き】を参照。
  • エスケープが必要だったりして、caret syntaxと比較して冗長なので、caret syntaxの使用が推奨されている

caret syntax(キャレットシンタックス)

  • 「^下限バージョン」という形式で、バージョンの範囲を指定する方法
  • 「^バージョン」と指定されていたら、「指定されたバージョンと後方互換性が保証されているすべてのバージョンの範囲」を意味する。
  • 例えば、「^2.4.0」と指定されていたら「バージョン2.4.0以上、3.0.0未満」を意味する。上限を指定していないのに、なぜ「バージョン3.0.0未満」の意味になるかというと、Dartではセマンティックバージョニングを前提としているから(より詳しくは後述)。
  • traditional syntaxよりもシンプルに書けることもあり、caret syntaxの使用が推奨されている
  • 注意点として、Dart2.19以前では、SDK constraintsにcaret syntaxを使うことができなかった。1そのため、Web記事だけでなく、公式ドキュメントでもtraditional syntaxが使われていることがあるが、現在では、pubspec.yaml内でのあらゆるバージョン指定に、caret syntaxを使えば良い。SDK constraintsについて詳しくは、「【Flutter開発】pubspec.yamlのフィールドまとめ」を参照。

semantic versioning(セマンティック バージョニング)とは

なぜcaret syntaxで、バージョンの下限を指定するだけで、バージョンの上限がわかるのかというと、Dartがsemantic versioning(セマンティック バージョニング)を採用しているから。

セマンティックバージョニングでは、以下のように定められている。

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

  1. APIの変更に互換性のない場合はメジャーバージョンを、
  2. 後方互換性があり機能性を追加した場合はマイナーバージョンを、
  3. 後方互換性を伴うバグ修正をした場合はパッチバージョンを上げます。

プレリリースやビルドナンバーなどのラベルに関しては、メジャー.マイナー.パッチ の形式を拡張する形で利用することができます。

セマンティック バージョニング 2.0.0:概要」より引用

つまり、依存するパッケージが、セマンティックバージョニングに従っているならば、後方互換性のない変更時には、メジャーバージョンが上がるので、そのパッケージのバージョン「x.y.z」で使用できる機能は、バージョン「x+1.0.0」になるまで(ただし、x+1.0.0は含まない)使えることが保証されている、ということ。

具体的なパッケージで言うと、flutter_native_splashのバージョン「2.4.0」で使える機能は、「2.4.11」でも「2.5.0」でも「2.30.1」でも使えることが約束されるが、「3.0.0」以降では使えなくなる可能性があるということ。

なので、セマンティックバージョニングにしたがっている限り、caret syntaxでバージョンの範囲を指定したときの上限(後方互換性が保証されている範囲)は、次にメジャーバージョンが上がるまで、に必ずなる。

参考文献

Package dependencies
Add other packages to your app. Specify package locations, version constraints, and more.
セマンティック バージョニング 2.0.0
Semantic Versioning spec and website

脚注

  1. https://dart.dev/tools/pub/pubspec#sdk-constraints ↩︎
タイトルとURLをコピーしました