Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
sbt core concepts
Eugene Yokota (@eed3si9n)

Lightbend
goal:

gain better intuition about sbt
sbt に対する直感を育む
sbt by example


build tool
• "automates repeatable tasks"

— Build Systems à la Carte

Mokhov, Mitchell, Jones
「リピータブルなタスクの自動化」
a casually functional

build tool
カジュアルに関数型なビルドツール
State
State
1. build structure
2. your disk
sbt での状態は、ビルド構造とあなたのディスク
Command
• State State
Command
• State State
• processed sequentially
• low-level construct; avoid making custom commands
逐次処理される
低レベルなものなので、カスタム...
examples of command
commands
help, tasks
projects, project hello
set name := "foo"
<command1>; <command2>
++ 2.13.0, ++ 2....
act command
• lifts tasks and settings into a command
act コマンドはタスクやセッティングを持ち上げる
which state is it changing?
commands changes
help, tasks no changes
projects, project hello build structure
set name := "f...
why State + Command?
何のために State + Command があるの?
why State + Command?
• predictable checkpoint
• building block for interactiveness:

"automates repeatable tasks"
予測可能なチェッ...
interactive
sbt> testOnly foo.bar
command
logs
sbt shell
effects
about time
distributed events
event a
event b
"happens before"
process p
分散イベント
同プロセス内では、イベントの順序は自明
distributed events
event a
event b
"happens before"
process p process q
メッセージの送信はメッセージの受信よりも先にある
distributed events
• a → b (a happens before b)
• a ↛ b (a does not happen before b)
• 2 distinct events a and b are said ...
distributed events
• a → b (a happens before b)
• a ↛ b (a does not happen before b)
• 2 distinct events a and b are said ...
Applicative functor
scala> (3.some, 2.some) mapN { _ + _ }
res8: Option[Int] = Some(5)
scala> (none[Int], 5.some) mapN { _...
for comprehension
getLine flatMap { x =>
print(length(x)) flatMap { _ =>
getLine flatMap { y =>
IO(x ++ y)
}
}
}
for {
x <...
build.sbt DSL
// sbt 0.12 style
foo <<= (compile in Compile, bar) map { (c, b) =>
doSomething(b)
}
// sbt 1.x style
foo :=...
build.sbt DSL
// sbt 0.12 style
foo <<= (compile in Compile, bar) map { (c, b) =>
doSomething(b)
}
// sbt 1.x style
foo :=...
build.sbt DSL
foo := {
val c = (Compile / compile).value
val b = bar.value
doSomething(b)
}
Compile / compile bar
foo
"hap...
build.sbt DSL
foo := {
val c = (Compile / compile).value
val b = bar.value
doSomething(b)
}
Compile / compile bar
foo
"hap...
Applicative composition
foo := {
val c = (Compile / compile).value
val b = bar.value
doSomething(b)
}
Test / test := {
val...
why Applicative composition?
Compile / compile bar
foo
"happens before"
Test / test
"happens before"
何故 Applicative 合成をするの...
why Applicative composition?
Compile / compile bar
foo
"happens before"
Test / test
"happens before"
1. minimality (execut...
why Applicative composition?
Compile / compile bar
foo
"happens before"
Test / test
"happens before"
1. minimality
2. auto...
act command
• given a task, creates a plan that evaluates the task
in current and aggregated subprojects
• concurrent task...
act command
• how does it relate with State?
s0 s1 s2
reload (settings) act (task) act (task)
状態との関連は?

tasks vs commands
• prefer tasks for plugin extension
• tasks compose automatically
• command composition is stateful / se...
~ command
build structure
ビルド構造

build structure: build
build {uri}
subproject {uri}foo
configuration foo/Compile
key-value store (settings + tasks)
Scala v...
build structure: subproject
build {uri}
subproject {uri}foo
configuration
foo/Compile
foo/Runtime
foo/Test
key-value store ...
build structure: configuration
• has its own sources + library dependencies
• Test extends Runtime. Runtime extends
Compile...
build structure: k-v store
build {uri}
subproject {uri}foo
configuration foo/Compile
key-value store (settings + tasks)
Sca...
key-value store
key value
name helloworld
version 0.1.0
organization com.example
key-value store
key value
foo/name helloworld
ThisBuild/version 0.1.0
ThisBuild/organization com.example
foo/Compile/compi...
key scoping
1. subproject (Zero, ThisBuild, foo, etc.)
2. configuration (Zero, Compile, Test, etc.)
3. in-task (Zero, conso...
key-value store
key value
name
foo/name
foo/Zero/Zero/name helloworld
foo/Compile/console/scalacOptions List()
• keys are ...
why key-value store?
• inspect command
• provides flexible extensibility on most aspects of the build
• plugins can created...
setting expresion
name := { "hello" }
key operator (setting/task) body
• operators :=, +=, ++=
• a setting expression repr...
setting expresion
ThisBuild / organization := "com.example"
name := (ThisBuild / organization).value + "12"
• use .value t...
delegation rules
x := (core / Test / console / scalacOption).value
1. look for the specified key, then try in-task ⇢ Zero
2...
delegation rules
ThisBuild / version := name.value
lazy val b = project
.settings(
name := "b"
something := version.value
...
tip for plugin authors
• define custom keys at the widest scope (Global),
and reference the keys using the narrowest scope
...
key-value store
foo/Compile/scalacOptions
foo/name
ThisBuild/version
Test
Runtime
Compile
foo/Compile/compile
foo
ThisBuil...
sbt 1.3.0
sbt 1.3.0 RC-2
• Coursier for library management
• super shell and tracing
• turbo mode (enabled layered ClassLoader)
• de...
Thank You
delta vee (2019.06 mixtape)
sbt core concepts (ScalaMatsuri 2019)
sbt core concepts (ScalaMatsuri 2019)
You’ve finished this document.
Download and read it offline.
Upcoming SlideShare
What to Upload to SlideShare
Next
Upcoming SlideShare
What to Upload to SlideShare
Next
Download to read offline and view in fullscreen.

0

Share

sbt core concepts (ScalaMatsuri 2019)

Download to read offline

sbt is an interactive build tool created for Scala. In this talk I will go over the core concepts of sbt such as tasks vs commands, and scoping.

Related Books

Free with a 30 day trial from Scribd

See all

Related Audiobooks

Free with a 30 day trial from Scribd

See all
  • Be the first to like this

sbt core concepts (ScalaMatsuri 2019)

  1. 1. sbt core concepts Eugene Yokota (@eed3si9n)
 Lightbend
  2. 2. goal: gain better intuition about sbt sbt に対する直感を育む
  3. 3. sbt by example
  4. 4. 
 build tool • "automates repeatable tasks"
 — Build Systems à la Carte
 Mokhov, Mitchell, Jones 「リピータブルなタスクの自動化」
  5. 5. a casually functional
 build tool カジュアルに関数型なビルドツール
  6. 6. State
  7. 7. State 1. build structure 2. your disk sbt での状態は、ビルド構造とあなたのディスク
  8. 8. Command • State State
  9. 9. Command • State State • processed sequentially • low-level construct; avoid making custom commands 逐次処理される 低レベルなものなので、カスタムコマンドは避ける
  10. 10. examples of command commands help, tasks projects, project hello set name := "foo" <command1>; <command2> ++ 2.13.0, ++ 2.13.0!, +<command> shell command act command
  11. 11. act command • lifts tasks and settings into a command act コマンドはタスクやセッティングを持ち上げる
  12. 12. which state is it changing? commands changes help, tasks no changes projects, project hello build structure set name := "foo" build structure <command1>; <command2> both ++ 2.13.0, ++ 2.13.0!, +<command> both act command disk 変更している状態はどっち?
  13. 13. why State + Command? 何のために State + Command があるの?
  14. 14. why State + Command? • predictable checkpoint • building block for interactiveness:
 "automates repeatable tasks" 予測可能なチェックポイント インタラクティブ性のための構成要素
  15. 15. interactive sbt> testOnly foo.bar command logs sbt shell effects
  16. 16. about time
  17. 17. distributed events event a event b "happens before" process p 分散イベント 同プロセス内では、イベントの順序は自明
  18. 18. distributed events event a event b "happens before" process p process q メッセージの送信はメッセージの受信よりも先にある
  19. 19. distributed events • a → b (a happens before b) • a ↛ b (a does not happen before b) • 2 distinct events a and b are said to be concurrent if a ↛ b and b ↛ a a ↛ b かつ b ↛ a であるとき、2つのイベントは並行
  20. 20. distributed events • a → b (a happens before b) • a ↛ b (a does not happen before b) • 2 distinct events a and b are said to be concurrent if a ↛ b and b ↛ a 2 events are concurrent if neither can causality affect each other 2つのイベントがお互いに因果的に影響を持たない場合、並行
  21. 21. Applicative functor scala> (3.some, 2.some) mapN { _ + _ } res8: Option[Int] = Some(5) scala> (none[Int], 5.some) mapN { _ - _ } res9: Option[Int] = None See 'Oh, All the things you'll traverse' by Luka Jacobowitz
  22. 22. for comprehension getLine flatMap { x => print(length(x)) flatMap { _ => getLine flatMap { y => IO(x ++ y) } } } for { x <- getLine _ <- print(length(x)) y <- getLine } yield x ++ y def procedural: Unit = { val x = getLine print(length(x)) val y = getLine x ++ y } for 内包表記

  23. 23. build.sbt DSL // sbt 0.12 style foo <<= (compile in Compile, bar) map { (c, b) => doSomething(b) } // sbt 1.x style foo := { val c = (Compile / compile).value val b = bar.value doSomething(b) }
  24. 24. build.sbt DSL // sbt 0.12 style foo <<= (compile in Compile, bar) map { (c, b) => doSomething(b) } // sbt 1.x style foo := { val c = (Compile / compile).value val b = bar.value doSomething(b) } Applicative composition
  25. 25. build.sbt DSL foo := { val c = (Compile / compile).value val b = bar.value doSomething(b) } Compile / compile bar foo "happens before"
  26. 26. build.sbt DSL foo := { val c = (Compile / compile).value val b = bar.value doSomething(b) } Compile / compile bar foo "happens before" line of sand in time-space
  27. 27. Applicative composition foo := { val c = (Compile / compile).value val b = bar.value doSomething(b) } Test / test := { val c = (Compile / compile).value val f = foo.value } Compile / compile bar foo "happens before" Test / test "happens before"
  28. 28. why Applicative composition? Compile / compile bar foo "happens before" Test / test "happens before" 何故 Applicative 合成をするのか?
  29. 29. why Applicative composition? Compile / compile bar foo "happens before" Test / test "happens before" 1. minimality (executes task at most once, for input that changed) evaluated only once ミニマル性 (タスクは入力が変化したとき、最多で1回のみ) Compile / compile は一回のみ実行される
  30. 30. why Applicative composition? Compile / compile bar foo "happens before" Test / test "happens before" 1. minimality 2. automatic parallel processing 自動並列処理

  31. 31. act command • given a task, creates a plan that evaluates the task in current and aggregated subprojects • concurrent tasks are evaluated in parallel lazy val root = (project in file(".")) .aggregate(util, core) .settings(...) lazy val util = (project in file("util")) .dependsOn(core) lazy val core = (project in file("core")) act コマンドは、与えられたタスクを現在サブプロジェクトと
 集約されたサブプロジェクトで実行するプランを作成する
  32. 32. act command • how does it relate with State? s0 s1 s2 reload (settings) act (task) act (task) 状態との関連は?

  33. 33. tasks vs commands • prefer tasks for plugin extension • tasks compose automatically • command composition is stateful / sequential プラグイン拡張性にはタスクがオススメ
 タスクは自動合成するが、コマンド合成は stateful
  34. 34. ~ command
  35. 35. build structure ビルド構造

  36. 36. build structure: build build {uri} subproject {uri}foo configuration foo/Compile key-value store (settings + tasks) Scala version subproject {uri}bar configuration bar/Compile Scala version
  37. 37. build structure: subproject build {uri} subproject {uri}foo configuration foo/Compile foo/Runtime foo/Test key-value store (settings + tasks) Scala version
  38. 38. build structure: configuration • has its own sources + library dependencies • Test extends Runtime. Runtime extends Compile. subproject {uri}foo configuration foo/Compile foo/Runtime foo/Test Scala version コンフィギュレーションは独自のソースとライブラリ依存性を 持つ
  39. 39. build structure: k-v store build {uri} subproject {uri}foo configuration foo/Compile key-value store (settings + tasks) Scala version subproject {uri}bar configuration bar/Compile Scala version
  40. 40. key-value store key value name helloworld version 0.1.0 organization com.example
  41. 41. key-value store key value foo/name helloworld ThisBuild/version 0.1.0 ThisBuild/organization com.example foo/Compile/compile <task> foo/Compile/console/scalacOptions List()
  42. 42. key scoping 1. subproject (Zero, ThisBuild, foo, etc.) 2. configuration (Zero, Compile, Test, etc.) 3. in-task (Zero, console, etc.) foo/Compile/console/scalacOptions キーのスコープ付け

  43. 43. key-value store key value name foo/name foo/Zero/Zero/name helloworld foo/Compile/console/scalacOptions List() • keys are automatically scoped to the current subproject • other scope axes default to Zero • Global = Zero/Zero/Zero キーは自動的にカレント・サブプロジェクトにスコープされる 他のスコープ軸のデフォルトは Zero
  44. 44. why key-value store? • inspect command • provides flexible extensibility on most aspects of the build • plugins can created based on other plugins sbt:sbtRoot> inspect tree test [info] Test / test = Task[Unit] [info] +-Test / executeTests = Task[sbt.Tests$Output] [info] | +-classLoaderLayeringStrategy = ScalaLibrary [info] | +-Test / loadedTestFrameworks = Task[scala.collection.immutable.Map[sbt.TestFramework, .. [info] | | +-Test / loadedTestFrameworks / streams = Task[sbt.std.TaskStreams[sbt.internal.util... [info] | | | +-Global / streamsManager = Task[sbt.std.Streams[sbt.internal.util.Init$.. [info] | | | 構造を inspect することができる ビルドを形成する多くの部分を柔軟に拡張できる
  45. 45. setting expresion name := { "hello" } key operator (setting/task) body • operators :=, +=, ++= • a setting expression represents a transformation of k-v store セッティング式
  46. 46. setting expresion ThisBuild / organization := "com.example" name := (ThisBuild / organization).value + "12" • use .value to lookup the setting/task value • key-value store forms a DAG (directed acyclic graph) .value を使ってセッティングやタスクの値を参照する key-value ストアは DAG を形成する
  47. 47. delegation rules x := (core / Test / console / scalacOption).value 1. look for the specified key, then try in-task ⇢ Zero 2. next try Test ⇢ Runtime ⇢ Compile ⇢ Zero 3. next try core ⇢ ThisBuild ⇢ Zero 4. precedence: subproject > configuration > in-task 5. transitive evaluation doesn't carry original context (no dynamic dispatch) 5つの移譲ルールがあり、指定されたキーが無い場合に 次に見る場所を規定する
  48. 48. delegation rules ThisBuild / version := name.value lazy val b = project .settings( name := "b" something := version.value ) • transitive evaluation doesn't carry original context (no dynamic dispatch) 間接的評価は元のコンテキストを伴わない OO の this.draw 的な振る舞いでは無い
  49. 49. tip for plugin authors • define custom keys at the widest scope (Global), and reference the keys using the narrowest scope Global / obfuscateLogic := Logic.Default Compile / obfuscate := { val logic = (Compile / obfuscateLogic).value doObfuscate(logic) } • This allows build users various levels to rewire the setting (Global, ThisBuild, proj, proj/Compile) カスタムキーは最も広いスコープ付けで定義し、 最も狭いスコープ付けで参照すると最大の柔軟性を得られる
  50. 50. key-value store foo/Compile/scalacOptions foo/name ThisBuild/version Test Runtime Compile foo/Compile/compile foo ThisBuild Zero key configuration subproject foo/Runtime/compile foo/Test/compile in-task foo/Compile/console/scalacOptions foo/baseDirectory
  51. 51. sbt 1.3.0
  52. 52. sbt 1.3.0 RC-2 • Coursier for library management • super shell and tracing • turbo mode (enabled layered ClassLoader) • details https://www.lightbend.com/blog/sbt-1.3.0- release Coursier がライブラリ管理のデフォルト
 super shell は現行タスクを表示させる
  53. 53. Thank You
  54. 54. delta vee (2019.06 mixtape)

sbt is an interactive build tool created for Scala. In this talk I will go over the core concepts of sbt such as tasks vs commands, and scoping.

Views

Total views

686

On Slideshare

0

From embeds

0

Number of embeds

34

Actions

Downloads

10

Shares

0

Comments

0

Likes

0

×