轻快的SBT

Sbt是当前Scala项目的标准构建工具

Session目的

  1. 了解sbt中让人感觉轻松愉快的部分
  2. 以最小的学习成本帮助我们处理scala项目

http://scala-sbt.org

The interactive build tool

Use Scala to define your tasks. Then run them in parallel from the shell.

Sbt 全称

  1. Simple Build Tool
  2. Scala Build Tool
  3. The interactive build tool

or

S(i) B(ian) T(ai)

Sbt的复杂来源于

  1. 糟糕的文档: 没有实例,抽象描述,冗长,不准确
  2. 初学者不友好: 无向导工具,无模板项目
  3. 混乱的版本: sbt & scala
  4. 各种奇怪操作符: :=, +=, ++=, <<=
  5. 混乱的结构: *.sbt, project/*.scala, ~/.sbt/0.13/plugins/*

以及

  1. 各种编译错误: Sbt是一套类型安全的scala DSL
  2. 复杂的key机制: settingKey, taskKey, inputKey
  3. 复杂的scope: project scope, config scope, inkey scope

Sbt很努力,只是Scala世界很复杂

让我们开始SBT轻快之旅吧!

  1. 一条命令SBT安装
  2. 零配置运行一个Scala程序
  3. 一条命令生成新项目
  4. 快速添加依赖
  5. 快速生成Idea项目
  6. 一条命令让项目内置sbt脚本
  7. Sbt好插件
  8. 轻松支持多项目
  9. 轻松解读配置文件基本规则
  10. 自定义极简单的任务

1. SBT安装

安装:

brew install sbt

升级:

brew update sbt

2. 零配置运行一个Scala程序

touch Hello.scala

内容如下:

object Hello extends App {
    println("Hello, sbt!")
}

运行:

$ sbt run
Hello, sbt!

3. 一条命令生成新项目

~/.sbt/0.13/plugins/np.sbt

resolvers += Resolver.url("sbt-np",
  url("http://scalasbt.artifactoryonline.com/scalasbt/sbt-plugin-releases/"))(
    Resolver.ivyStylePatterns)

addSbtPlugin("me.lessis" % "np" % "0.2.0")

~/.sbt/0.13/np.sbt

seq(npSettings: _*)

$ sbt np

生成:

├── build.sbt
└── src
    ├── main
    │   ├── resources
    │   └── scala
    └── test
        ├── resources
        └── scala

build.sbt

organization := "mytest"

name := "default"

version := "0.1-SNAPSHOT"

4. 快速添加依赖

build.sbt

resolvers ++= Seq(
  "ibiblio" at "http://mirrors.ibiblio.org/pub/mirrors/maven2",
  "Sonatype snapshots" at "https://oss.sonatype.org/content/repositories/snapshots/",
  "Sonatype releases" at "http://oss.sonatype.org/content/repositories/releases"
)

libraryDependencies ++= Seq(
  "org.scalaz" %% "scalaz-core" % "7.1.0",
  "org.specs2" %% "specs2" % "2.3.13" % "test"
)

$ sbt
> update
> gen-idea

5. 快速生成Idea项目

~/.sbt/0.13/plugins/sbt-idea.sbt

addSbtPlugin("com.github.mpeltonen" % "sbt-idea" % "1.6.0")

不下载源代码

$ sbt gen-idea

下载源代码:

$ sbt 
> gen-idea sbt-classifiers

用idea打开:

idea .

6. 一条命令让项目内置sbt脚本

curl -s https://raw.githubusercontent.com/paulp/sbt-extras/master/sbt > sbt
chmod 0755 sbt

$ ./sbt
Downloading sbt launcher for 0.13.6:
  From  http://typesafe.artifactoryonline.com/typesafe/ivy-releases/org.scala-sbt/sbt-launch/0.13.6/sbt-launch.jar
    To  /Users/freewind/.sbt/launchers/0.13.6/sbt-launch.jar
Getting org.scala-sbt sbt 0.13.6 ...
:: retrieving :: org.scala-sbt#boot-app
    confs: [default]
    44 artifacts copied, 0 already retrieved (13750kB/150ms)
[info] Loading global plugins from /Users/freewind/.sbt/0.13/plugins
[info] Updating {file:/Users/freewind/.sbt/0.13/plugins/}global-plugins...
[info] Resolving org.scala-sbt.ivy#ivy;2.3.0-sbt-14d4d23e25f354cd296c73bfff40554[info] Resolving org.fusesource.jansi#jansi;1.4 ...
[info] Done updating.
[info] Set current project to default (in build file:/private/tmp/mytest/)

7. Sbt好插件

  1. 创建新项目: https://github.com/softprops/np
  2. 生成IDEA项目:https://github.com/mpeltonen/sbt-idea
  3. 显示dependency: https://github.com/jrudolph/sbt-dependency-graph
  4. 查看项目文件数量统计:https://github.com/orrsella/sbt-stats

  1. Git支持:https://github.com/sbt/sbt-git
  2. 把build.sbt中信息自动生成scala: https://github.com/sbt/sbt-buildinfo
  3. 打包成一个jar: https://github.com/sbt/sbt-assembly

更多:

http://www.scala-sbt.org/0.13/docs/Community-Plugins.html

8. 轻松支持多项目

$ sbt
> np name:root
> np name:core dir:core
> np name:util dir:util

├── build.sbt
├── src
│   ├── main
│   │   ├── resources
│   │   └── scala
│   └── test
│       ├── resources
│       └── scala
├── core
│   ├── build.sbt
│   └── src
└── util
    ├── build.sbt
    └── src

添加对子项目的引用

build.sbt

lazy val core = project

lazy val util = project

9. 轻松解读配置文件基本规则

build.sbt

name := "hello"

version := "1.0"

organization := "org.my"

scalaVersion := "2.11.0"

sbtVersion := "0.13.5"

规则

  1. 以空行分隔两个定义
  2. 可使用预定义的key,也可以自定义key
  3. 使用:=给一个key赋值
  4. 可以将一个key定义成一个task
  5. 会将*.sbt, *.scala, project/*.sbt, project/*.scala内容合并

10. 自定义极简单的任务

lazy val hello = taskKey[Unit]("An example task")

hello := { println("Hello, world") }

运行

$ sbt
> hello
Hello, world!

Task:显示根目录下的文件

lazy val showRootFiles = taskKey[Unit]("Show root files")

showRootFiles := {
  baseDirectory.value.listFiles.foreach(println)
}

运行

$ sbt
> showRootFiles
/private/tmp/mytest/.idea
/private/tmp/mytest/.idea_modules
/private/tmp/mytest/.sbt
/private/tmp/mytest/build.sbt
/private/tmp/mytest/core
/private/tmp/mytest/project
/private/tmp/mytest/src
/private/tmp/mytest/target
/private/tmp/mytest/util

更多文档(后面的简单,从最后一个看起)

  1. sbt中读懂inspect的输出
  2. 理解sbt的scopes
  3. 如何创建一个简单的sbt插件
  4. 如何在build.sbt中调用其它scala中定义的值
  5. 在Build.scala中定义多个子项目
  6. sbt多个子项目的build.sbt是如何处理的
  7. 使用build.sbt配置多个子项目

  1. sbt中build.sbt和Build.scala配合使用
  2. sbt中如何创建一个最简单的Build.scala
  3. 在sbt中声明依赖时同时下载源代码
  4. 在sbt中使用一个不在maven库中的jar作为依赖
  5. 如何在build.sbt中执行一段初始化代码
  6. build.sbt中有哪些操作符可用
  7. 可放在项目代码中的sbt脚本
  8. 用脚本快速初始化一个sbt项目的结构

  1. 基本的build.sbt配置
  2. 无需任何配置,直接使用sbt运行一个scala文件
  3. 如何在定义sbt任务时,使用其它key的值
  4. 如何在sbt中定义一个最简单的hello world任务
  5. sbt预定义的keys