Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
SBT Basic Concepts
Search
Pishen Tsai
July 12, 2016
Programming
680
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
220
都什麼時代了,你還在寫 while loop 嗎?
pishen
2
770
Pishen's Emacs Journey
pishen
0
160
Scala + Google Dataflow = Serverless Spark
pishen
6
890
Shapeless Introduction
pishen
2
940
ScalaKitchen
pishen
1
490
sbt-emr-spark
pishen
1
170
My Personal Report of Scala Kansai 2016
pishen
0
440
annoy4s
pishen
0
120
Other Decks in Programming
See All in Programming
コードで差別化できない時代の ソフトウェアエンジニアリング / Software Engineering in an Era Where Code Doesn’t Differentiate
kishida
2
170
Unity6 URPによる海底をテーマにしたVJシステムの解説 | Unity Shader 完全に理解した 勉強会
gam0022
0
360
TechTown - Creating Composable Callables in Contemporary C++
rollbear
0
110
mrbgem 三角測量 開発
ogom
0
240
残高管理から台帳サービスへの進化
artoy
1
200
月間100万人のサービス刷新で、 技術選定をHonoに振り切った話
yutobara
8
6.5k
Embedded Swiftで作る自作USBデバイス によるiOSデバイスの自動テスト / iOSDC Japan 2026 glassfiber
glassfiber
0
340
AIに “答え“を書かせるのを やめてみた
___akari11
0
120
HTML-in-Canvasで作る未来のWeb UI表現
clockmaker
5
4.8k
個人開発者よ、Honoを使え(おじさんver)
tanahiro2010
2
250
プロダクトコードからライブラリの境界を見つける
elmetal
PRO
0
110
気持ちぃ〜角丸 Squircle
ryu1013
0
290
Featured
See All Featured
The Cult of Friendly URLs
andyhume
79
7k
Claude Code のすすめ
schroneko
67
230k
First, design no harm
axbom
PRO
2
1.3k
What does AI have to do with Human Rights?
axbom
PRO
1
2.4k
Measuring Dark Social's Impact On Conversion and Attribution
stephenakadiri
2
310
The Organizational Zoo: Understanding Human Behavior Agility Through Metaphoric Constructive Conversations (based on the works of Arthur Shelley, Ph.D)
kimpetersen
PRO
0
490
Accessibility Awareness
sabderemane
1
250
Code Review Best Practice
trishagee
74
20k
Public Speaking Without Barfing On Your Shoes - THAT 2023
reverentgeek
1
590
How to Get Subject Matter Experts Bought In and Actively Contributing to SEO & PR Initiatives.
livdayseo
0
220
GraphQLの誤解/rethinking-graphql
sonatard
75
12k
Thoughts on Productivity
jonyablonski
76
5.4k
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