sbt 2.0 の変更点

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

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

  • Scala 3 を用いたメタビルド。ビルド定義やプラグインに使われる sbt 2.x build.sbt DSL は Scala 3.x ベースとなった (現行では 3.8.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.8.2/<subproject>/ へと変更された。
  • sbt 2.x は build.sbt に変更があると、デフォルトで自動的リロードされるようになった @eed3si9n in #8211
  • sbt 2.x は、sbt シェル内でのスコープ付きタスクの委譲を禁止する @eed3si9n in #8539
  • sbt 2.x は、エヴィクション・エラー規制を Test コンフィギュレーションでも施行する by @calm329 and @zainab-ali in #8451 + #9102

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

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

新機能

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

コモン・セッティング

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

scalaVersion := "3.8.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 ...ExampleTest

さらに、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 2.0 では、sbt server は run タスクを sbtn に送り返して、sbtn 側で新しい JVM にフォークさせる。以下のように実行するだけでいい:

sbt run

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

クライアントサイド REPL

クライアントサイド・ラン同様に、sbt server は console (Scala REPL) を sbtn に送り返して、sbtn 側で新しい JVM をフォークして REPL を実行する。以下のように実行するだけでいい:

sbt console

これは、sbt server をブロックしてしまうことを回避する。これは @eed3si9n@calm329 によって#8018, #8604, #8677, #8705, #8722 としてコントリされた。

rootProject と autoAggregate

sbt 2.0 は rootProject マクロを追加する:

lazy val root = rootProject

これは build.sbt に頻出する (project in file(".")) 略記法だ。

lazy val root = rootProject
  .autoAggregate

sbt 2.0 は、ロード時にローカルの全サブプロジェクトに展開する autoAggregate メソッドを追加する。

Maven BOM (Bill of Materials) の使用

sbt 2.0 は Maven BOM (Bill of Materials) の使用を追加する。サブプロジェクトは .pomOnly() を使って BOM アーティファクトに依存することができる:

libraryDependencies += ("com.fasterxml.jackson" % "jackson-bom" % "2.21.0").pomOnly()

これらの部品表 (bill of materials) は Resolve.addBom() を経由して Coursier に渡され、(Jackson などの) 特定のライブラリに対するバージョン制限を導入する。"*" を使って無バージョンのライブラリ依存性を宣言することができる:

libraryDependencies += "com.fasterxml.jackson.core" % "jackson-core" % "*"

これによって Coursier に自動的に部品表からのバージョンを穴埋めさせることができる (この場合 "2.21.0")。これは @bitloi により #8675 としてコントリされた。

性能の改善

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

過去の変更点

以下も参照: