sbt inspect

概要

sbt inspect [subproject / ] [ config / ] task
sbt inspect actual [subproject / ] [ config / ] task
sbt inspect tree [subproject / ] [ config / ] task

説明

inspect コマンドはタスクとセッティングのグラフを調査する手段を提供する。例えば、別のタスクに影響を与えるためにどのセッティングを変更すべきか判断するのに使える。

値、説明、提供元

inspect が提供する最初の情報は、タスクの型またはセッティングの値と型である。

例:

$ sbt inspect libraryDependencies
[info] Setting: interface scala.collection.immutable.Seq =
  List(org.scala-lang:scala3-library:3.7.2,
       org.typelevel:toolkit:0.1.29,
       org.typelevel:toolkit-test:0.1.29:test)
[info] Description:
[info]  Declares managed dependencies.
[info] Provided by:
[info]  ProjectRef(uri("file:/tmp/aaa/"), "aaa") / libraryDependencies
....

出力の次のセクションは「Provided by」とラベル付けされる。セッティングが定義されている実際のスコープを示す。

libraryDependencies がカレント・プロジェクト(ProjectRef(uri("file:/tmp/aaa/"), "aaa"))で定義されていることを示す。

関連セッティング

inspect 出力の「Related」セクションは、キーの全ての定義を一覧表示する。例:

> inspect compile
...
[info] Related:
[info]  Test / compile

要求された Compile / compile タスクに加え、Test / compile タスクも存在することを示す。

セッティング依存性

順方向セッティング依存性は、セッティング(またはタスク)の定義に使用される他のセッティング(またはタスク)を示す。逆方向セッティング依存性は逆方向に、どの設定が与えられたセッティングを使用するかを示す。inspect は指定セッティング依存性または実効セッティング依存性に基づいてこの情報を提供する。指定セッティング依存性はセッティングが直接指定するものである。実効セッティングはそれらの依存関係が解決された結果である。この区別は以下のセクションで詳しく説明する。

指定セッティング依存性

例として、console を見てみる:

$ sbt inspect console
...
[info] Dependencies:
[info]  Compile / console / initialCommands
[info]  Compile / console / compilers
[info]  Compile / state
[info]  Compile / console / cleanupCommands
[info]  Compile / console / taskTemporaryDirectory
[info]  Compile / console / scalaInstance
[info]  Compile / console / scalacOptions
[info]  Compile / console / fullClasspath
[info]  Compile / fileConverter
[info]  Compile / console / streams

...

console タスクへの入力が表示される。クラスパスとオプションは Compile / console / fullClasspathCompile / console / scalacOptions から取得されることが分かる。inspect コマンドの情報により、変更すべきセッティングを見つけるのに役立つ。consolefullClasspath などのキーの慣例では、Scala 識別子はキャメルケース、文字列表現は小文字でハイフン区切りである。コンフィギュレーションの Scala 識別子は compiletest などのタスクと区別するため大文字である。例えば、前の例から Scala インタプリタ起動時に実行するコードの追加方法を推測できる:

> set Compile / console / initialCommands := "import mypackage._"
> console
...
import mypackage._
...

inspectconsoleCompile / console / initialCommands セッティングを使用していることを示した。initialCommands 文字列を Scala 識別子に変換すると initialCommands になる。compile は main ソース用であることを示す。console / はセッティングが console 専用であることを示す。このため、consoleQuick タスクに影響を与えずに console タスクの初期コマンドを設定できる。

実効セッティング依存性

inspect actual <スコープ付きキー> は使用される実効セッティング依存性を表示する。委譲により依存関係が指定されたスコープ以外から来る可能性があるため有用である。inspect actual を使うと、どのスコープがセッティングに値を提供しているか正確に分かる。inspect actual と通常の inspect を組み合わせると、セッティングに影響するスコープの範囲が分かる。上記の例に戻ると、

