Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
SBT Basic Concepts
Search
Pishen Tsai
July 12, 2016
Programming
670
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
SBT Basic Concepts
Pishen Tsai
July 12, 2016
More Decks by Pishen Tsai
See All by Pishen Tsai
Introduction to Minitime
pishen
1
170
都什麼時代了,你還在寫 while loop 嗎?
pishen
2
750
Pishen's Emacs Journey
pishen
0
160
Scala + Google Dataflow = Serverless Spark
pishen
6
880
Shapeless Introduction
pishen
2
930
ScalaKitchen
pishen
1
480
sbt-emr-spark
pishen
1
170
My Personal Report of Scala Kansai 2016
pishen
0
440
annoy4s
pishen
0
110
Other Decks in Programming
See All in Programming
なぜ関数型プログラミングで「型」と「証明」が語られるのか #fp_matsuri
kajitack
3
800
「なぜそう決めたのか」を残し続ける仕組み ― Notion AI カスタムエージェント × Slack連携による設計判断の自動記録 - NIKKEI Tech Talk #47
niftycorp
PRO
0
260
スマートグラスで並列バイブコーディング
hyshu
0
290
Claude Team Plan導入・ガイド
tk3fftk
0
170
Claude Opus 4.6以後の受託開発エンジニアの変化(Claude Code開発ノウハウ大公開スペシャルbyクラスメソッド)
iidatakuma
1
580
どこまでゆるくて許されるのか
tk3fftk
0
470
Even G2とAWSで推しのエージェントを召喚しよう!
har1101
1
160
鹿野さんに聞く!『TypeScriptコードレシピ集』で磨く実践力
tonkotsuboy_com
4
1.1k
Observability in Practice:Grafana 與 Edge Device SRE 的那些事
blueswen
0
190
Hatena Engineer Seminar #37「言語モデルの活用に関する研究」
slashnephy
0
510
PHPだって関数型したい 〜できること、できないこと〜 / fp-in-php
jsoizo
0
190
Snowflake Summitでの新機能 CoCo / CoWork / snowflake-summit-2026-overall-what-new-coco
tatsuhiro
1
220
Featured
See All Featured
Applied NLP in the Age of Generative AI
inesmontani
PRO
4
2.4k
AI: The stuff that nobody shows you
jnunemaker
PRO
8
820
Designing for humans not robots
tammielis
254
26k
How to Talk to Developers About Accessibility
jct
2
340
The Cost Of JavaScript in 2023
addyosmani
55
10k
Build your cross-platform service in a week with App Engine
jlugia
234
18k
How to Think Like a Performance Engineer
csswizardry
28
2.7k
Learning to Love Humans: Emotional Interface Design
aarron
275
41k
16th Malabo Montpellier Forum Presentation
akademiya2063
PRO
0
190
Avoiding the “Bad Training, Faster” Trap in the Age of AI
tmiket
0
190
Six Lessons from altMBA
skipperchong
29
4.3k
RailsConf 2023
tenderlove
30
1.5k
Transcript
SBT Basic Concepts @pishen
build.sbt
name := "hello_world" SettingKey[String] a function Setting[String]
build.sbt (*.sbt) name := "hello_world" version := "0.1.0-SNAPSHOT" scalaVersion :=
"2.11.8" libraryDependencies += "com.typesafe.akka" %% "akka-actor" % "2.4.8" //libraryDependencies += // "com.typesafe.akka" % "akka-actor_2.11" % "2.4.8" Setting[String] Setting[Seq[ModuleID]]
> inspect libraryDependencies Setting: Seq[ModuleID] = List(...) > show libraryDependencies
List(...)
build.sbt import java.util.Date def getTime() = new Date().getTime val baseVersion
= "0.1.0" version := { println("Mom! I'm here!!") baseVersion + "_" + getTime() } class A() {...} object B {...}
Define your own Key
SettingKey[T] TaskKey[T] InputKey[T] name, version compile run
val a = settingKey[Int]("this is a") val demo = taskKey[Unit]("demo")
Description, will be shown in > inspect SettingKey[Int] > show a > demo
Implement the Settings val demo = taskKey[Unit]("demo") name := "hello_world"
demo := { println("Hello, this is project " + name.value) } dependency > demo > inspect demo build.sbt
Parallelization & deduplication val demo1 = taskKey[Unit]("demo1") val demo2 =
taskKey[Unit]("demo2") val demo3 = taskKey[Unit]("demo3") demo1 := println("demo1") demo2 := println("demo2") demo3 := { demo1.value println("demo3") demo2.value demo1.value } demo1 demo2 demo3 demo2 demo1 demo3 build.sbt
SBT is recursive ``The project directory is another build inside
your build, which knows how to build your build.
SBT is recursive ``The project directory is another build inside
your build, which knows how to build your build.
my-project/ └ src/main/scala/.../Main.scala └ Hello.scala └ anything.sbt └ build.sbt └
target/ └ Main.class
my-project/ └ src/main/scala/.../Main.scala └ Hello.scala └ anything.sbt └ build.sbt └
project/ └ MyPlugin.scala └ target/ └ Main.class class A() {...} object B {...} val a = new A()
my-project/ └ src/main/scala/.../Main.scala └ Hello.scala └ anything.sbt └ build.sbt └
project/ └ MyPlugin.scala └ cool.sbt └ assembly.sbt └ target/ └ Main.class libraryDependencies += "joda-time" % "joda-time" % "2.9.4" addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.14.3") val now = DateTime.now()
my-project/ └ src/main/scala/.../Main.scala └ Hello.scala └ anything.sbt └ build.sbt └
project/ └ MyPlugin.scala └ cool.sbt └ assembly.sbt └ project/ └ PluginOfMyPlugin.scala └ target/ └ Main.class
Some examples
pishen/annoy4s src/main/cpp/annoyjava.cpp src/main/resource/linux-x86-64/libannoy.so win32-x86 darwin freebsd-x86 ... g++ https://github.com/pishen/annoy4s
pishen/annoy4s libraryDependencies += "net.java.dev.jna" % "jna" % "4.2.2" https://github.com/pishen/annoy4s project/plugins.sbt
pishen/annoy4s val compileNative = taskKey[Unit](...) import com.sun.jna.Platform import sys.process._ compileNative
:= { val lib = s"src/main/resources/${Platform.RESOURCE_PREFIX}/libannoy.so" val cpp = "src/main/cpp/annoyjava.cpp" s"g++ -o $lib -shared -fPIC $cpp".! } > compileNative https://github.com/pishen/annoy4s build.sbt
KKBOX/spark-deployer libraryDependencies ++= Seq( "com.typesafe" % "config" % "1.3.0", "com.amazonaws"
% "aws-java-sdk-s3" % "1.10.34", "com.amazonaws" % "aws-java-sdk-ec2" % "1.10.34", "org.pacesys" % "openstack4j" % "2.0.9" ) addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.14.0") https://github.com/KKBOX/spark-deployer project/plugins.sbt
Scopes
compile Key
test:compile Key Configuration
test:compile::fullClasspath Key Configuration other Key
Configuration scope compile test * runtime staging production Global custom
configurations : : : : : : name name name name name name "G" "A" "B" "C" "D" delegate
Configuration scope compile test * runtime staging production : :
: : : : compile compile compile compile compile compile Configuration Key
Define Configurations lazy val Staging = config("staging") name := "G"
name in Staging := "D" + name.value build.sbt > show name > show *:name > show staging:name > inspect staging:name Global
Question 1 lazy val Staging = config("staging") version := "1.0"
version in Staging := "1.0.1" name in Staging := "D" + version.value build.sbt > show staging:name D1.0? D1.0.1?
Solution 1 name in Staging := "D" + (version in
Staging).value inConfig(Staging)(Seq( name := "D" + version.value )) build.sbt
Question 2 > compile Configuration? Key?
Usage of Configuration lazy val Staging = config("staging") lazy val
Production = config("production") val deploy = taskKey[Unit]("deploy") val servers = settingKey[Seq[String]]("servers") val baseSettings = Seq( deploy := {... servers.value ...} ) inConfig(Staging)(baseSettings) inConfig(Production)(baseSettings) deploy.sbt
Usage of Configuration servers in Staging := Seq("192.168.0.1") servers in
Production := Seq("140.112.172.1", ...) build.sbt > staging:deploy > production:deploy sbt-codedeploy https://github.com/gilt/sbt-codedeploy
Task scope * :: name compile test assembly :: ::
:: name name name name :: assembly Key Key
Question 3 val demo = taskKey[Unit]("demo") version := "1.0" version
in demo := "1.0.1" demo := println("D" + version.value) build.sbt > demo D1.0? D1.0.1? demo::version
Usage of Task scope fullClasspath in assembly += baseDirectory.value /
"production-resources" my-project/ └ src/main/ └ scala/... └ resources/application.conf └ build.sbt └ production-resources/ └ production.conf include "production.conf" build.sbt
Mixed scope test:compile::fullClasspath fullClasspath in (Test, compile) := {...}
Publishing
libraryDependencies += "com.typesafe.akka" %% "akka-actor" % "2.4.8" ~/.ivy2/cache/ Maven Central
Bintray JCenter ~/.ivy2/local/
libraryDependencies += "com.typesafe.akka" %% "akka-actor" % "2.4.8-SNAPSHOT" ~/.ivy2/cache/ Maven Central
Bintray JCenter ~/.ivy2/local/
organization := "net.pishen" name := "my-project" version := "0.1.0-SNAPSHOT" crossScalaVersions
:= Seq("2.10.6", "2.11.8") > +publishLocal ~/.ivy2/local/ Project A libraryDependencies += "net.pishen" %% "my-project" % "0.1.0-SNAPSHOT" Project B ~/.ivy2/cache/
Resolvers val r = "My Resolver" at "http://my-server/my-repository" val r
= Resolver.sonatypeRepo("public") val r = Resolver.bintrayRepo("owner", "repo") val r = Resolver.sftp(...) val r = Resolver.... resolvers += r publishTo := Some(r) > publish
Publish your own library via Bintray 1. Create an account
on https://bintray.com/ 2. Install bintray-sbt https://github.com/softprops/bintray-sbt 3. Share your masterpiece to the world!
> thanks @pishen