こんにちは、教育系エンジニアのひらまつ(@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(セマンティック バージョニング)を採用しているから。
セマンティックバージョニングでは、以下のように定められている。
バージョンナンバーは、メジャー.マイナー.パッチ とし、バージョンを上げるには、
- APIの変更に互換性のない場合はメジャーバージョンを、
- 後方互換性があり機能性を追加した場合はマイナーバージョンを、
- 後方互換性を伴うバグ修正をした場合はパッチバージョンを上げます。
プレリリースやビルドナンバーなどのラベルに関しては、メジャー.マイナー.パッチ の形式を拡張する形で利用することができます。
「セマンティック バージョニング 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でバージョンの範囲を指定したときの上限(後方互換性が保証されている範囲)は、次にメジャーバージョンが上がるまで、に必ずなる。