sbt concepts, part 2

22
SBT Concepts, part 2 Renat Bekbolatov @R2D7 - Eastside Scala Meetup - Apr 2015

Upload: renat-bekbolatov

Post on 15-Jul-2015

148 views

Category:

Technology


0 download

TRANSCRIPT

SBT Concepts, part 2Renat Bekbolatov @R2D7 - Eastside Scala Meetup - Apr 2015

Installation

• Pre-reqs: java and scala installed

• http://www.scala-sbt.org/release/tutorial/Setup.html

• sbt runs as a java program: sbt-launch.jar

2

Let’s create an SBT project

• mkdir my_project

• cd my_project

• mkdir -p project src/{main,test}/{scala,java,resources}

• echo “sbt.version=0.13.7” > project/build.properties

3

Directory Structure• “src” contains source and resource

files

• “project” directory contains build

code for this project

• “build.properties” is a key-value

properties file for sbt

• “build.sbt” also contains build

information for this project

• “target” directory (not shown)

contains build products

Image source: http://just-thor.com/2013/11/getting-started-with-a-simple-sbt-project/

build.sbt——————— build.sbt —————————————————————

—————————

name := "MyProj"

version := "1.0"

scalaVersion := “2.11.6”

libraryDependencies += "com.google.guava" % "guava" % "18.0"

—————————————————————————————————

———————————————

Remember from part 1, we are setting values to keys:

KEY := VALUE <——- SETTING

KEY[T] := VALUE <——- SETTING[T] - type of value

5

sbt REPL

% sbt

[info] Loading project definition from my_project/project

[info] Updating {file: my_project/project/}my_project-build...

[info] Resolving org.fusesource.jansi#jansi;1.4 ...

[info] Done updating.

[info] Set current project to MyProj (in build file:my_project/)

(Now we are in sbt REPL)

> name

[info] MyProj

> version

[info] 1.0

>

6

show & inspect

> show name

[info] MyProj

>

> inspect name

[info] Setting: java.lang.String = MyProj <— Type and Value

[info] Description:

[info] Project name.

[info] Provided by:

[info] {file: my_project/}my_project/*:name

[info] Defined at:

[info] my_project/build.sbt:1 <——— Key “name” that

[info] Reverse dependencies: we set in build.sbt

[info] *:projectInfo

[info] *:normalizedName

[info] *:onLoadMessage

[info] *:description

[info] Delegates: <——— Delegates (more on this later)

[info] *:name

[info] {.}/*:name

[info] */*:name

>

7

src/main/scala/StringSplit.scala————————————————————————————————-

StringSplit.sbt ———————————

package example

import com.google.common.base.Splitter

import scala.collection.JavaConversions._

object StringSplit extends App {

println("hello")

val parts = Splitter.on(',')

.trimResults()

.omitEmptyStrings()

.split("foo,bar,, baz")

parts.foreach { part => println(s"Part: $part")}

}————————————————————————————————————

————————————————-———————8

compile & run% sbt[info] Loading project definition from my_project/project

[info] Set current project to MyProj (in build file:my_project/)

> compile[info] Updating {file:my_project/}my_project...

[info] [SUCCESSFUL ] com.google.guava#guava;18.0!guava.jar(bundle) (28ms)

[info] Done updating.

[info] Compiling 1 Scala source to my_project/target/scala-2.11/classes...

[info] 'compiler-interface' not yet compiled for Scala 2.11.6. Compiling...

[info] Compilation completed in 12.713 s

[success] Total time: 48 s, completed Apr 1, 2015 2:41:55 PM

> run[info] Updating {file:my_project/}my_project...

[info] Resolving jline#jline;2.12.1 ...

[info] Done updating.

[info] Compiling 1 Scala source to my_project/target/scala-2.11/classes...

[info] Running example.StringSplit

hello

Part: foo

Part: bar

Part: baz

[success] Total time: 5 s, completed Apr 1, 2015 3:04:05 PM

>

9

package

> package

[info] Compiling 1 Scala source to my_project/target/scala-2.11/classes...

[info] Packaging my_project/target/scala-2.11/myproj_2.11-1.0.jar ...

[info] Done packaging.

[success] Total time: 1 s, completed Apr 1, 2015 3:21:59 PM

> exit

(Now we are in shell)

% ls -lh target/scala-2.11

drwxr-xr-x 3 renat renat 102B Apr 1 15:21 classes

-rw-r--r-- 1 renat renat 4.2K Apr 1 15:21 myproj_2.11-1.0.jar

10

List available tasks

(Now we are in sbt REPL)

> tasks

This is a list of tasks defined for the current project.

It does not list the scopes the tasks are defined in; use the 'inspect' command for that.

Tasks produce values. Use the 'show' command to run the task and print the resulting value.

clean Deletes files produced by the build, such as generated sources, comp…

compile Compiles sources.

console Starts the Scala interpreter with the project classes on the classpath.

… [truncated]

11

console> console

[info] Starting scala interpreter...

[info]

Welcome to Scala version 2.11.6 (Java HotSpot(TM)

64-Bit Server VM, Java 1.7.0_60).

Type in expressions to have them evaluated.

Type :help for more information.

(Now we are in Scala console - with main classpath)

scala> import com.google.common.base.Splitter

import com.google.common.base.Splitter

