8000 add content on custom sbt task · defaultRobot/real_world_scala@21cfe96 · GitHub
[go: up one dir, main page]

Skip to content

Commit 21cfe96

Browse files
committed
add content on custom sbt task
1 parent acfd62f commit 21cfe96

File tree

1 file changed

+86
-1
lines changed

1 file changed

+86
-1
lines changed

02_sbt.markdown

Lines changed: 86 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -360,7 +360,7 @@ object HelloBuild extends Build {
360360
}
361361
```
362362

363-
build的定义只要扩展sbt.Build,然后添加相应的逻辑即可,所有代码都是标准的scala代码,在Build定义中,我们可以添加更多的settings, 添加自定义的task,添加相应的val和方法定义等等, 更多代码实例可以参考SBT Wiki(<https://github.com/harrah/xsbt/wiki/Examples>)。
363+
build的定义只要扩展sbt.Build,然后添加相应的逻辑即可,所有代码都是标准的scala代码,在Build定义中,我们可以添加更多的settings, 添加自定义的task,添加相应的val和方法定义等等, 更多代码实例可以参考SBT Wiki(<https://github.com/harrah/xsbt/wiki/Examples>),另外,我们在后面介绍SBT的更多高级特性的时候,也会引入更多.scala形式的build定义的使用
364364

365365
NOTE
366366

@@ -375,7 +375,92 @@ build的定义只要扩展sbt.Build,然后添加相应的逻辑即可,所有
375375

376376
### 自定义SBT Task
377377

378+
大部分情况下,我们都是使用SBT内建的Task,比如compile, run等,实际上, 除了这些,我们还可以在build定义中添加更多自定义的Task。
378379

380+
自定义SBT的Task其实很简单,就跟把大象关冰箱里一样简单, 概况来说其实就是:
381+
382+
1. 定义task;
383+
2. 将task添加到项目的settings当中;
384+
3. 使用自定义的task;
385+
386+
#### 定义task
387+
388+
Task的定义分两部分,第一部分就是要定义一个TaskKey来标志Task, 第二部分则是定义Task的执行逻辑。
389+
390+
假设我们要定义一个简单的打印"hello, sbt~"信息的task,那第一步就是先定义它的Key,如下代码所示:
391+
392+
```scala
393+
val hello = TaskKey[Unit]("hello", "just say hello")
394+
```
395+
396+
TaskKey的类型指定了对应task的执行结果,因为我们只想打印一个字符串,不需要返回什么数据,所以定义的是TaskKey[Unit]。 定义TaskKey最主要的一点就是要指定一个名称(比如第一个参数“hello”),这个名称将是我们调用该task 10000 标志性建筑。 另外,还可以可选择的通过第二个参数传入该task的相应描述和说明。
397+
398+
有了task对应的Key之后,我们就要定义task对应的执行逻辑,并通过`:=`方法将相应的key和执行逻辑定义关联到一起:
399+
400+
```scala
401+
hello := {
402+
println("hello, sbt~")
403+
}
404+
```
405+
406+
完整的task定义代码如下所示:
407+
408+
```scala
409+
val hello = TaskKey[Unit]("hello", "just say hello")
410+
411+
hello := {
412+
println("hello, sbt~")
413+
}
414+
```
415+
416+
NOTE
417+
418+
:= 只是简单的将task的执行逻辑和key关联到一起, 如果之前已经将某一执行逻辑跟同一key关联过,则后者将覆盖前者,另外,如果我们想要服用其他的task的执行逻辑,或者依赖其他task,只有一个:=就有些力不从心了。这些情况下,可以考虑使用~=或者<<=等方法,他们可以借助之前的task来映射或者转换新的task定义。比如(摘自sbt wiki):
419+
// These two settings are equivalent
420+
intTask <<= intTask map { (value: Int) => value + 1 }
421+
intTask ~= { (value: Int) => value + 1 }
422+
423+
#### 将task添加到项目的settings当中
424+
425+
光完成了task的Key和执行逻辑定义还不够,我们要将这个task添加到项目的Settings当中才能使用它,所以,我们稍微对之前的代码做一补充:
426+
427+
```scala
428+
object ProjectBuild extends Build {
429+
430+
val hello = TaskKey[Unit]("hello", "just say hello")
431+
432+
val helloTaskSetting = hello := {
433+
println("hello, sbt~")
434+
}
435+
436+
lazy val root = Project(id = "", base = file(".")).settings(Defaults.defaultSettings ++ Seq(helloTaskSetting): _*)
437+
438+
}
439+
```
440+
441+
将Key与task的执行逻辑相关联的过程实际上是构建某个Setting的过程,虽然我们也可以将以上定义写成如下形式:
442+
443+
```scala
444+
lazy val root = Project(id = "", base = file(".")).settings(Defaults.defaultSettings ++ Seq(hello := {
445+
println("hello, sbt~")
446+
}): _*)
447+
```
448+
449+
但未免代码就太不雅观,也不好管理了(如果要添加多个自定义task,想想,用这种形式是不是会让代码丑陋不堪那?!),所以,我们引入了helloTaskSetting这个标志常量来帮助我们净化代码结构 :)
450+
451+
#### 测试和运行定义的task
452+
453+
万事俱备之后,就可以使用我们的自定义task了,使用定义Key的时候指定的task名称来调用它即可:
454+
455+
$ sbt hello
456+
hello, sbt~
457+
// 或者
458+
$ sbt
459+
> hello
460+
hello, sbt~
461+
[success] Total time: 0 s, completed Oct 4, 2012 2:48:48 PM
462+
463+
怎么样? 在SBT中自定义task是不是很简单那?!
379464

380465
### SBT插件
381466

0 commit comments

Comments
 (0)
0