Sbt構建工具常用操作

五柳-先生發表於2016-01-26

概述

  作為Scala的標準構建工具,使用風格與Maven類似,由Scala語言寫的,參考官方網站,目前的版本是0.13,雖然說Scala的專案可以通過Maven來構建和管理,但是依然推薦Sbt,更適合一些。

安裝

  有兩種安裝方式,標準版本的sbt只有基礎的工具,構建工程和編譯打包等需要的額外的工具在需要的時候會自動下載,比如說需要用2.11的版本來編譯scala程式碼,就回下載當前最新的scala-2.11.7的:

  1. 獨立的sbt-launch安裝,Windows/Mac/Linux都有對應的安裝過程,也是官方的標準工具,包含了sbt標準的命令;
  2. 通過安裝typesafe activator,typesafe是一家商業公司,他們釋出的這個工具包含了sbt,同時擴充套件了這個工具,包含了兩個新的命令activator ui和activator new.
    1. activator ui可以通過檢視的方式來管理構建的工程,在ui上可以檢視專案模板、建立、執行、測試工作區內的專案,比較方便,另外typesafe提供了大量的教程程式碼,針對akka/play的不同的功能特性都有一些example程式碼,可以直接通過ui下載教程檢視;
    2. activator new可以快速的建立專案,類似於maven通過選擇archetype來快速建立專案,typesafe提供了很多種模板,包括了web專案,akka, spark,hadoop等等template,根據需要可以選擇一種原型作為基礎來修改。

配置

  sbt雖然預設使用的是maven的倉庫,但是是使用ivy來管理依賴,預設的本地快取也是使用的是ivy的目錄結構,與maven的.m2目錄不同,是在使用者目錄下的.ivy目錄下,這樣會導致如果本地既有maven專案又有sbt的專案,很多jar會存在兩份,浪費空間。優點在於ivy支援更智慧的依賴解析方式,比如版本號支援區間的形式,[2.4.0,)代表ivy會選擇一個在你設定的約束範圍內最新的模組下載,保持自動更新。
  需要注意的是除了快取的目錄不同,如果我們要使用公司內部的nexus伺服器來下載依賴模組,需要的配製也與maven不同,maven使用的是.m2/settings.xml來管理全域性配製,設定中央倉庫,自定義的倉庫以及驗證的使用者名稱密碼等。sbt的配製都在.sbt目錄下,除了自身需要的boot launchers目錄,需要新增或者修改兩個檔案:

1. Repositories配置

  repositories 全域性的resolvers倉庫地址,預設的只有maven2的central repository,這裡我們需要加上一些自己的配製,才能夠使用我們自己的nexus倉庫,當然也可以在自己的專案具體的build.sbt裡邊增加,不過鑑於這個是全域性配置放在這裡比較方便:
[repositories] local oschina:http://maven.oschina.net/content/groups/public/ oschina-ivy:http://maven.oschina.net/content/groups/public/, [organization]/[module]/(scala_[scalaVersion]/)(sbt_[sbtVersion]/)[revision]/[type]s/[artifact](-[classifier]).[ext] sbt-releases-repo: http://repo.typesafe.com/typesafe/ivy-releases/, [organization]/[module]/(scala_[scalaVersion]/)(sbt_[sbtVersion]/)[revision]/[type]s/[artifact](-[classifier]).[ext] sbt-plugins-repo: http://repo.scala-sbt.org/scalasbt/sbt-plugin-releases/, [organization]/[module]/(scala_[scalaVersion]/)(sbt_[sbtVersion]/)[revision]/[type]s/[artifact](-[classifier]).[ext] maven-central: http://repo1.maven.org/maven2/ maven-releases: http://teamwork.kmtongji.com/nexus/content/groups/public
  在上邊的例子中,我們包含了7個倉庫,在下載依賴的時候會按照上邊的順序,首先檢查local的目錄下有沒有,如果沒有優先選擇oschina->sbt->maven官方的地址去下載,oschina是國內的一個映象,同步速度和頻寬都不錯,一般情況可以替代官方的倉庫,而我們內部的nexus放到了最後,當然這個順序根據實際情況可以自己調節,因為我們本地的nexus也快取了大量的模組,可以把他放到靠前的位置。

