sbt クエリ

sbt 2.x はスラッシュ構文を拡張してサブプロジェクトの集約を可能とする:

act ::= [ query / ] [ config / ] [ in-task / ] ( taskKey | settingKey )

言い換えると、sbt クエリはサブプロジェクト軸の新しい書き方だと言える。

サブプロジェクトの参照

サブプロジェクトの参照は、サブプロジェクトを選択するクエリとしてそのまま使える:

build.sbt example 1

scalaVersion := "3.7.3"

lazy val foo = project

上のようなビルドがあるとき、sbt 1.x と同様の構文を使って foo サブプロジェクトのテストを実行できる:

foo/test

... ワイルドカード

... ワイルドカードはどの文字列にもマッチして、他の文字や数字とも組み合わせて、ルートの集約リストを絞り込むことができる。例えば、以下のようにして foo で始まる全サブプロジェクトのテストを実行することができる:

foo.../test

備考: * vs ...

sbt クエリは、直感的に分かりやすそうな * (アスタリスク) でなく、意図的に ... (ドット・ドット・ドット) を採用する。これは * がシェル環境においてワイルドカードとして使われることが多いからだ。そのため、常にクォートで囲む必要があり、また */test をクォートし忘れると src/test のようなディレクトリにマッチしてしまう可能性が高い。

@scalaBinaryVersion パラメータ

@scalaBinaryVersion パラメータは、サブプロジェクトの scalaBinaryVersion セッティングにマッチする。

Example

val toolkitV = "0.5.0"
val toolkit = "org.scala-lang" %% "toolkit" % toolkitV

lazy val foo = projectMatrix
  .settings(
    libraryDependencies += toolkit,
  )
  .jvmPlatform(scalaVersions = Seq("3.7.3", "2.13.17"))

lazy val bar = projectMatrix
  .settings(
    libraryDependencies += toolkit,
  )
  .jvmPlatform(scalaVersions = Seq("3.7.3", "2.13.17"))

例えば、全ての 3.x サブプロジェクトのテストを以下のように実行できる:

...@scalaBinaryVersion=3/test

以下のように、ターミナル上からも使うことができる:

$ sbt ...@scalaBinaryVersion=3/test
[info] entering *experimental* thin client - BEEP WHIRR
[info] terminate the server with `shutdown`
> ...@scalaBinaryVersion=3/test
[info] Passed: Total 0, Failed 0, Errors 0, Passed 0
[info] No tests to run for Test / testQuick
[info] compiling 1 Scala source to /tmp/foo/target/out/jvm/scala-3.6.4/foo/test-backend ...
[info] Passed: Total 0, Failed 0, Errors 0, Passed 0
[info] No tests to run for bar / Test / testQuick
example.ExampleSuite:
  + Scala version 0.003s
[info] Passed: Total 1, Failed 0, Errors 0, Passed 1

projectMatrix を使っていると集約サブプロジェクトの絞り込みが欲しくなる場面が多々あるが、sbt クエリがこれが解決する。