scala> Splitter.on(' ').split("one two three”)

res0: Iterable[String] = [one, two, three]

scala> example.StringSplit.main(Array[String]())

hello

Part: foo

Part: bar

Part: baz

12

More on sbt commands…

• Can issue command directly in shell: “sbt run”

• Can combine commands: “sbt test package”

• clean, publish, publish-local, update, reload

• Plugins can add new keys

13

Build script

So far we have been running only with one file

build.sbt in project’s root directory.

Behind the scenes, sbt created a Project object

and appended the contents of project’s

build.sbt to its settings.

Manually creating a project by creating a Scala

file in project directory…

Build script——————— project/MyBuild.scala ———————————————————————————

import sbt._

import sbt.Keys._

object MyBuild extends Build {

lazy val root = (project in file("."))

.settings(

name := "MyProj",

version := "1.0",

scalaVersion := "2.11.6",

libraryDependencies += "com.google.guava" % "guava" % "18.0"

)

}

—————————————————————————————————————————————————

—————————————

Same definition as before with build.sbt file.

Settings in build.sbt will be applied on top of this.

In fact, any .sbt files in a project, will be merged with the build definition for the entire build, but scoped to that

project.

15

Scopeslazy val commonSettings = Seq(

organization := "com.example",

version := "0.1.0",

scalaVersion := "2.11.4"

)

lazy val core = (project in file("core"))

.dependsOn(util)

.settings(commonSettings: _*)

.settings(

name := "projCore"

// other settings

)

lazy val util = (project in file("util"))

.settings(commonSettings: _*)

.settings(

name := "projUtil"

// other settings

)

Then in sbt:

> util/name

[info] projUtil

> core/name <— {<build-uri>}<project-id>/config:inkey::key

[info] projCore

> util/name

[info] projUtil

>

16

ConfigurationsA configuration defines a flavor of build, potentially with its own classpath, sources, generated

packages, etc.

The configuration concept comes from Ivy, which sbt uses for managed dependencies Library

Dependencies, and from MavenScopes.

Some configurations you’ll see in sbt:

Compile which defines the main build (src/main/scala).

Test which defines how to build tests (src/test/scala).

Runtime which defines the classpath for the run task.

By default, all the keys associated with compiling, packaging, and running are scoped to a

configuration and therefore may work differently in each configuration.

The most obvious examples are the task keys compile, package, and run; but all the keys

which affect those keys (such as sourceDirectories or scalacOptions or fullClasspath) are

also scoped to the configuration.

17

Source: http://www.scala-sbt.org/0.13/tutorial/Scopes.html

Scopes again

In build definition:

scalacOptions in Test ++= Seq(“-unchecked")

In REPL:

Test:scalacOptions

General for in REPL is {<build-uri>}<project-id>/config:intask::key

18

PluginsA plugin extends the build definition, most commonly by adding new settings, possibly new tasks.

For example - if you want to create fat jars, there is a plugin for that: plugin “sbt-assembly”.

In project directory create file “assembly.sbt” with the following:

addSbtPlugin("com.eed3si9n" % "sbt-assembly" % “0.11.2”)

This particular plugin brings in new keys, such as:

assembly, assemblyJarName, assemblyMergeStrategy, …

Now in sbt, you can run “assembly”:

> assembly[info] Including: guava-18.0.jar

[info] Including: scala-library-2.11.6.jar

[info] Checking every *.class/*.jar file's SHA-1.

[info] Merging files...

[warn] Merging 'META-INF/MANIFEST.MF' with strategy 'discard'

[warn] Merging 'META-INF/maven/com.google.guava/guava/pom.properties' with strategy 'discard'

[warn] Merging 'META-INF/maven/com.google.guava/guava/pom.xml' with strategy 'discard'

[warn] Strategy 'discard' was applied to 3 files

[info] SHA-1: db72fdf182c7c5332a145aa4c018466840f9c554

[info] Packaging /Users/renatb/tmp/sm/my_project/target/scala-2.11/MyProj-assembly-1.0.jar ...

[info] Done packaging.

[success] Total time: 5 s, completed Apr 1, 2015 11:51:57 PM

>

19

DelegatesA setting has a key and a scope.

A request for a key in a scope A may be delegated to another scope if A doesn't define a

value for the key.

The delegation chain is well-defined and is displayed in the Delegates section of the inspect

command.

The Delegates section shows the order in which scopes are searched when a value is not

defined for the requested key.

> inspect console::initialCommands

...

[info] Delegates:

[info] *:console::initialCommands

[info] *:initialCommands

[info] {.}/*:console::initialCommands

[info] {.}/*:initialCommands

[info] */*:console::initialCommands

[info] */*:initialCommands

...

20

Useful links

• http://www.scala-sbt.org/0.13/tutorial/index.html

• http://just-thor.com/2013/11/getting-started-with-a-

simple-sbt-project/

• http://www.scala-sbt.org/0.13/tutorial/Full-Def.html

• http://www.scala-sbt.org/0.13.2/docs/Detailed-

Topics/Inspecting-Settings.html

21

Upcoming Meetups

Seattle Spark Meetup

Sparkly Notebook: Interactive Analysis and Visualization with Spark

Wednesday, April 15, 2015 - Avvo - 705 5th Ave South #600, Seattle, WA

Scala at the Sea

Discuss Scala Akka and Related Technologies

Tuesday, April 14, 2015 - Whitepages - 1301 5th Avenue #1600, Seattle, WA

22