$ sbt inspect actual console
...
[info] Dependencies:
[info]  Compile / console / streams
[info]  Global / taskTemporaryDirectory
[info]  scalaInstance
[info]  Compile / scalacOptions
[info]  Global / initialCommands
[info]  Global / cleanupCommands
[info]  Compile / fullClasspath
[info]  console / compilers
...

initialCommands はグローバルスコープ(Global)から来ていることが分かる。これを inspect console の関連出力と組み合わせると:

Compile / console / initialCommands

この例から分かるのは initialCommands セッティングは、グローバルスコープを使って全域スコープ付けしたり、カレント・プロジェクトの console タスクスコープのように狭くスコープ付けしたり、またはその間の任意のスコープで設定できるということだ。例えば、プロジェクト全体で initialCommands を設定すると console に影響する:

> set initialCommands := "import mypackage._"
...

ここで設定したい理由は、他の console 系タスクもこの値を使用するようになるためである。inspect actual の逆方向セッティング依存性の出力を見ると、どのタスクが新しいセッティングを使用するか分かる:

$ sbt inspect actual Global/initialCommands
...
[info] Reverse dependencies:
[info]  Compile / console
[info]  consoleProject
[info]  Test / console
[info]  Test / consoleQuick
[info]  Compile / consoleQuick
...

プロジェクトで initialCommands を設定すると、そのプロジェクトの全コンフィギュレーションの全 console 系タスクに影響する例をみた。プロジェクトのクラスパスが利用できない consoleProject には初期コマンドを適用したくない場合、より具体的なタスク軸を使用できる:

> set console / initialCommands := "import mypackage._"
> set consoleQuick / initialCommands := "import mypackage._"`

またはコンフィギュレーション軸:

> set Compile/ initialCommands := "import mypackage._"
> set Test / initialCommands := "import mypackage._"

次は Delegates セクションについて説明する。スコープの委譲チェーンを示す。

スコープ委譲

セッティングはキーとスコープを持つ。スコープ A の任意のキーへの要求があるが、スコープ A にて値が定義されていない場合、要求は別のスコープに委譲される。委譲チェーンは明確に定義され、inspect コマンドの Delegates セクションに表示される。Delegates セクションは、要求されたキーに値が定義されていない場合にスコープが検索される順序を示す。

具体例として、consoleinitialCommands を再び考える:

$ sbt inspect console/initialCommands
...
[info] Delegates:
[info]  console / initialCommands
[info]  initialCommands
[info]  ThisBuild / console / initialCommands
[info]  ThisBuild / initialCommands
[info]  Zero / console / initialCommands
[info]  Global / initialCommands
...

console/initialCommands 用に具体的な値がない場合、Delegates の下にリストされたスコープが定義された値が見つかるまで順に検索されることを意味する。

inspect tree

前述のセクションで説明した直接の順方向・逆方向セッティング依存性の表示に加え、inspect tree コマンドはタスクまたはセッティングのセッティング依存性ツリーを表示できる。例:

$ sbt inspect tree console
[info] Compile / console = Task[void]
[info]   +-Global / cleanupCommands =
[info]   +-console / compilers = Task[class xsbti.compile.Compilers]
[info]   +-Compile / fullClasspath = Task[Seq[class sbt.internal.util.Attributed]]
[info]   +-Global / initialCommands =
[info]   +-scalaInstance = Task[class sbt.internal.inc.ScalaInstance]
[info]   +-Compile / scalacOptions = Task[Seq[class java.lang.String]]
[info]   +-Compile / console / streams = Task[interface sbt.std.TaskStreams]
[info]   | +-Global / streamsManager = Task[interface sbt.std.Streams]
[info]   |
[info]   +-Global / taskTemporaryDirectory = target/....
[info]   +-Global / fileConverter = sbt.internal.inc.MappedFileConverter@10095d95
[info]   +-Global / state = Task[class sbt.State]
[info]
[success] elapsed: 0 s

各タスクについて、inspect tree はタスクが生成する値の型を表示する。セッティングの場合は、セッティングの toString が表示される。