読者です 読者をやめる 読者になる 読者になる

decadence

個人のメモ帳

sbtの起動時にプロジェクトの設定を読むとこ + shellコマンド

sbt
  • bootの話(reload + shell)
    • compileとかrunが入ったJvmPluginを読み込む所とかある

sbt.xMainではbootコマンドが初めに実行されるっての前の前に見た。

ここでは、sbt shellが立ち上がる前にbootによりreloadコマンドが実行されている。

  1. reloadの話
  2. shellの話

プロジェクトの設定の読み込み: reload

ここでは、load失敗時のコマンドload-failed、失敗時のコマンドの仕切りを表すresumeFromFailureコマンドが追加されている。そしてプロジェクトの設定を読み込むloadpコマンドが読み込まれる。

  • loadpは引数無し、pluginsreturnの3通りで動作し、LoadAction.ValueのenumとしてそれぞれCurrentPluginsReturnとなる(以下、Currentのみの処理を見る)
    • Current: (Re)loads the project in the current directory.
    • Plugins: (Re)loads the plugins project (under project directory).
    • Return: (Re)loads the root project (and leaves the plugins project).
  • sbt.BuildinCommands.doLoadProject: loadpの実装
    • loadActionでは、ProjectReturnという属性(Attribute)に対し、LoadAction.Valueに応じて現在のStateに対し、値が設定される
      • 引数無しのCurrentの場合、現在のStateのProjectReturn属性の値が設定されていればそのまま、設定されてなければbaseDirectoryのプロジェクトのみがProjectReturn属性の値として設定される
    • baseDirectoryとなるディレクトリが存在していなければ、ここでディレクトリが作成される
      • build.sbtに簡単な設定を書いてsbtを起動すると勝手にディレクトリが作られるのはここ
    • stateにcompileのためのキャッシュが定義されてない時は、設定する
      • compiler-cacheというAttributeを用いる
      • 新たに作成する際は、CompilerCache.fresh: GlobalsCacheを用いる
      • GlobalCacheはOutput, xLogger, Reporterなどの引数を用いてCacheCompilerを作るinterface
    • sbt.Load.defaultLoad <- なるほど : なんかめっちゃ設定する
      • defaultPreGlobal: clasloader, クラスパス, compilerとか探したりして、LoadBuildConfiguration作る
      • defaultWithGlobal
        • グローバルなプラグイン探してGlobalPlugin.load(TODO 後で見る)
        • グローバルなsbtの設定探してloadGlobalSettings (TODO 後で見る)
      • Load.apply <- なるほど〜 : やってること下の方にコメントそのまま載せてる
        • compileとかrunの入ったJvmPluginはここから以下のように参照されてる(長い)
          • sbt.Load.apply -> Load.load -> Loag.buildinLoader -> Load.loadUnit -> Load.plugins -> Load.buildPlugins/noPlugins -> Load.loadPluginDefinition -> Load.loadPlugins -> PluginDiscovery.discoverAll(data, loader)) -> defaultAutoPlugins
    • sbt.Load.initialSession
    • Project.setProject: 得られたsessionやloadした結果から得られるstructureからプロジェクトをセットする
      • onLoadonUnloadのhookを取得し、onUnloadを設定
      • onLoadはここで実行
      • ここで最後にupdateCurrentってのが呼ばれてる:Project.updateCurrent(s: State): State
        • プロジェクトの設定(BuildStructure)を読み込む
        • プロジェクト自体を読み込んだら、onLoadMessageを表示する
        • プロジェクトのGlobalコンフィギュレーションのコマンドとか、現在のセッションで定義されたコマンドなどをまとめてs.definedCommandsに入れる

Load.applyでしてること、コメントには以下のように書いてる

// build, load, and evaluate all units.
// 1) Compile all plugin definitions
// 2) Evaluate plugin definitions to obtain and compile plugins and get the resulting classpath for the build definition
// 3) Instantiate Plugins on that classpath
// 4) Compile all build definitions using plugin classpath
// 5) Load build definitions.
// 6) Load all configurations using build definitions and plugins (their classpaths and loaded instances).
// 7) Combine settings from projects, plugins, and configurations
// 8) Evaluate settings

ちなみに、デフォルトで読み込まれるpluginは以下の通り

val defaultAutoPlugins = Seq(
  "sbt.plugins.IvyPlugin" -> sbt.plugins.IvyPlugin,
  "sbt.plugins.JvmPlugin" -> sbt.plugins.JvmPlugin,
  "sbt.plugins.CorePlugin" -> sbt.plugins.CorePlugin,
  "sbt.plugins.JUnitXmlReportPlugin" -> sbt.plugins.JUnitXmlReportPlugin
)

sbt shell: shell

プロジェクトの設定が読み込まれた後に、shellコマンドにより、sbt shellが立ち上がる。shellの定義は、sbt.BasicCommands.shell

当然だがshellもコマンドの1つなので、Stateを取って実行後にStateを返すブロックを持つ。

ここでは、1行line: Stringを読み取って、以下のように前のStateから新しいStateを作る。

val newState = s.copy(onFailure = Some(Shell), remainingCommands = line +: Shell +: s.remainingCommands).setInteractive(true)

remainincCommandsの先頭に読み込んだlineを入れて、その後に再度shellコマンドを入れる。コマンドを打つ毎に異なるshellが呼び出されてる事が分かる。

他のコマンドの実装例: alias

他のコマンドの実装例も軽く見る。

aliasalias c=compileみたいにするとccompileが呼ばれるもの。~/.sbtrcに色々書いたりしとくと便利なやつ。 Stateから、既存のaliasがあるかとか確認しつつ、最終的にs.copy(definedCommands = newAlias(name, value) +: s.definedCommands)により新しいStateを返す。

cって名前のコマンドをdefinedCommandsに追加してくれる。cの中身(Parsr[() => State])はcってした時のStateremainingCommandsの前に、compileを入れてくれるってもの。


Commandは大体終わり

InputKey, TaskKey, SettingKeyとかそのへん見たいんだけど、そもそもReferenceちゃんと読んでないの思い出したから先に読もう...

当たり前な事になるほど、とか言ってる気しかしない

http://www.scala-sbt.org/release/docs/Combined+Pages.html