sbt 2.0 の変更点

互換性に影響のある変更点

sbt 1.x からのマイグレーションも参照。

  • Scala 3 を用いたメタビルド。ビルド定義やプラグインに使われる sbt 2.x build.sbt DSL は Scala 3.x ベースとなった (現行では 3.7.3) (sbt 1.x 並びに 2.x は、Scala 2.x と 3.x の両方をビルドすることが可能) by @eed3si9n, @adpi2, and others.
  • コモン・セッティング。build.sbt に直書きされたセッティングは、ルートサブプロジェクトだけではなく、全てのサブプロジェクトに追加され、これまで ThisBuild が受け持ってきた役目を果たすことができる。
  • 差分テストtest は、テスト結果をキャッシュする差分テストへと変更された。全テストを走らせたい場合は testFull を使う by @eed3si9n in #7686
  • キャッシュ化されたタスク。全てのタスクはデフォルトで、キャッシュ化されている。詳細はキャッシュ参照。
  • 依存性のツリー表示dependencyTree 関連のタスク群は 1つのインプット・タスクに統一された by @eed3si9n in #8199
  • test タスクの形が Unit から TestResult へと変更された by @eed3si9n in #8181
  • 以前 URL に型付けされていたデフォルトのセッティングやタスクキー (apiMappings, apiURL, homepage, organizationHomepage, releaseNotesURL など) は URI に変更された in #7927
  • license キーの型が Seq[(String, URL)] から Seq[License] へと変更された in #7927
  • sbt 2.x プラグインは _sbt2_3 という suffix を用いて公開される by @eed3si9n in #7671
  • sbt 2.x は、platform セッティングを追加して、ModuleID%%% 演算子を使わなくても、%% 演算子だけで JVM、JS、Native のクロスビルドができるようにした by @eed3si9n in #6746
  • useCoursier セッティングを廃止して、Coursier をオプトアウトできないようにした by @eed3si9n in #7712
  • Key.Classpath 型は、Seq[Attributed[File]] からSeq[Attributed[xsbti.HashedVirtualFileRef]] 型のへのエイリアスへと変更された。同様に、以前 File を返していたタスクキーのいくつかはHashedVirtualFileRef を返すように変更された。ファイルのキャッシュ化も参照。
  • sbt 2.x では、target のデフォルトが <subproject>/target/ から target/out/jvm/scala-3.7.3/<subproject>/ へと変更された。
  • sbt 2.x は build.sbt に変更があると、デフォルトで自動的リロードされるようになった @eed3si9n in #8211
  • 自動的タスク集約を行う Project#autoAggregate が追加された @eed3si9n in #8290

勧告どおり廃止された機能

  • IntegrationTest コンフィギュレーションは廃止された in #8184
  • sbt 0.13 スタイルのシェル構文は廃止された in #7700

新機能

  • project matrix。sbt 1.x からプラグインで使用可能だった project matrix が本体に取り込まれ、並列クロスビルドができるようになった。
  • sbt クエリ。sbt 2.x は統一スラッシュ構文を拡張してサブプロジェクトのクエリを可能とする。詳細は下記参照。
  • ローカル/リモート兼用のキャッシュ・システム。詳細は下記参照。
  • クライアントサイド・ラン。詳細は下記参照。

コモン・セッティング

sbt 2.x では、build.sbt に直書きされたセッティングはコモン・セッティングとして解釈され、全サブプロジェクトに注入される。そのため、ThisBuild スコープ付けを使わずに scalaVersion を設定できる:

scalaVersion := "3.7.3"

さらに、これはいわゆる動的ディスパッチ問題を解決する:

lazy val hi = taskKey[String]("")
hi := name.value + "!"

sbt 1.x では hi タスクはルートプロジェクトの名前を捕捉してしまっていたが、sbt 2.x は各サブプロジェクトの name! を追加する:

$ sbt show hi
[info] entering *experimental* thin client - BEEP WHIRR
[info] terminate the server with `shutdown`
> show hi
[info] foo / hi
[info]  foo!
[info] hi
[info]  root!

これは、@eed3si9n によって #6746 としてコントリされた。

sbt クエリ

サブプロジェクトが複数あるとき、選択範囲を狭めるのに sbt 2.x は sbt クエリを導入する。

$ sbt foo.../test

上の例では、foo から始まる全てのサブプロジェクトを実行する。

$ sbt ...@scalaBinaryVersion=3/test

上の例では、scalaBinaryVersion3 の全てのサブプロジェクトを実行する。これは、@eed3si9n によって #7699 としてコントリされた。

差分テスト

sbt 2.x では、test タスクはインプット・タスクとなって、実行するテスト・スイートをフィルターできるようになった:

> test *Example*

さらに、test はキャッシュ化された差分テストとなった。そのため、以前にテストが失敗したか、前回の実行から何かが変更されないと実行されないようになった。

詳細は test 参照

ローカル/リモート兼用のキャッシュ・システム

sbt 2.x は、デフォルトでキャッシュ化されたタスクを実装するため、自動的にタスクの結果をローカルのディスクもしくは Bazel 互換のリモートキャッシュにてキャッシュ化することができる。

lazy val task1 = taskKey[String]("doc for task1")

task1 := name.value + version.value + "!"

これは task1 への入力を追跡してマシン・ワイドなディスクキャッシュを作成する。これはリモート・キャッシュとしても設定できるようになっている。sbt タスクはファイルを生成することがよくあるので、ファイルのコンテンツをキャッシュ化できる仕組みも提供する。

lazy val task1 = taskKey[String]("doc for task1")

task1 := {
  val converter = fileConverter.value
  ....
  val output = converter.toVirtualFile(somefile)
  Def.declareOutput(output)
  name.value + version.value + "!"
}

詳細はキャッシュ化を参照。これは @eed3si9n によって #7464 / #7525 としてコントリされた。

クライアントサイド・ラン

sbt runner 1.10.10 以降は sbt 2.x を起動するのに、デフォルトで sbtn (GraalVM native-image のクライアント) を使う。sbt 2.0 は run タスクを sbtn に送り返して、sbtn 側で新しい JVM にフォークさせる。以下のように実行するだけでいい:

sbt run

これは、sbt server をブロックしてしまうことを回避し、かつ複数の実行を行うことができる。これは @eed3si9n によって#8060 としてコントリされた。run ドキュメンテーション参照。

性能の改善

Adrien Piquerez さんが Scala Center に在籍していたときに、性能改善に関連するコントリをいくつか行った。

  • perf: 長生きするオブジェクトの数を削減して、2.0.0-M2 比較で起動を 20% 高速化した by @adpi2 in #7866
  • perf: SettingInitialize が作成される数を削減した by @adpi2 in #7880
  • perf: Settings をリファクタリングして、集約キーのインデックス化を最適化した @adpi2 in #7879
  • perf: InfoBasicAttributeMap のインスタンスを削除した by @adpi2 in #7882

過去の変更点

以下も参照: