arrow ← to go left, arrow → to go right

sbt

update and running

@softprops

What is sbt?

What is _?

What is Happiness?

What is Happiness?

For developers ^

bob

fact:

History is able to teach us about our Evolution

> history | awk '{print $2}' | sort | uniq -c
ant
mvn
sbt

In the beginning, there was Java

Java < xml />

import javax.xml.*

< ? xml ? />

Beautiful Java

does exist

I've seen it.

<but>
  <it does="not">
    <look/>
    <like>
      ${env.this}
    </like>
  </it>
</but>

xml may be good for some things.

a maintainable configuration is not one of them.

nosql ~> nojava

(not only java)

jvm is an ecosystem

What can a jvm built system learn from a rubyist?

What if?

echo "Makefile" | sed 's/Make/Rake/'

happiness is

right in front of you

jim

rake -T # ruby developer happiness ensues

Programmers often feel joy when they can concentrate on the creative side of programming, so Ruby is designed to make programmers happy.

— Yukihiro “Matz” Matsumoto

buildrapache buildr caught on

  • a build system using executable code
  • java/scala aware
  • but...

why build Scala projects with Ruby?

clojure leiningen gets it

(defproject leiningen "0.5.0-SNAPSHOT"
  :description "A build tool designed to not set your hair on fire."
  :url "http://github.com/technomancy/leiningen"
  :dependencies [[org.clojure/clojure "1.1.0"]
             [org.clojure/clojure-contrib "1.1.0"]]
  :dev-dependencies [[swank-clojure "1.2.1"]])

clojure on clojure action ^

Notice a theme?

enter: sbt

  • a simple(r) build tool
  • a scala build tool
  • a sexy build tool

of the scala, by the scala, for the scala

sbt scala

Guy in the back exclaims...

Wait!!! What about my IDE???

eclipse

There is no e in sbt

use what you like

Relax

It's Editor Independence Day!

usa

cereal box prizes

  • project management
  • dependency managment
  • bendy
  • it's tiny by default
  • all from a friggin' REPL!

project managment

sbt is built with sbt. How cool is that?

adoption

> mkdir -p fooz/src/{main,test}/{scala,resources}

> mkdir -p fooz/{project,src/{main,test}/\
  {scala,resources}}
> tree # or
> ls -R | grep ":$" | sed -e 's/:$//' \
-e 's/[^-][^\/]*\//--/g' -e 's/^/   /' -e 's/-/|/'
|-project # <-- your sbt project config lives here
|-src
|---main
|-----resources
|-----scala
|---test
|-----resources
|-----scala
> cat `which sbt`
java -Xmx512M -jar `dirname $0`/sbt-launch-0.7.4.jar "$@"

toe dip

> sbt
Project does not exist, create new project? (y/N/s) y
Name: fooz
Organization: nyscala
Version [1.0]: 0.0.1
scala version [2.7.7]: 2.8.0
sbt version [0.7.4]:
... getting stuff
[info] Building project fooz 0.0.1 against Scala 2.8.0
[info]    using sbt.DefaultProject with sbt 0.7.4
  and Scala 2.7.7
> exec find src/main/scala -iname *.scala -exec wc -l {} ;
> tree | head -14
|-lib
|-project
|---boot
|-----scala-2.7.7
|-------lib
|-------org.scala-tools.sbt # sbt power
|---------sbt
|-----------0.7.4
|-------------compiler-interface-bin_2.7.7.final
|-------------compiler-interface-bin_2.8.0.RC2
|-------------compiler-interface-src
|-------------xsbti
|-----scala-2.8.0
|-------lib
> {editor} project/build/Project.scala

import sbt._

/** Sbt will evaluate this as the project's configuration */
class Fooz(info: ProjectInfo) extends DefaultProject(info) {
  // override defaults
  // declare dependencies
  // conjure spells!
}

save points

> cat project/build.properties
#Project properties
#Sat Jan 29 20:16:24 EST 2011
project.organization=nyscala
project.name=fooz
sbt.version=0.7.4
project.version=0.0.1
build.scala.versions=2.8.0
project.initialize=false
lazy val projectOrganization = propertyOptional[String](name, true)
lazy val projectName = propertyLocalF[String](NonEmptyStringFormat)
lazy val sbtVersion = property[String]
lazy val projectVersion = property[Version]
lazy val defScalaVersion = property[String]
lazy val buildScalaVersions = propertyOptional[String](
  defScalaVersion.value, true)

dependency management

> ls lib_managed | wc -l
0

> sbt update

> ls lib_managed | wc -l
{n}

ivy and or maven

(but mostly ivy)

%% and %

and other business

// fixed scala version
val a = "org.a" % "a_2.7.7" % "1.0"

// cross built (a good citizen)
val b = "org.b" %% "a" % "1.0"

// java/maven
val jc = "org.jc" % "jc" % "1.0"

// jar from where evs
val d = "d" % "d" % "2.1" from "http://somehost.com/2.1/d.jar"

phone out, phone home

val x = "repo name" at "path"

val scalaToolsSnapshots =
  "Scala-Tools Maven2 Snapshots Repository" at
    "http://scala-tools.org/repo-snapshots"

val m2 = "Local M2" at
  "file://%s/.m2/repository" format Path.userHome

publishing

> cat /project/build/Project.scala
import sbt._

class Project(info: ProjectInfo)
  extends DefaultProject(info) {
  override def managedStyle = ManagedStyle.Maven
  val publishTo =
   "Repoz" at "http://you.com/repos/releases/"
  Credentials(Path.userHome / ".ivy2" / ".credentials", log)
}

> sbt +publish

thank you for being a friend

> cat project/build.properties | grep versions
build.scala.versions 2.8.1 2.8.0 2.7.7

> sbt +update
> sbt +compile
> sbt +publish

think global,

publish local

> sbt +publish-local # publish your project locally

> mvn -o # maven's offline mode

tasks

speak louder than words

discovery

list actions

> sbt actions

> rake -T # rake's task:description listing

watch it mister!

continuous execution

> sbt ~test

teach sbt to speak

lazy val say = task { args =>
  args match {
    case Array() => task { Some("say what?") }
    case _ => task {
      new java.lang.ProcessBuilder(
        ("say" :: args.toList).toArray:_*).start
      None
    }
  }
} describedAs("chatty")

speak sbt, speak!

sbt 'say i am in your codez'

plugins

sharing is caring

make

> cat project/build/ChattyProject.scala
import sbt._

class ChattyProject(info: ProjectInfo) extends PluginProject(info)

> cat src/main/scala/Chatty.scala
package nyscala

import sbt._

trait Chatty extends Project {
 lazy val say = task { ... }
}

take

> cat project/plugins/Plugins.scala
import sbt._

class Plugins(info: ProjectInfo) extends PluginDefinition(info) {
  val repo = "repoz" at  "http://host.com/repos"
  val chatty = "nyscala" % "chatty" % "1.0.0"
}

> cat project/build/Project.scala
import sbt._

class Fooz(info: ProjectInfo)
  extends DefaultProject(info)
  with nyscala.Chatty {
  // you can now make sbt speak
}

fin

> sbt update run