När man börjar utveckla i Scala dröjer det inte länge innan man behöver ett byggverktyg. Maven kommer med fullt javastöd  men för att kompilera Scala behövs maven-scala-pluginen. Det  gör att man börjar undra om det finns ett byggverktyg med fullt inbyggt stöd för Scala och det gör det, Simple Build Tool, eller SBT. På code.google.com finns SBT att ladda ner och bra engelsk dokumentation för installation och handhavande. SBT liknar Maven väldigt mycket; samma konvention för hur filerna ska organiseras, de flesta av Mavens kommandon har direkta motsvarigheter i SBT. Så istället för mvn compile skriver man sbt compile. SBT kan använda Mavens repositories, till och med Mavens pom.xml för beroendehantering. Det gör att det är väldigt enkelt att testa SBT i ett befintligt Maven-projekt.

Så vilka fördelar har SBT framför Maven, förutom att kompilera både scala- och javakod utan plugin-konfiguration?

  • Går att köra interaktivt
  • Skriva konfigurationen i Scala
  • Stöd för kontinuerlig test
  • Köra Scalas REPL med beroenden

Går att köra interaktivt

Ofta när jag kör Maven tycker jag att den tar lite väl lång tid på sig. En av anledningarna är att en jvm ska starts och det tar tid. I SBT finns möjligheten att starta interaktivt med kommandot sbt
Då får man en sbt-prompt där man kan köra compile, test etc interaktivt. Jag har gjort en liten mätning på hur lång tid olika kommandon tar i Maven och SBT.

KommandoMavenSBTSBT interaktiv
clean, compile14 s12 s4 s
compile3 s1 s0 s
Som synes går det fortare att köra interaktivt.

Skriva konfigurationen i Scala

I Maven, skriver man konfigurationen i xml. I SBT skriver man i Scala. Det ser ut så här i Maven:

<dependency>
    <groupId>junit</groupId> 
    <artifactId>junit</artifactId> 
    <version>4.7</version>
    <scope>test</scope>
</dependency>

Och i SBT blir det:

val junit = "junit" % "junit" % "4.7" % "test"

Vill man dessutom att SBT ska ladda ner källkoden till beroendena så lägger man till withSources():

val junit = "junit" % "junit" % "4.7" % "test" withSources()

Det blir betydligt kompaktare och det gäller för resten av konfigurationen också. I mitt lilla Scala projekt trl8 är pom.xml på 191 rader och SBTs konfigfil på 26 rader scalakod. Att man skriver i Scala innebär också att du har hela språket till ditt förfogande i konfigurationen.Vill du att din konfiguration ska vara beroende på valutakursen så går det att skriva.

Stöd för kontinuerlig test

SBT kommer med stöd för ScalaCheckspecs och ScalaTest. Dessutom finns det en underbar liten finess, om du prefixerar ett kommando med ~ så betyder det: Kör kommandot varje gång någon källkodsfil ändras. En praktisk användning är givetvis vid testdriven utveckling. Kör sbt ~test i ett terminalfönster och börja skriv dina testfall och kod. Varje gång du sparar en fil så körs testfallen.

Köra Scalas REPL med beroenden

I Scala brukar man testa saker i REPL, Read-Eval-Print-Loop, det är helt enkelt ett interaktivt scala-shell där man kan skriva scalakod direkt  på samma sätt som till exempel med Python. I SBT finns kommandot console som startar en REPL med projektets alla klasser och beroenden i classpathen. Mycket trevligt för att interaktiv prova sig fram.

Pluginer och processorer

SBT går givetvis att utöka om man inte hittar det man vill ha. Man skiljer på pluginer, aktiva per projekt och processorer, aktiva för alla projekt. En trevlig processor är coverage som ger en html-vy av vilken täckningsgrad dina testfall har. Kortfattade instruktion, starta sbt och skriv

undercoverRepo at http://undercover.googlecode.com/svn/maven/repository/ coverage is com.proinnovate sbt-coverage 0.1 coverage

Du bör få en ny sida öppnad i din standardwebläsare med en testfallstäckningsrapport. Nästa gång du vill köra räcker det med sbt coverage.

Sammanfattning

Det jag berört i den här artikeln är det som jag har använt av SBT. Det finns mycket mer och mycket som utvecklas. Titta på SBT’s hemsida på code.google.com. SBT erbjuder Scala-programmeraren byggverktyg som slår Maven med hästlängder. Givetvis får vi se vad Maven 3 har i bakfickan.