sbt 1.2.0
皆さんこんにちは。Lightbend Tooling team にかわって sbt 1.2.0 をアナウンスします。これは sbt 1 のフィーチャーリリース第二弾で、バイナリ互換性は維持しつつ新機能にフォーカスを当てたリリースとなっている。sbt 1 は Semantic Versioning にもとづいてリリースされるので、プラグインは sbt 1.x シリーズ中機能することが期待されている。
- 2018年7月31日に 1.2.0 final 版がリリースされた。
2018年7月6日までに大きな問題が見つからなければ、1.2.0-RC1 は 1.2.0 final 版となる予定だ。
sbt 1.2 の主な新機能はクロスJDK forking、composite project、そして実験的な thin client だ。sbt 1.1 から 6ヶ月の間他にも色々なバグ修正や改善点がたまっていた。
プラグイン開発のための SbtPlugin
SbtPlugin
は、プロジェクトが sbt plugin であることを宣言するためのプラグインだ。これは自動的に scripted test を導入して、sbtPlugin := true
を設定する。
lazy val root = (project in file("."))
.enablePlugins(SbtPlugin)
互換性に関する注意: ScritpedPlugin
は triggered plugin ではなくなった。
クロス JDK forking
run
や test
を fork した場合、java++
を使って Java Home を切り替えれるようになった。
sbt:helloworld> run
[info] Running (fork) Hello
[info] 1.8.0_171
sbt:helloworld> java++ 10!
[info] Reapplying settings...
sbt:helloworld> run
[info] Running (fork) Hello
[info] 10.0.1
sbt は、インストール済みの Java home を検知して discoveredJavaHomes
セッティングに代入し、shyiko/jabba もサポートする。それで不十分な場合は Global / javaHomes
を用いて補足する:
Global / javaHomes += "6" -> file("/something/java-6")
この機能は、ライブラリを古い JDK でテストして互換性の確認を取ることを目的としている。
#4139 by @2m, @cunei, and @eed3si9n
Composite project
sbt 1.2.0 は CompositeProject という trait を導入して、プラグイン作者が、クロスビルドなどのためにサブプロジェクトを生成することを可能とする。
trait CompositeProject {
def componentProjects: Seq[Project]
}
これは @BennyHill さんによって #4056 にてコントリビュートされた。
Project matrix
実験段階。CompositeProject
のレファレンス実装として、projectMatrix
という DSL を導入する sbt-projectmatrix というプラグインを実装した。
lazy val core = (projectMatrix in file("core"))
.scalaVersions("2.12.6", "2.11.12")
.settings(
name := "core"
)
.jvmPlatform()
lazy val app = (projectMatrix in file("app"))
.dependsOn(core)
.scalaVersions("2.12.6")
.settings(
name := "app"
)
.jvmPlatform()
このプラグインはよりジェネリックなクロスビルド (Scala バージョン、プラットフォーム、その他) をサポートして、サブプロジェクトとして表現することを目的としている。上の例の projectMatrix
は coreJVM2_12
、coreJVM2_11
、そして appJVM2_12
という 3つのサブプロジェクトを作る。
Semantic Version selector API
sbt 1.2.0 は、VersionNumber()
データ型に Semantic Version selector を導入し、基本的なマッチ、比較 (<=
, <
, >=
, >
)、論理演算 (>1.0.0 <2.0.0
, ||
)、範囲 (A.B.C - D.E.F
)、ワイルドカード (2.12.x
) をサポートする。
scala> import sbt.librarymanagement.{ VersionNumber, SemanticSelector }
import sbt.librarymanagement.{VersionNumber, SemanticSelector}
scala> VersionNumber("2.12.5").matchesSemVer(SemanticSelector(">=2.12"))
res1: Boolean = true
scala> VersionNumber("2.12.5").matchesSemVer(SemanticSelector("<2.12"))
res2: Boolean = false
scala> VersionNumber("2.13.0-M4").matchesSemVer(SemanticSelector("2.13"))
res3: Boolean = false
scala> VersionNumber("2.12.5").matchesSemVer(SemanticSelector("2.12.1 - 2.12.6"))
res4: Boolean = true
scala> VersionNumber("2.12.5").matchesSemVer(SemanticSelector("2.12.x"))
res5: Boolean = true
scala> VersionNumber("2.12.5").matchesSemVer(SemanticSelector("2.11.x || 2.12.x"))
res6: Boolean = true
これは Rikito Taniguchi (@tanishiking) さんにより lm#239 にてコントリビュートされた。
addPluginSbtFile コマンド
IntelliJ チームからビルドに安全にプラグインを注入したいというリクエストが以前よりあった。sbt 1.2.0 は -addPluginSbtFile
というコマンドを追加してそれを可能とする。
$ cat /tmp/extra.sbt
addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.14.7")
$ sbt -addPluginSbtFile=/tmp/extra.sbt
...
sbt:helloworld> plugins
In file:/xxxx/hellotest/
...
sbtassembly.AssemblyPlugin: enabled in root
これは @eed3si9n により #4211 にて実装された。
拡張可能な sbt server
実験段階。プラグインを用いて sbt server を拡張できるようにした。
Global / serverHandlers += ServerHandler({ callback =>
import callback._
import sjsonnew.BasicJsonProtocol._
import sbt.internal.protocol.JsonRpcRequestMessage
ServerIntent(
{
case r: JsonRpcRequestMessage if r.method == "lunar/helo" =>
jsonRpcNotify("lunar/oleh", "")
()
},
PartialFunction.empty
)
この機能はまだ実験的なので今後 API などが変更される可能性がある。
Thin client(s)
実験段階。sbt 1.2.0 は -client
という新しいモードを追加する。sbt が -client
コマンドとともに実行されると、ビルドを読み込まず、JSON-RPC を用いて sbt server のインスタンスに接続しようとする。サーバが走っていなければ (portfile が見つからなければ) 新たな sbt インスタンスを全く別の新しい JVM 上に fork する。
これによって sbt
をターミナル上、もしくはエディタなどから呼び出すことができる。
$ time sbt -client clean
[info] entering *experimental* thin client - BEEP WHIRR
[info] server was not detected. starting an instance
[info] waiting for the server...
[info] waiting for the server...
[info] waiting for the server...
[info] waiting for the server...
[info] server found
> clean
[success] completed
sbt -client clean 9.23s user 2.33s system 22% cpu 50.558 total
# server stays
$ ps | rg java
21860 ttys015 1:22.43 java -Xms2048M -Xmx2048M -Xss2M -jar /usr/local/Cellar/sbt/1.1.6/libexec/bin/sbt-launch.jar
22014 ttys015 0:00.00 rg java
$ time sbt -client clean
[info] entering *experimental* thin client - BEEP WHIRR
> clean
[info] Updating ...
[info] Done updating.
[success] completed
sbt -client clean 3.39s user 1.75s system 104% cpu 4.898 total
server を終了させるには sbt -client shutdown
を呼び出す。 #4227 by @eed3si9n
さらに、thin client の代替実装も既に出ていて、Rust を用いてクリスさん cb372/sbt-client と Dale dwijnand/sbtl が作っている。
互換性に影響のある変更点
- 廃止勧告が出ていたコマンド
-
、--
、---
を削除した。onFailure
,sbtClearOnFailure
,resumeFromFailure
に移行してほしい。 #4124
その他のバグ修正や改善点
-
タスク出力キャッシングのバグを修正した。 [util#169][util169] by @bpholt
-
“destination file exists” というエラーメッセージが分かりづらいのを修正した。 [lm#255][lm255] by @eed3si9n
-
Command.process(String, State): State
が間違って消されていたので再導入した。 #4023 by @dwijnand -
シャットダウン時
active.json
が削除されない問題を修正した。 #4194 by @veera83372 -
Windows でタイムスタンプを読むときのファイルパーミッションのエラー ("
CreateFile()
failed") を修正した。 io#134 by @cunei -
removeEscapeSequences
におけるStringIndexOutOfBoundsException
を修正した。 util#139 by @dwijnand -
OkHttp の
JavaNetAuthenticator
で null pointer error が出る問題を修正した。 lm#177 by @eed3si9n -
Sonatype がタイムアウトする問題をデフォルトを 1h まで延ばして修正した。 lm#246 by @peterneyens
-
JavaDoc の警告がエラーとしてログに表示される問題を修正した。 zinc#506 by @kaygorodov
-
クラス依存性が存在しない object を含む問題を修正した。 zinc422 by @romanowski
-
廃止された 0.10/0.12 DSL の移行に関するドキュメンテーションへのリンクを修正した。 #3901 by @colindean
-
Global / cancelable
がtrue
に設定された場合の fork されたテストにおける Ctrl-C の取り扱いを修正した。 #4226 by @driquelme -
++ <scala-version> <command>
が互換性のあるサブプロくジェクトのみで<command>
を実行するようにした。 #3698/#3995 by @ruippeixotog -
eviction warning がデフォルトでまとめだけを表示するようにして、
ThisBuild / evictionWarningOptions
で設定を変えれるようにした。 lm211 and #3947 by @exoego -
inThisBuild(...)
,inConfig(C)(...)
,inTask(t)(...)
,inScope(scope)(...)
が可変長変数を受け取るようにした。 #4106 by @dwijnand -
fgRun
とfgRunMain
タスクを追加して sbt 0.13 のrun
と同様に振る舞うようにした。 #4216 by @agaro1121 -
scripted のファイル名として
test.script
とpending.script
もサポートするようにした。 #4220 by @regadas -
アクセスが拒否された場合のエラーメッセージを改善した。 lm#203 by @stephennancekivell
-
Scalac オプションの変更を無視できるオプションを追加した。 zinc#548 by @lukaszwawrzyk
-
コンフィギュレーション軸のための scope filter のファクトリーメソッド
inConfigurationsByKeys
とinConfigurationsByRefs
を追加した。 #3994 -
lastGrep
、loadFailed
、などのコマンドを追加して kebab-case のコマンドを置き換えた。 #4080 by @naferx, #4159 by @Asamsig, and #4169 by @tiqwab -
JUnitXML レポートに timestamp フィールドを追加した。 4154 by @timcharper
-
-Dsbt.offline
がoffline
セッティングを設定するようにした。 #4198 by @eed3si9n
内部実装に関する変更
- コンパイラ警告の削除。 #3087 by @dwijnand
- @dwijnand によるその他のリファクタリング
- Zinc におけるコンパイラ警告の削除。 zinc#493 by @exoego
- 最適化: 不必要な
URI
のコピーをIO.directoryURI
で作らないようにした。 io#132 by @jrudolph - 最適化:
initStringCodecs
で reflect universe の初期化を回避した。 util#153 by @jrudolph - 最適化:
Parsers.validID
の高速化。 #3952 by @jrudolph - 最適化: Scope の委譲を最適化するために
for
内包表記を自前で展開した。 #4003 by @jrudolph and @eed3si9n
Scala Spree NYC
2018年6月19日に Scala Days の周辺イベントとして Scala Spree も New York City に来た。主催は Tapad社と Scala Center で、Lightbend社は朝食とランチを提供した。Scala Spree は OSS な Scala プロジェクトの代表者 (通常はメンテナ) と一緒に作業して pull request を送って、Scala コントリビュータになろうというハッカソンの一種だ。
Lightbend Tooling Team は sbt を代表して参加した。前準備として、Dale と僕は GitHub issue に “help wanted” や “good first issue” といったラベル付けを行って、コントリビュータ希望者が作業できるものを見つけれるようにした。
Thanks everyone who joined us for Scala Spree NYC today! pic.twitter.com/LPzi1V9Hkf
— sbt (@scala_sbt) June 19, 2018
一日を通してディスカッションやバグ調査が行われ、当日や後日も含め複数の pull request があった:
fgRun
とfgRunMain
タスクを追加して sbt 0.13 のrun
と同様に振る舞うようにした。 #4216 by @agaro1121- scripted のファイル名として
test.script
とpending.script
もサポートするようにした。 #4220 by @regadas inspect
コマンドがエイリアスも処理できるようにした。 #4221 by @gpoirierGlobal / cancelable
がtrue
に設定された場合の fork されたテストにおける Ctrl-C の取り扱いを修正した。 #4226 by @driquelme- “Choosing local” という警告を改善した。 lm#248 by @khvatov
- CI プロセスに
doc
を追加した。 #4218 by @regadas
イベントに皆が参加しやすいようにサポートしていたフレンドリーな Tapad の皆さんにお礼を言いたい。
参加
前回の sbt 1 フィーチャーリリースは 2028年1月の sbt 1.1.0 だった。それ以降バグ修正などのために 6本のパッチリリースをリリースしたが、機能追加などは 1.x ブランチに merge されてきた。
2月の段階で sbt 1.2.0 roadmap を公開して、その中で以下の点に注力することを提案した:
- sbt 1.x へのビルド移行
- sbt をコントリビュートしやすくする
- sbt server (LSP) 関連の機能拡張
2018年を通して Lightbend Tooling team はオープンソースにおけるコントリビューションにフォーカスしてきた。これは、僕たちがコミュニティーにどう貢献できるかということと、sbt や Zinc といったツール群が Scala コミュニティー全般から参加しやすくするにはどうすればいいのかという両方を含んでいる。毎週水曜日にミーティングを行ったり (是非参加したい人は声をかけてほしい)、ロードマップを公開したり、コントリビュータガイドを改善したり、再現性の低い CI テストを直すなどといったことを具体的に行ってきた。さらに、一言でコントリビューションといっても様々な方法があることを強調してきた:
- 採用するのを手伝う
- 職場や Stackoverflow などで他のユーザをアシストする
- ドキュメンテーションにコントリビュートする
- issue トラッカーのガーデニング
- pull request のレビューを手伝う
- issue を報告する
- エコシステムを拡張する
- コアをパッチする
sbt と Zinc 1 の改善に手伝ってくれた皆さんにこの場をお借りして感謝します。
sbt 1.2.0 は 60名のコントリビュータのお陰でできました (敬称略): Dale Wijnand, Eugene Yokota, Kenji Yoshida (xuwei-k), Yasuhiro Tatsuno (exoego), Łukasz Wawrzyk, Jorge Vicente Cantero (jvican), Alistair Johnson, Antonio Cunei, Jason Zaugg, Rikito Taniguchi (tanishiking), Seiya Mizuno, Tim Harper, Aloisia Davì (alodavi), Arnout Engelen, Ethan Atkins, Johannes Rudolph, Krzysztof Romanowski, Allan Renucci, Brian P. Holt, Filipe Regadas, Hiroshi Ito, Martijn Hoekstra, OlegYch, Seth Tisue, natans, Aaron S. Hawley, Alex Khvatov, Alexander Samsig, Andreas Jim-Hartmann, Andrei Pozolotin, Andrey Kaygorodov, Anthony Garo, Christopher Hunt, Colin Dean, Daniel Riquelme, Deokhwan Kim, Gerard Maas, Guillaume Poirier, Heikki Vesalainen, Jason Pickens, Jonas Fonseca, Julien Jerphanion, Justin Pihony, Kazufumi Nishida, Kyle Goodale, Maksym Fedorov, Mark Canlas, Martynas Mickevičius, Michael Pollmeier, Mike Skells, Nafer Sanabria, Naohisa Murakami (tiqwab), PanAeon, Peter Neyens, Rui Gonçalves, Sean Sullivan, Stephen Nancekivell, Veera Venky, blakkan, ortigali. Thank you!