SBT <<= (Build) { FTW }
        @indrajitr
SBT
• Build tool on Scala for building Scala-Java projects

• Compliant with Maven's convention (mostly)

• Basics done right

• Easy to set up for simple projects (intrusive)

• Shares a *lot* with Scala




                                 Bay Area Scala Enthusiasts Meeting #42 (10-10-11)
Build Definitions
• Simple: Quick DSL

• Diabolical: Scala code (with embedded DSL)

• And the shell rocks




                              Bay Area Scala Enthusiasts Meeting #42 (10-10-11)
Build Definitions
<base>/*.sbt

<base>/project/*.scala

<base>/project/plugins.sbt

<base>/project/plugins/*.(scala|sbt)

~/.sbt/plugins/*.(scala|sbt)




                          Bay Area Scala Enthusiasts Meeting #42 (10-10-11)
build.sbt
organization := "net.liftweb"

name       := "lift-demo"

version    := "1.0"

scalaVersion := "2.9.1"

libraryDependencies ++=

  Seq("net.liftweb" %% "lift-webkit" % "2.4-M4",

 "org.eclipse.jetty" % "jetty-webapp" % "7.3.0.v20110203" % "jetty")
                            Bay Area Scala Enthusiasts Meeting #42 (10-10-11)
project/build.scala
import sbt._

object LiftBuild extends Build {

    lazy val projects: Seq[ProjectReference] = Seq(common, actor, json)

    lazy val framework = Project("lift-framework", file(".")).aggregate(projects)

    lazy val common = Project(“lift-common”, file(“core/common”)).settings(/*...*/)

    lazy val actor = Project(“lift-actor”, file(“core/actor”)).dependsOn(common).settings(/*...*/)

    lazy val json = Project("lift-json", file("core/json")) dependsOn(common % "test")

    //lazy val foo = Project("lift-foo", file("core/foo"), delegates = common :: Nil)

}

                                        Bay Area Scala Enthusiasts Meeting #42 (10-10-11)
The Expression
Reminder:

Statement ≠ Expression

  Statement:

    val foo = bar + baz

  Expression:

    bar + baz


                          Bay Area Scala Enthusiasts Meeting #42 (10-10-11)
The Expression
The expression:

organization <<= organization or normalizedName.identity

Is a: Project.Setting[S]

And <<= is thus:

final def <<= (app: Initialize[S]): Setting[S]

for: InputKey, SettingsKey


                             Bay Area Scala Enthusiasts Meeting #42 (10-10-11)
The Emojis
                The ONE




    <<=
Bay Area Scala Enthusiasts Meeting #42 (10-10-11)
The Emojis
  And the rest

  := += ++= <+= <++= ~=
• Initialize ( := )


• Append ( += ++= <+= <++= )


• Update ( ~= )



                      Bay Area Scala Enthusiasts Meeting #42 (10-10-11)
Scoped Keys
sealed trait Key[T] extends Scoped

final class SettingKey[T] extends Key[T] with ScopedSetting[T]

final class TaskKey[T] extends Key[T] with ScopedTask[T]

final class InputKey[T] extends Key[InputTask[T]] with ScopedInput[T]




                          Bay Area Scala Enthusiasts Meeting #42 (10-10-11)
Examples
name := "lift-demo"

name ~= formalize

resolvers in GlobalScope += JavaNet2Repository

scalacOptions ++= Seq("-encoding", "UTF-8")

resolvers <++= isSnapshot { s => if (s) Seq(ScalaToolsSnapshots) else Nil }

inceptionYear <<= inceptionYear ?? Some(2011)

organization <<= organization or normalizedName.identity
                            Bay Area Scala Enthusiasts Meeting #42 (10-10-11)
Examples
libraryDependencies <<= (libraryDependencies, scalaVersion) apply { (ld, sv) =>
ld :+ scalap(sv) })

libraryDependencies <+= (scalaVersion)(scalap)

libraryDependencies <+= scalaVersion apply scalap

scalacOptions /*in GlobalScope*/ in doc <++= (name in doc, version in doc) map
(Seq("-doc-title", _, "-doc-version", _))




                         Bay Area Scala Enthusiasts Meeting #42 (10-10-11)
Settings are Scoped!
def in(s: Scope): Result // ScopedSetting, ScopedTask, ScopedInput

def in(p: Reference): Result

def in(t: Scoped): Result

def in(c: ConfigKey): Result

def in(c: ConfigKey, t: Scoped): Result

def in(p: Reference, c: ConfigKey): Result

def in(p: Reference, t: Scoped): Result

def in(p: Reference, c: ConfigKey, t: Scoped): Result

def in(p: ScopeAxis[Reference], c: ScopeAxis[ConfigKey], t: ScopeAxis[AttributeKey[_]]): Result

                                      Bay Area Scala Enthusiasts Meeting #42 (10-10-11)
Miscellaneous
MOAR Emojis (in shell)!

~ + ++ ; ! < -

Plugin, State, Life, Universe and everything else




                            Bay Area Scala Enthusiasts Meeting #42 (10-10-11)
Lost?
 Befriend ‘em

• Defaults.scala

• Keys.scala

• IDE




                   Bay Area Scala Enthusiasts Meeting #42 (10-10-11)
Exercise
Questions?

