State は、sbtで使用可能なすべての情報のエントリポイントです。主要なメソッドは次のとおりです。
definedCommands: Seq[Command]
は、登録されているすべてのコマンド定義を返します。remainingCommands: List[Exec]
は、実行される残りのコマンドを返します。attributes: AttributeMap
は、汎用データを含みます。コマンドのアクション部分は、作業を実行し、State
を変換します。以降のセクションでは、State => State
変換について説明します。前述のように、コマンドは通常、解析された値も処理します:(State, T) => State
。
コマンドは、現在登録されているコマンドまたは実行されるコマンドを変更できます。これは、アクション部分で、コマンドに提供された(不変の)Stateを変換することで行われます。追加のパワーコマンドを登録する関数は、次のようになります。
val powerCommands: Seq[Command] = ...
val addPower: State => State =
(state: State) =>
state.copy(definedCommands =
(state.definedCommands ++ powerCommands).distinct
)
これは、現在のコマンドを取得し、新しいコマンドを追加し、重複を削除します。あるいは、Stateには上記の処理を行うための便利なメソッドがあります。
val addPower2 = (state: State) => state ++ powerCommands
実行する残りのコマンドを変更する関数の例をいくつか示します。
val appendCommand: State => State =
(state: State) =>
state.copy(remainingCommands = state.remainingCommands :+ "cleanup")
val insertCommand: State => State =
(state: State) =>
state.copy(remainingCommands = "next-command" +: state.remainingCommands)
最初の関数は、現在指定されているすべてのコマンドの実行後に実行されるコマンドを追加します。2番目の関数は、次に実行されるコマンドを挿入します。残りのコマンドは、挿入されたコマンドが完了した後に実行されます。
コマンドが失敗し、実行を続行しないことを示すには、state.fail
を返します。
(state: State) => {
val success: Boolean = ...
if(success) state else state.fail
}
プロジェクト関連情報は、attributes
に保存されます。通常、コマンドはこれへ直接アクセスせず、代わりに最も有用な情報を抽出するための便利なメソッドを使用します。
val state: State
val extracted: Extracted = Project.extract(state)
import extracted._
Extracted は、以下を提供します。
currentRef
)structure.data
)Setting
と、.sbtファイルおよび.scalaファイルからの元の永続的な設定へのアクセス(それぞれsession.appendとsession.original)すべてのプロジェクトデータは、structure.data
に保存されます。これはsbt.Settings[Scope]
型です。通常、T
型の情報は次の方法で取得します。
val key: SettingKey[T]
val scope: Scope
val value: Option[T] = key in scope get structure.data
ここで、SettingKey[T]
は通常Keysから取得され、たとえば.sbt
ファイルで設定を定義するために使用される型と同じです。Scopeは、キーが取得されるスコープを選択します。必要なスコープ軸のみを指定するために使用できるin
の便利なオーバーロードがあります。Structure.scalaで、in
および設定インターフェースの他の部分が定義されている場所を参照してください。いくつかの例を示します。
import Keys._
val extracted: Extracted
import extracted._
// get name of current project
val nameOpt: Option[String] = (currentRef / name).get(structure.data)
// get the package options for the `Test/packageSrc` task or Nil if none are defined
val pkgOpts: Seq[PackageOption] = (currentRef / Test / packageSrc / packageOptions).get(structure.data).getOrElse(Nil)
BuildStructureには、ビルドとプロジェクトの関係に関する情報が含まれています。主要なメンバーは次のとおりです。
units: Map[URI, LoadedBuildUnit]
root: URI
URI
はビルドを識別し、root
はロードされた最初のビルドを識別します。LoadedBuildUnitは、単一のビルドに関する情報を提供します。LoadedBuildUnit
の主要なメンバーは次のとおりです。
// Defines the base directory for the build
localBase: File
// maps the project ID to the Project definition
defined: Map[String, ResolvedProject]
ResolvedProjectは、project/Build.scala
で使用されるProject
と同じ情報を持っていますが、ProjectReferencesはProjectRef
に解決されます。
sbtのクラスパスはSeq[Attributed[File]]
型です。これにより、クラスパスエントリに任意の情報をタグ付けできます。sbtは現在これを使い、エントリにAnalysis
を関連付けます。これは、マルチプロジェクトのインクリメンタルリコンパイルに必要な情報を管理する方法です。また、管理されたエントリ(依存関係管理によって取得されたエントリ)にModuleIDとArtifactを関連付けます。基になるSeq[File]
のみが必要な場合は、files
を使用します。
val attributedClasspath: Seq[Attribute[File]] = ...
val classpath: Seq[File] = attributedClasspath.files
コマンド(*別のタスクからはなく*)から特定のプロジェクトタスクを実行し、その結果を取得することが役立つ場合があります。たとえば、IDE関連のコマンドはプロジェクトからクラスパスを取得したり、タスクはコンパイルの結果を分析したりする場合があります。関連するメソッドはProject.runTask
で、次のシグネチャを持ちます。
def runTask[T](taskKey: ScopedKey[Task[T]], state: State,
checkCycles: Boolean = false): Option[(State, Result[T])]
たとえば、
val eval: State => State = (state: State) => {
// This selects the main 'compile' task for the current project.
// The value produced by 'compile' is of type inc.Analysis,
// which contains information about the compiled code.
val taskKey = Compile / Keys.compile
// Evaluate the task
// None if the key is not defined
// Some(Inc) if the task does not complete successfully (Inc for incomplete)
// Some(Value(v)) with the resulting value
val result: Option[(State, Result[inc.Analysis])] = Project.runTask(taskKey, state)
// handle the result
result match
{
case None => // Key wasn't defined.
case Some((newState, Inc(inc))) => // error detail, inc is of type Incomplete, use Incomplete.show(inc.tpe) to get an error message
case Some((newState, Value(v))) => // do something with v: inc.Analysis
}
}
特定のプロジェクトのテストクラスパスを取得するには、このキーを使用します。
val projectRef: ProjectRef = ...
val taskKey: Task[Seq[Attributed[File]]] =
(projectRef / Test / Keys.fullClasspath)
タスクから現在のStateにアクセスするには、state
タスクを入力として使用します。たとえば、
myTask := ... state.value ...
タスクでsbtの状態を更新することも可能です。そのためには、タスクはStateTransform
型を返す必要があります。タスクの評価が完了すると、状態が変換されます。StateTransform
は、前のState
の値を受け入れて新しい状態を生成するState => State
関数で構成されます。たとえば
import complete.DefaultParsers._
val counter = AttributeKey[Int]("counter")
val setCounter = inputKey[StateTransform]("Set the value of the counter attribute")
setCounter := {
val count = (Space ~> IntBasic).parsed
StateTransform(_.put(counter, count))
}
は、カウンター属性を何らかの値に設定する入力タスクsetCounter
を作成します。