2. Http authentication for local repositories

  一般情況我們本地的nexus倉庫都是有閘道器密碼的,不能隨便訪問,因此如果sbt在下載的時候需要指定credential,因為sbt本身是一種類似scala的語言,通常用程式來實現就是在build.sbt加上這麼一行:
Credentials.add("Sonatype Nexus Repository Manager", "nexusHostIp", "nexususername", "nexuspassword")
更好的辦法是把credential放到一個檔案:
credentials += Credentials(Path.userHome / ".ivy2" / ".credentials")
但是這樣需要在所有的工程裡邊加這麼一句,很是麻煩,作為通用的配製,我們可以讓他在更基礎的檔案裡邊呼叫,因此最終的方法如下,先把credential放到一個檔案,這裡我們選擇的是~/.sbt/.credentials, 內容如下:
realm=Sonatype Nexus Repository Managerhost=teamwork.kmtongji.comuser=xxxxxpassword=xxxxx
接下來我們在sbt配置目錄下建立一個公共呼叫的檔案~/.sbt/0.13/plugins/credentials.sbt,內容如下:
credentials += Credentials(Path.userHome / ".sbt" / ".credentials")
將呼叫放到底層載入過程中,因此具體的credentials檔案放到哪裡不那麼重要,重點是呼叫這行程式碼,可以隱含的載入預設的credentials
上邊只這展示了一個的例子,通過realm來匹配驗證的使用者名稱密碼,只對http basic authentication有效,如果需要多個realm,應該也可以通過toml的配製方式增加[xxxx]的section區分,並沒有測試過,只是猜測。

build.sbt

  sbt生成的程式碼目錄結構與maven類似,只是會多一個project目錄,最外層是整個專案的構建的build.sbt檔案,再project目錄下會有plugin.sbt用來控制plugin的載入。對於單個工程的專案構建只需要在build.sbt裡邊直接寫相關的settings,包括名字,依賴關係等,不需要外層的變數,不過更多時候我們需要多專案工程構建,這就需要有一個根專案以及裡邊的子模組,模組之間存在一定的依賴關係,這就需要每個工程對應一個變數,一般我們會用lazy val來生命,只有在用到的時候才會載入這部分,整個檔案就是一個簡單的指令碼程式,不再多說。
整個結構一般情況下包含三部分,

  • common settings, 這個配製會被其他的工程所使用,可以在後續覆蓋其中一部分配製,
  • root專案,用來表明這是一個多工程的專案,列舉出他所包含的工程,在根目錄執行sbt compile等命令的時候會按順序將子模組也進行相關的處理,一般也在這部分啟動或者禁用某些外掛
  • 最後就是各個專案的定義或者說自定義的task了

plugin.sbt

  這個檔案比較簡單,一行行的包含了所新增的外掛,外掛的啟用禁用可以在build檔案裡邊控制,舉例說明:
addSbtPlugin("com.typesafe.sbt" % "sbt-native-packager" % "1.0.3")

常用命令

  sbt批處理的命令與maven有很多相似,不過sbt有兩種模式,一種互動介面,輸入sbt進入之後,可以在新的shell輸入各種命令,一種是批處理命令例如sbt clean compile 與maven類似,sbt還有一種可以實時編譯的命令 ~compile在檔案改動後會自動編譯,且是增量編譯,比較方便。
常用的命令包括clean compile test run package console reload help,需要特別注意的是run命令,預設情況執行run命令,這個task所執行的jvm與當前sbt自身執行的jvm是同一個,如果需要給run task設定單獨的javaOptions並獨立出一個程式來執行,則需要特殊的宣告,在build.sbt中舉例,比如一個工程的settings:
.settings( name := "aco-queen", javaOptions += "-Dconfig.resource=./queen.conf", // Do not work, you have to run with 'sbt -Dconfig.resource=./queen.conf queen/run' fork in(Test, run) := true, // To enable java options , fork run process to a new jvm separated with sbt)
注意其中的javaOptions要生效,前提是有下邊的fork語句,在run和test的時候fork新的程式來執行。

當然之前的javaOptions並沒有生效,其實如果是指定一些property直接在sbt命令裡邊加上就好,會傳遞給具體的jvm虛擬機器裡邊,類似於直接使用java -Dxxxx=xxxx

轉載:http://www.jianshu.com/p/9494aecebc8d

相關文章