Simple Build Tool Introduction

  • 1.
    SBT <<= (Build){ FTW } @indrajitr
  • 2.
    SBT • Build toolon Scala for building Scala-Java projects • Compliant with Maven's convention (mostly) • Basics done right • Easy to set up for simple projects (intrusive) • Shares a *lot* with Scala Bay Area Scala Enthusiasts Meeting #42 (10-10-11)
  • 3.
    Build Definitions • Simple:Quick DSL • Diabolical: Scala code (with embedded DSL) • And the shell rocks Bay Area Scala Enthusiasts Meeting #42 (10-10-11)
  • 4.
  • 5.
    build.sbt organization := "net.liftweb" name := "lift-demo" version := "1.0" scalaVersion := "2.9.1" libraryDependencies ++= Seq("net.liftweb" %% "lift-webkit" % "2.4-M4", "org.eclipse.jetty" % "jetty-webapp" % "7.3.0.v20110203" % "jetty") Bay Area Scala Enthusiasts Meeting #42 (10-10-11)
  • 6.
    project/build.scala import sbt._ object LiftBuildextends Build { lazy val projects: Seq[ProjectReference] = Seq(common, actor, json) lazy val framework = Project("lift-framework", file(".")).aggregate(projects) lazy val common = Project(“lift-common”, file(“core/common”)).settings(/*...*/) lazy val actor = Project(“lift-actor”, file(“core/actor”)).dependsOn(common).settings(/*...*/) lazy val json = Project("lift-json", file("core/json")) dependsOn(common % "test") //lazy val foo = Project("lift-foo", file("core/foo"), delegates = common :: Nil) } Bay Area Scala Enthusiasts Meeting #42 (10-10-11)
  • 7.
    The Expression Reminder: Statement ≠Expression Statement: val foo = bar + baz Expression: bar + baz Bay Area Scala Enthusiasts Meeting #42 (10-10-11)
  • 8.
    The Expression The expression: organization<<= organization or normalizedName.identity Is a: Project.Setting[S] And <<= is thus: final def <<= (app: Initialize[S]): Setting[S] for: InputKey, SettingsKey Bay Area Scala Enthusiasts Meeting #42 (10-10-11)
  • 9.
    The Emojis The ONE <<= Bay Area Scala Enthusiasts Meeting #42 (10-10-11)
  • 10.
    The Emojis And the rest := += ++= <+= <++= ~= • Initialize ( := ) • Append ( += ++= <+= <++= ) • Update ( ~= ) Bay Area Scala Enthusiasts Meeting #42 (10-10-11)
  • 11.
    Scoped Keys sealed traitKey[T] extends Scoped final class SettingKey[T] extends Key[T] with ScopedSetting[T] final class TaskKey[T] extends Key[T] with ScopedTask[T] final class InputKey[T] extends Key[InputTask[T]] with ScopedInput[T] Bay Area Scala Enthusiasts Meeting #42 (10-10-11)
  • 12.
    Examples name := "lift-demo" name~= formalize resolvers in GlobalScope += JavaNet2Repository scalacOptions ++= Seq("-encoding", "UTF-8") resolvers <++= isSnapshot { s => if (s) Seq(ScalaToolsSnapshots) else Nil } inceptionYear <<= inceptionYear ?? Some(2011) organization <<= organization or normalizedName.identity Bay Area Scala Enthusiasts Meeting #42 (10-10-11)
  • 13.
    Examples libraryDependencies <<= (libraryDependencies,scalaVersion) apply { (ld, sv) => ld :+ scalap(sv) }) libraryDependencies <+= (scalaVersion)(scalap) libraryDependencies <+= scalaVersion apply scalap scalacOptions /*in GlobalScope*/ in doc <++= (name in doc, version in doc) map (Seq("-doc-title", _, "-doc-version", _)) Bay Area Scala Enthusiasts Meeting #42 (10-10-11)
  • 14.
    Settings are Scoped! defin(s: Scope): Result // ScopedSetting, ScopedTask, ScopedInput def in(p: Reference): Result def in(t: Scoped): Result def in(c: ConfigKey): Result def in(c: ConfigKey, t: Scoped): Result def in(p: Reference, c: ConfigKey): Result def in(p: Reference, t: Scoped): Result def in(p: Reference, c: ConfigKey, t: Scoped): Result def in(p: ScopeAxis[Reference], c: ScopeAxis[ConfigKey], t: ScopeAxis[AttributeKey[_]]): Result Bay Area Scala Enthusiasts Meeting #42 (10-10-11)
  • 15.
    Miscellaneous MOAR Emojis (inshell)! ~ + ++ ; ! < - Plugin, State, Life, Universe and everything else Bay Area Scala Enthusiasts Meeting #42 (10-10-11)
  • 16.
    Lost? Befriend ‘em •Defaults.scala • Keys.scala • IDE Bay Area Scala Enthusiasts Meeting #42 (10-10-11)
  • 17.
  • 18.

Editor's Notes

  • #2 The title is actually valid SBT expression\nSkipping lots of things to make room for more important ones in 45 min\nBasic things and then SBT code\nNo FP details (unless something slips out)\n\n
  • #3 It&amp;#x2019;s SIMPLE once you get past the initial hoop\nAs crazy and as awesome as scala\nTricky to get going, no looking back when there\n
  • #4 Roughly equivalent to pom.xml\n\nGreat DSL in SBT: Buy DSL in Action or learn SBT for free\n\n
  • #5 \n
  • #6 \n
  • #7 Contents of settings are expressions\n
  • #8 Expressions compose, statements don&amp;#x2019;t\nExpression has a value\n
  • #9 \n
  • #10 \n
  • #11 \n
  • #12 \n
  • #13 \n
  • #14 lazy val scalap: String =&gt; ModuleID = &quot;org.scala-lang&quot; % &quot;scalap&quot; % _\n
  • #15 \n
  • #16 \n
  • #17 \n
  • #18 \n
  • #19 \n