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
1
490
SBT Basic Concepts
Pishen Tsai
July 12, 2016
Tweet
Share
More Decks by Pishen Tsai
See All by Pishen Tsai
Introduction to Minitime
pishen
1
100
都什麼時代了,你還在寫 while loop 嗎?
pishen
2
680
Pishen's Emacs Journey
pishen
0
99
Scala + Google Dataflow = Serverless Spark
pishen
6
740
Shapeless Introduction
pishen
2
820
ScalaKitchen
pishen
1
320
sbt-emr-spark
pishen
1
95
My Personal Report of Scala Kansai 2016
pishen
0
160
annoy4s
pishen
0
63
Other Decks in Programming
See All in Programming
Swiftの型推論を学ぼう | Let's Learn About Type Inference in Swift
omochi
2
820
導入から5年が経って見えた Datadog APM 運用の課題
bgpat
2
540
Enhancing Applications with Accessibility API
kishikawakatsumi
3
1k
受託開発でGitLab CI を活用していく
xiombatsg
1
130
TCAの Shared Stateって どういう仕組みになってんの?
yimajo
0
330
document.write再考
brn
5
2.5k
とにかくHTTP3をライトニングに話す / Anyway, I'll talk to Lightning about HTTP3.
seike460
PRO
0
120
WasmOS: Wasmを実行する自作Microkernel
riru
0
380
Prepare for Jakarta EE 11 - Performance and Developer Productivity
ivargrimstad
0
530
AppDeveloperCon 2024 EU: Building polyglot developer experiences in 2024
salaboy
0
380
チームでモデリングを育てるうえで 考えたこと・気づいたこと / Cultivating Modeling in Teams: Thoughts and Insights
mackey0225
5
2.5k
PHP8の機能を使って堅牢にコードを書く
fendo181
6
2.6k
Featured
See All Featured
Making Projects Easy
brettharned
106
5.4k
The Invisible Customer
myddelton
114
12k
Designing for humans not robots
tammielis
247
25k
Why You Should Never Use an ORM
jnunemaker
PRO
50
8.6k
Java REST API Framework Comparison - PWX 2021
mraible
PRO
18
6.8k
[Rails World 2023 - Day 1 Closing Keynote] - The Magic of Rails
eileencodes
1
1.2k
How to name files
jennybc
62
92k
10 Git Anti Patterns You Should be Aware of
lemiorhan
644
57k
ParisWeb 2013: Learning to Love: Crash Course in Emotional UX Design
dotmariusz
101
6.6k
Building an army of robots
kneath
300
41k
4 Signs Your Business is Dying
shpigford
174
21k
Design and Strategy: How to Deal with People Who Don’t "Get" Design
morganepeng
113
18k
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