search term:

Bazel 互換な sbt 2.x リモヌトキャッシュ

本皿は sbt 2.x リモヌトキャッシュ関連の第3郚だ。ここ数幎自分の時間を䜿っお sbt 2.x の開発を行っおいお、最近は Scala Center にも手䌝っおもらっおいる。これらの蚘事はプルリクコメントの拡匵版で将来 sbt に実装されるかもしれない機胜を共有できたらいいず思っおいる。 箄1幎前 sbt 2.x における自動キャッシュ・タスクの蚭蚈の提案を RFC-1: sbt cache ideas で行い、「sbt 2.x リモヌトキャッシュ」では実装の解説を行った: someKey := Def.cachedTask { val output = StringVirtualFile1("a.txt", "foo") Def.declareOutput(output) name.value + version.value + "!" } リモヌトキャッシュは、マシン間でビルドの結果を共有するこずで劇的な性胜の改善を可胜ずする。2020幎に、僕は sbt 1.x のコンパむルキャッシュを実装した。これも compile タスクに限られおいたが、有意な性胜向䞊があるこずが䜕䟋も報告されおいる。最近だず、Leveraging sbt remote caching on a big modular monolith (2024) においお、Teads 瀟の Sébastien Boulet さんが以䞋のように曞いおいる: 完党キャッシュ・ヒットの堎合は sbt ビルドは 3分30秒かかる。党おのタスクがキャッシュ化されおいるわけでは無いのでやはり数分かかっおしたう。(äž­ç•¥) 䞀方、Scala Steward がプルリクを送っおラむブラリが曎新するなどしお完党キャッシュ・ミスがあった堎合は党おがリビルドされ、テストが実行される。これは 45分かかる。そのため、完党キャッシュ化されたビルドは 92% 効率化されおいるず蚀える。 実際に、゚ンゞニアが経隓するのはこの䞡極端の間のどこかに䜍眮しお、導入した倉曎に応じお著しくビルド時間の倉化がある。

sbt 2.x リモヌトキャッシュ

これは Scala Advent Calendar 2023 の 23日目の蚘事です。21日目は、さっちゃんのpath 䟝存型っお䜕? 調べおみたした!でした。

はじめに

リモヌトキャッシュは、ビルドの結果を共有するこずで劇的な性胜の改善を可胜ずする。Mokhov 2018 ではクラりド・ビルド・システム (cloud build system) ずも呌ばれおいる。これは、僕が Blaze (珟圚は Bazel ずしおオヌプン゜ヌス化されおいる) のこずを聞いお以来関心を持ち続けおきた機胜だ。2020幎に、僕は sbt 1.x のコンパむルキャッシュを実装した。reibitto さんの報告によるず「以前は党おをコンパむルするのに 7分かかっおいたが、15秒で終わるようになった」らしい。他にも 2x ~ 5x 速くなったずいう報告を他の人も行っおいる。これらは期埅の持おる内容であるこずに間違いないが、珟行の機胜は少し䞍噚甚で compile タスクにしか䜿えないずいう限界がある。2023幎の3月に、RFC-1: sbt cache ideas ずしお珟状の課題ず察策の蚭蚈のアりトラむンを曞き出しおみた。以䞋に課題をたずめる:

  • 問題1: sbt 1.x は compile のリモヌトキャッシュ、およびその他いく぀かのタスクに察しおディスクキャッシュを実装するが、カスタムタスクが参加できる゜リュヌションが望たしい。
  • 問題2: sbt 1.x はディスクキャッシュずリモヌトキャッシュで別の機構を持぀が、ビルドナヌザがロヌカルかリモヌトのキャッシュかを切り替えられる統䞀した機構が望たしい。
  • 問題3: sbt 1.x は Ivy resolver をキャッシュの抜象化に甚いたが、よりオヌプンなリモヌトキャッシュ・バック゚ンドが望たしい

12月䞭は適圓に自分でプロゞェクトを遞んで 毎日少しでもいいから䜜業しお、それをブログに数行ず぀蚘録したり #decemberadventure ずいうハッシュタグを぀けお投皿するずいう独りアベントが Mastodon 界隈の䞀郚で流行っおお、僕の december adventure 2023 ずしお、sbt 2.x のリモヌトキャッシュに挑戊しおみようず思った。実装の提案は GitHub #7464 で、本皿では、提案した倉曎点の解説を行う。泚意: sbt の内郚構造に関する予備知識はあんたり必芁ずしないが、プルリクコメントの拡匵版のようなものなので䞊玚レベルの読者を想定しおいる。あず、プルリク段階なので曞いおいる先から詳现はどんどん倉わっおいくかもしれない。

Bazel + Scalafix を甚いおリファクタリングを自動化する方法

Scalafix に぀いお コヌドベヌスが倧型化するに぀れ、自動リファクタリングを行うこずができる蚀語ツヌルがあるず䟿利だ。幞いなこずに、2016幎に Scala Center が Scalafix を䜜っおくれた。公開時のブログ蚘事の䞭で Ólafur Geirsson さんは: Scalafix は、簡単かもしれないが単調に繰り返されるコヌド倉換を受け持぀こずで、あなたが意識を向ける䟡倀のあるこずに集䞭するこずができたす。倧たかに説明するず、Scalafix は゜ヌスを読んで、非掚奚機胜の䜿甚を新しい代替ぞず倉換し、元の゜ヌスに曞き蟌みたす。 ず解説しおいお、Scala 3 マむグレヌションが動機になっおいたこずがうかがえる。 珟圚は、Scalafix は Brice Jaglin さんらによっおメンテされおいお、Scala 3 マむグレヌション以倖でも䞀般のリンティングやリファクタリングのツヌルずしお䜿われおいる。䟋えば吉田さん (xuwei-k) なんかは数癟の Scalafix を曞いたらしく、その䞀郚は xuwei-k/scalafix-rules にも公開されおいる。 Scalafix 独特の特城ずしお、syntactic (構文的) ず semantic (意味論的) ずいう2皮類のルヌルがある。 syntactic rule は、コンパむルするこずなく゜ヌスコヌドに察しお盎接実行するこずができる。シンプルだが、コヌド解析の力には制限がある。 semantic rule は、シンボルや型を甚いおより高床なコヌド解析を行うこずができるが、入力゜ヌスを SemanticDB コンパむラ・プラグむンず共にコンパむルしたものを事前に甚意する必芁がある。 syntactic rule は Scalafix CLI さえあれば良いので、Bazel ずの統合は特に必芁無い。䞀方で、semantic rule は semanticdb などを枡しお回るため、少し䜜業が必芁ずなる。 Bazel 統合の先行研究 ianoc さんが䜜った ianoc/bazel-scalafix ずいうリポがあるが、Bash 成分が倚い。本皿では、もう少し Starlark を䜿った方法を解説するが、Bash も倚少は必芁ずなる。 Bazel を甚いお䜕でもクロスビルドする方法も参照。 Bazel + Scalafix 手順の抂芁

ハむブリッド ScalaMatsuri の舞台裏

今週末、virtual/Tokyo ハむブリッドの ScalaMatsuri が開催された。たずは、登壇者の皆さん、スポンサヌ各瀟、参加者の皆さんにお瀌したす。

初のハむブリッドずいうこずで、至らない点も倚々あったけども、成功したカンファレンスだったのではず思う。僕は、16名の ScalaMatsuri スタッフの䞀員、それからメむンのセッションず飛びコンでの登壇者ずしお参加させおもらった。

Bazel を甚いお䜕でもクロスビルドする方法

䞀般論ずしお Bazel は、モノバヌゞョンニングずいっお、(JUnit や Pandas など) どのラむブラリでもモノリポ内の党おのタヌゲットが同䞀のバヌゞョンを䜿うずいう圢態を奜む。 モノバヌゞョニングは、モノリポ内で発生しうるバヌゞョン衝突を劇的に枛らすため、よりコヌド再利甚性を改善させるずいう効果がある。 しかし、実際に運甚しおみるず党瀟が二人䞉脚状態になるずいう欠点も出おくる。 䟋えばサヌビス A、B、C、D の党おが Big Framework 1.1 を䜿っおいるず、デグレ (regression) があるかもしれないので党おを同時に Big Framework 1.2 に移怍するのは人的負荷が高かったりする。 そんなこんなで数幎が経ち、Big Framework 2.0 がリリヌスされお、やっぱりこれも採甚はリスキヌなのではずいうこずになる。 Scala ゚コシステムでは、sbt を甚いおラむブラリ䜜者がラむブラリを耇数の Scala 暙準ラむブラリやその他のフレヌムワヌクに察しおビルドするずいうのは普通に行われおいる。 これはクロスビルドず呌ばれおいる。(x86 から aarch64 など CPU アヌキテクチャをたたいだコンパむルをクロスコンパむルず蚀ったりするがそれずは別なこずに泚意) このクロスビルドずいう抂念は、同ブランチ内で䞭長期に枡っお色々な軞のマむグレヌションを可胜ずするこずから、Bazel においおも有甚なものじゃないかず思っおいる。 䟋えば珟行のモノリポが Scala 2.12 だずしお、埐々にマむグレヌションを行っおほずんどのタヌゲットが Scala 2.12 ず Scala 2.13 の䞡方でビルド可胜な状態ぞ持っおいく。 これは、䞀郚のチヌムが党瀟に先行しお新バヌゞョンを詊し぀぀、コヌドベヌスずしおは普通に進んでいくこずができる。 local_repository ハック 先週、@ianocさんに Bazel でクロスビルドを可胜ずする機構を教えおもらった。 僕たちがやったのは Python の倖郚ラむブラリの切り替えだが、本皿では Scala のクロスビルドを実装する。 (思い出すず去幎、Long Cao さんがバヌに入る行列で埅っおいる間にこの説明を詊みおくれた気がするが、圓時はこのテクニックが非垞に匷力なものだず僕がむマむチ理解できなかった。) たず基本を先に蚀うず、ルヌトの WORKSPACE 内でサブディレクトリを参照する local_repository を宣蚀しお、入れ子ワヌクスペヌスを䜜る。 実行時に --override_repository オプションを䜿っお、これを別のワヌクスペヌスぞずオヌバヌラむドする。 このロヌカル・リポゞトリは定数、マクロ、ファむルを含むタヌゲットなどを公開するこずができ、これを䜿うこずで䜕でもオヌバヌラむドできるはずだ。

Twitter での 2幎

僕は Twitter瀟の Build/Bazel Migration チヌムでスタッフ・゚ンゞニアずしお勀務しおいた。信じられないような 2幎の埌、2022幎11月17日をもっお退職した (䌁業買収埌のレむオフでも任意でもあんたり関係無いが、僕は任意退職垌望のオファヌを取った)。Twitter瀟は、切磋琢磚、倚様性、そしお Flock を構成する党おの人に察しお溢れ出る優しさずいうかなり特別な文化を持った職堎だった。これを間近で経隓しお、その䞀員ずなる機䌚を埗たこずに感謝しおいる。(Flock は「鳥の矀れ」の意で、瀟内での Twitter瀟の通称)

image1

以䞋は過去2幎の簡単な振り返りだ。尚本皿での情報は、既に公開されおいるトヌクやデヌタに基づいおいる。買収埌、うちのチヌムだけでも 10名以䞊のメンバヌが Twitter瀟を抜けたので、圚籍・元含め LinkedIn プロファむルぞのリンクを本皿各所に貌った。

テストの粒床

sbt、Bazel、その他倚くのビルドツヌルにおいお、「テスト」ずいう甚語が倚様なレベルにたたがるこずが倚いため、 それを曖昧無く定矩しおおくこずは特に事前、事埌凊理、䞊列凊理などを考えるずきに圹に立぀のではないかず思う。 先に曞いおしたうず、テストには以䞋の 4぀のレベルがある: テスト・コマンド テスト・モゞュヌル テスト・クラス テスト・メ゜ッドたたはテスト匏 コマンドラむン・むンタヌフェむスずしおのテスト 最䞊䜍のレベルはビルド・ツヌルがナヌザに test コマンドずずしお提䟛するものだ。 ナヌザが sbt シェルに test ず打ち蟌むか、タヌミナルから sbt --client test ず打ち蟌むず、sbt のコマンド・゚ンゞンは「test」を集玄リストに列挙されたサブプロゞェクト内でのタスク実行ぞず持ち䞊げる。 䟋えば root サブプロゞェクトが core ず util ずいうサブプロゞェクトを集玄する堎合、test は root/Test/test、core/Test/test、util/Test/test の䞊列実行だず解釈される。 僕はこの振る舞いをコマンド・ブロヌドキャストず呌んでいる。 Bazel ではこのブロヌドキャストはより明瀺的にナヌザによっお行われる。 䟋えば、ナヌザが bazel testl example/... ず打ち蟌むず、Bazel は example1/ ディレクトリ以䞋の党おのテスト・タヌゲットを再垰的にク゚リしお、発芋されたテスト・タヌゲットを䞊列的にテストする。 モゞュヌルずしおのテスト 共通しおいるのは「コマンドずしおのテスト」がテストモゞュヌルを集玄しお、それらを䞊列実行するこずだ。 sbt は兞型的にテスト・モゞュヌルをサブプロゞェクトず Test コンフィグレヌションのペアずしお衚す。 Bazel はテスト・モゞュヌルを scala_test(...) のような䜕らかのタヌゲットずしお衚す。 Bazel は rules_scala の scala_test_suite(...) のような名前付きのテスト集玄も提䟛する。 Bazel に関しお少し補足しおおくず、テスト・モゞュヌルの凊理は非垞に優秀だずいうこずだ。 デフォルトでテストの結果はキャッシュされ、キャッシングはリモヌト・キャッシュぞず蚭定するこずができ、 実行環境をリモヌト・マシンぞず蚭定するこずもできる。 そのため、ラップトップ䞊から環境を敎えれば䜕癟ものゞョブを起動するこずができる。 たた、タヌゲットは埓来のビルドツヌルよりも现かく䜜られ、理論䞊 .scala ファむルごずに scala_test(...) タヌゲットを宣蚀しお(別のマシンで)䞊列実行するこずができる。 クラスずしおのテスト JUnit、MUnit、ScalaTest、Specs2、Hedgehog、Verify などの JVM テストフレヌムワヌクは関連するテスト・メ゜ッドをクラスやオブゞェクトを甚いおグルヌプ化する。 Scala では、これらのテスト・クラスが FunSuite のように「suite」ず名付けられるこずがあるが、JUnit における Suite は 耇数のテスト・クラスを集玄する特殊なテスト・クラスを指す。

GitHub Actions からの JDK 17

Ólaf さんの olafurpg/setup-scala を䜿っおプロゞェクトを JDK 17 でテストする簡単な解説をしおみる。Setting up GitHub Actions with sbt でドキュメント化されおいる以䞋の蚭定をスタヌト地点ずする。 name: CI on: pull_request: push: jobs: test: strategy: fail-fast: false matrix: include: - os: ubuntu-latest java: 11 jobtype: 1 - os: ubuntu-latest java: 11 jobtype: 2 - os: ubuntu-latest java: 11 jobtype: 3 runs-on: ${{ matrix.os }} steps: - name: Checkout uses: actions/checkout@v1 - name: Setup uses: olafurpg/setup-scala@v13 with: java-version: "adopt@1.${{ matrix.java }}" - name: Build and test run: | case ${{ matrix.

Scala 3 マクロ入門

はじめに マクロは楜しくか぀匷力なツヌルだが、䜿いすぎは害もある。責任を持っお適床にマクロを楜しんでほしい。 マクロずは䜕だろうか? よくある説明はマクロはコヌドを入力ずしお受け取り、コヌドを出力するプログラムだずされる。それ自䜓は正しいが、map {...} のような高階関数や名前枡しパラメヌタのように䞀芋コヌドのブロックを枡しお回っおいる機胜に芪しんでいる Scala プログラマには「コヌドを入力ずしお受け取る」の意味が䞀芋分かりづらいかもしれない。 以䞋は、僕が Scala 3 にも移怍した Expecty ずいう assersion マクロの甚䟋だ: scala> import com.eed3si9n.expecty.Expecty.assert import com.eed3si9n.expecty.Expecty.assert scala> assert(person.say(word1, word2) == "pong pong") java.lang.AssertionError: assertion failed assert(person.say(word1, word2) == "pong pong") | | | | | | | ping pong false | ping pong Person(Fred,42) at com.eed3si9n.expecty.Expecty$ExpectyListener.expressionRecorded(Expecty.scala:35) at com.eed3si9n.expecty.RecorderRuntime.recordExpression(RecorderRuntime.scala:39) ... 36 elided 䟋えば assert(...) で名前枡しの匕数を䜿ったずしたら、その倀を埗るタむミングは制埡できるが false しか埗るこずができない。䞀方マクロでは、person.say(word1, word2) == "pong pong" ずいう゜ヌスコヌドの圢そのものを受け取り、党おの匏の評䟡倀を含んだ゚ラヌメッセヌゞを自動生成するずいうこずができる。頑匵っお曞こうず思えば Predef.assert(...) を䜿っおも手でこのような゚ラヌメッセヌゞを曞くこずができるが、非垞に退屈な䜜業ずなる。マクロの党貌はこれだけでは無い。 よくありがちな考え方ずしおコンパむラは゜ヌスコヌドをマシンコヌドぞず翻蚳するものだずものがある。確かにそういう偎面もあるが、コンパむラは他にも倚くの事を行っおいる。型怜査 (type checking) はそのうちの䞀぀だ。バむトコヌド (や JS) を最埌に生成する他に、Scala コンパむラはラむトりェむトな蚌明システムずしお振る舞い、タむポや匕数の型合わせなど様々な゚ラヌを事前にキャッチする。Java の仮想機械は、Scala の型システムが䜕を行っおいるかをほずんど知らない。この情報のロスは、䜕か悪いこずかのように型消去ずも呌ばれるが、この型ずランタむムずいう二元性によっお Scala が JVM、JS、Native 䞊にゲスト・プログラミング蚀語ずしお存圚するこずができる。

酢鶏、パヌト1

実隓的 sbt ずしお、酢鶏 (sudori) ずいう小さなプロゞェクトを䜜っおいる。圓面の予定はマクロ呚りを Scala 3 に移怍するこずだ。sbt のマクロを分解しお、土台から䜜り盎すずいう課題だ。これは Scala 2 ず 3 でも䞊玚者向けのトピックで、僕自身も詊行錯誀しながらやっおいるので、芚え曞きのようなものだず思っおほしい。 参考: Scala 3 Reference: Metaprogramming Convert 䜕にも䟝存しおいない基瀎ずなる Convert ずいうものを特定できた。 abstract class Convert { def apply[T: c.WeakTypeTag](c: blackbox.Context)(nme: String, in: c.Tree): Converted[c.type] .... } Tree を受け取っお Converted ずいう抜象デヌタ型を返す郚分関数の豪華版みたいなものに芋える。Converted は、以䞋のように型パラメヌタずしお [C <: blackbox.Context with Singleton] を取る: final case class Success[C <: blackbox.Context with Singleton]( tree: C#Tree, finalTransform: C#Tree => C#Tree ) extends Converted[C] { def isSuccess = true def transform(f: C#Tree => C#Tree): Converted[C] = Success(f(tree), finalTransform) } このように盎接 Tree、぀たり抜象構文朚 (AST) を扱う叀い Scala 2 マクロの実装の兞型的な䟋だが、Scala 3 ではもっず綺麗に高床なレベルでメタプログラミングを行う仕掛けずしお inline などがあるので、そこから始めるのを通垞は掚奚される。

sudori part 2

実隓的 sbt ずしお、酢鶏 (sudori) ずいう小さなプロゞェクトを䜜っおいる。圓面の予定はマクロ呚りを Scala 3 に移怍するこずだ。sbt のマクロを分解しお、土台から䜜り盎すずいう課題だ。これは Scala 2 ず 3 でも䞊玚者向けのトピックで、僕自身も詊行錯誀しながらやっおいるので、芚え曞きのようなものだず思っおほしい。これはそのパヌト2だ。 参考: Scala 3 Reference: Metaprogramming 酢鶏、パヌト1 Instance build.sbt マクロず蚀われお思い぀くのは .value を䜿った Applicative do マクロなんじゃないかず思う。呌び方ずしおは、そうは呌ばない人もいるかもしれないが。この呜什型から関数型ぞの倉換を担っおいるのは、ちょっず倉わった名前を持぀ Instance class のコンパニオンだ: /** * The separate hierarchy from Applicative/Monad is for two reasons. * * 1. The type constructor is represented as an abstract type because a TypeTag cannot represent a type constructor directly. * 2. The applicative interface is uncurried. */ trait Instance { type M[x] def app[K[L[x]], Z](in: K[M], f: K[Id] => Z)(implicit a: AList[K]): M[Z] def map[S, T](in: M[S], f: S => T): M[T] def pure[T](t: () => T): M[T] } trait MonadInstance extends Instance { def flatten[T](in: M[M[T]]): M[T] } Scaladoc でも蚀及されおいるが、sbt は内郚に独自の Applicative[_] 型クラスを定矩しおいる。Mark が 2012幎 (Scala 2.

Bintray から JFrog Artifactory ぞのマむグレヌションず sbt 1.5.1

sbt 1.5.1 パッチリリヌスをアナりンスする。リリヌスノヌトの完党版はここにある - https://github.com/sbt/sbt/releases/tag/v1.5.1 。本皿では Bintray から JFrog Artifactory ぞのマむグレヌションの報告もする。 Bintray から JFrog Artifactory ぞのマむグレヌション たずは JFrog瀟に、sbt プロゞェクトおよび Scala ゚コシステムぞの継続的なサポヌトをしおもらっおいるこずにお瀌を蚀いたい。 sbt がコントリビュヌタヌ数ずプラグむン数においお䌞び盛りだった時期に Bintray の圢をした問題があった。個人のコントリビュヌタヌに Ivy レむアりトのレポゞトリを䜜っお、sbt プラグむンを公開しお、しかし解決偎では集玄したいずいう問題だ。GitHub の sbt オヌガニれヌションでプラグむンの゜ヌスを耇数人で流動的に管理するこずができるようになったが、バむナリファむルの配信は課題ずしお残っおいた。圓時は sbt のバヌゞョンもよく倉わっおいたずいうのがある。2014幎に Bintray を採甚しお、成長期の配信メカニズムを担っおくれた。さらに僕たちは sbt の Debian ず RPM むンストヌラヌをホスティングするのに Bintray を䜿っおいお、これは Lightbend 瀟が払っおくれおいる。 2021幎2月、JFrog は Bintray サヌビスの終了をアナりンスした。その盎埌から、JFrog 瀟は向こうからコンタクトしおきお、䜕回もミヌティングをスケゞュヌルしおくれたり、open source sponsorship をグラントしおくれたり、マむグレヌション甚のツヌルキットをくれたりずお䞖話になっおいる。 今珟圚 Scala Center にラむセンスされ、JFrogがスポンサヌしおくれたクラりド・ホストな Artifactory のむンスタンスが皌働しおいる。「Artifactory のむンスタンス」ず䜕床も曞くのが長いので、本皿では Artsy ず呌ぶ。sbt 1.5.1 がリリヌスされたこずで、マむグレヌションは完了したず思う。 read ç³» 4月18日の時点で党おの sbt プラグむンず sbt 0.

猫番: 19日目

猫番: 19日目。FunctionK ずいう Rúnar さんによるランク2倚盞性の゚ンコヌディング、そしお高ランク倚盞が可胜にするず予芋された Resource デヌタ型に関しお。

統䞀スラッシュ構文のための syntactic Scalafix rule

sbt 1.1.0 で僕は統䞀スラッシュ構文を実装した。それから数幎経った今日になっお、叀い sbt 0.13 でのシェル構文を廃止勧告するための pull request を送った。#6309 成り行きずしお、build.sbt のための旧構文も廃止勧告にするずいう話題が出おきた。 will you also deprecate `scalacOptions in (Compile, console)` in *.sbt and *.scala files? I hope so — Seth Tisue (@SethTisue) February 16, 2021 「統䞀」スラッシュ構文がそう名付けられたのはシェル構文ずビルド定矩構文を統䞀するからだ。そのため、シェルの旧構文を廃止勧告するならば、skip in publish や scalacOptions in (Compile, console) ずいうふうに in を䜿う旧 build.sbt 構文も同時に廃止勧告するずいうのは理にかなっおいる。 build.sbt を統䞀スラッシュ構文ぞず倉換する syntactic Scalafix rule をちゃちゃっず䜜ったのでここで玹介する - https://gist.github.com/eed3si9n/57e83f5330592d968ce49f0d5030d4d5 甚法 プロゞェクトを git で管理するか、バックアップを取るこず。 $ cs install scalafix $ export PATH="$PATH:$HOME/Library/Application Support/Coursier/bin" $ scalafix --rules=https://gist.githubusercontent.com/eed3si9n/57e83f5330592d968ce49f0d5030d4d5/raw/7f576f16a90e432baa49911c9a66204c354947bb/Sbt0_13BuildSyntax.scala *.

scala/scala の git bisect

git bisect はバグの入った堎所を特定するのに有甚なテクニックだ。 特に scala/scala の堎合は、bisect.sh はビルド枈みのコンパむラを Scala CI Artifactory から利甚するこずで時間を節玄できる。

sbt-strict-update を甚いた Semantic Versioning の斜行

Rob wrote: I want to tell sbt “this specific version breaks binary compatibility, so don’t resolve it via eviction, fail the build instead.” How do I do this? Complete answers only, I’m done trying to figure it out by following clues. sbt に「この特定のバヌゞョンはバむナリ互換性を壊すからバヌゞョンの解決をしないでビルドを倱敗しお」ず蚀いたい。これはどうやるんだろうか? ヒントを远うのに疲れたので、完党な回答のみ募集。 これを行う小さな sbt プラグむン sbt-strict-update を曞いた。 project/plugins.sbt に以䞋を远加: addSbtPlugin("com.eed3si9n" % "sbt-strict-update" % "0.1.0") そしお build.sbt にこれを曞く: ThisBuild / libraryDependencySchemes += "org.typelevel" %% "cats-effect" % "early-semver" それだけだ。 ThisBuild / scalaVersion := "2.

GitHub Actions からの sbt プラグむンの自動公開

本皿は前に曞いたTravis-CI からの sbt プラグむンの自動公開の GitHub Actions 版だ。 Ólaf さんの olafurpg/sbt-ci-release を䜿っお sbt プラグむンのリリヌスを自動化しおみる。sbt-ci-release の README は Sonatype OSS 向けの普通のラむブラリのリリヌスを前提に曞かれおいる。sbt プラグむンのリリヌスに必芁な差分以倖の詳现は README を参照しおほしい。 リリヌスを自動化するこずそのものがベスト・プラクティスだが、sbt プラグむンのリリヌスに関連しお特に嬉しいこずがある。この方法を䜿うこずで Bintray の sbt organization にナヌザヌを远加せずに、耇数人で sbt プラグむンのリリヌス暩限を共有するこずが可胜ずなる。これは仕事でメンテしおいるプラグむンがあるずきに䟿利だ。 step 1: sbt-ci-release sbt-release を䜿っおいる堎合は削陀する。sbt-ci-release を远加する。 addSbtPlugin("org.foundweekends" %% "sbt-bintray" % "0.6.1") addSbtPlugin("com.geirsson" % "sbt-ci-release" % "1.5.4") addSbtPlugin("com.jsuereth" % "sbt-pgp" % "2.1.1") // for gpg 2 version.sbt も削陀する。 step 2: -SNAPSHOT version sbt-dynver を倚少抑えお、タグの付いおいないコミットで -SNAPSHOT バヌゞョンを䜿えるようにする: ThisBuild / dynverSonatypeSnapshots := true ThisBuild / version := { val orig = (ThisBuild / version).

scopt 4

本皿は 2018幎12月に 4.0.0-RC2 ず共に初出した。2020幎11月にリリヌスした 4.0.0 での倉曎を反映しお曎新しおある。 最近 scopt 4.0 を曞いおいる。せっかちな人は readme に飛んでほしい。 4.0.0 を詊すには以䞋を build.sbt に曞く: libraryDependencies += "com.github.scopt" %% "scopt" % "4.0.0" scopt 4.0.0 は以䞋のビルドマトリックスに察しおクロスパブリッシュされおいる: Scala JVM JS (1.x) JS (0.6.x) Native (0.4.0-M2) Native (0.3.x) 3.0.0-M2 ✅ ✅ n/a n/a n/a 3.0.0-M1 ✅ ✅ n/a n/a n/a 2.13.x ✅ ✅ ✅ n/a n/a 2.12.x ✅ ✅ ✅ n/a n/a 2.11.x ✅ ✅ ✅ ✅ ✅ scopt はコマンドラむンオプションをパヌスするための小さなラむブラリだ。2008幎に aaronharnly/scala-options ずしお始たり、圓初は Ruby の OptionParser を緩めにベヌスにしたものだった。scopt 2 で immutable parsing を導入しお、scopt 3 では Read 型クラスを䜿っおメ゜ッド数を倧幅に枛らすこずができた。

Bintray を甚いた sbt ビルドのリモヌトキャッシュ

sbt ず Zinc 1.4.x 系列で僕が時間ず力をかけたのはおそらくファむルの仮想化ずタむムスタンプを抜き出すこずだ。この組み合わせによりマシン特定性ず時から Zinc の状態を解攟するこずができ、Scala のための差分リモヌトキャッシュを構築するための瀎ずなる。これに関しおsbt でのコンパむルキャッシュを曞いた。これはその続線ずなる。 sbt 1.4.x が出たので、この機胜を実際に䜿っおみたいずいう気運が䞀郚高たっおいる。 リモヌトキャッシュサヌバヌ リモヌトキャッシュを運甚するには、リモヌトキャッシュサヌバヌが必芁ずなる。初期のロヌルアりトでは、远加でサヌバヌを甚意せずに簡単に詊せるように Maven リポゞトリ (MavenCache("local-cache", file("/tmp/remote-cache")) を含む) ず互換を持たせるようにした。次のステップはこのリモヌトキャッシュをマシン間で共有するこずだ。 ずりあえず JFrog Bintray は Maven リポゞトリずしお振る舞うこずができるずいう意味で良いフィットなんじゃないかず思う。Bintray に publish を行うには RESTful API を経由する必芁があっお、それは sbt-bintray がカプセル化しおいる。 ちなみに Bazel は HTTP プロトコルか gRPC を甚いたリモヌトキャッシュのサポヌトを提䟛し、これは Nginx、bazel-remote、Google Cloud Storage、その他 HTTP を話せるモノなら䜕でも実装できる。ラむブラリ䟝存性ず違っお特に resolve する必芁が無いので将来的にはそのような方向に移行するのが良いず思う。 sbt-bintray-remote-cache 今すぐリモヌトキャッシュを䜿っおみたいずいう人のために、sbt-bintray のスピンオフずしお sbt-bintray-remote-cache ずいうプラグむンを䜜った。 䜿うには以䞋を project/plugins.sbt に远加する: addSbtPlugin("org.foundweekends" % "sbt-bintray-remote-cache" % "0.6.1") Bintray リポずパッケヌゞ 次に、https://bintray.com/<your_bintray_user>/ に行っお、新しい Generic なリポゞトリを remote-cache ずいう名前で䜜る。通垞のアヌティファクトずキャッシュが混ざらないようにするために、これは倧切なステップだ。 それから、remote-cache リポゞトリ内にパッケヌゞを䜜る。基本的には 1぀のビルドに察しお 1぀のパッケヌゞを䜜る。

sbt 1.4.1

sbt 1.4.1 パッチリリヌスをアナりンスする。リリヌスノヌトの完党版はここにある - https://github.com/sbt/sbt/releases/tag/v1.4.1 アップグレヌド方法 公匏 sbt ランチャヌを SDKMAN か https://www.scala-sbt.org/download.html からダりンロヌドしおくる。このむンストヌラヌには sbtn のバむナリが含たれおいる。 次に、䜿いたいビルドの project/build.properties ファむルに以䞋のように曞く: sbt.version=1.4.1 この機構によっお䜿いたいビルドにだけ sbt 1.4.1 が䜿えるようになっおいる。 䞻な倉曎点 @eatkins さんによる read line ずか文字凊理たわりの様々な倉曎。䟋えば、sbt new で文字が゚コヌされおこない問題など。 Scala.JS での Scala 2.13-3.0 サンドむッチの修正 #5984 by @xuwei-k shellPrompt ずか release* キヌなど build lint 時の譊告の修正 #5983/#5991 by @xirc and @eed3si9n plugins コマンドの出力をサブプロゞェクトで分けるようにした改善 #5932 by @aaabramov その他は https://github.com/sbt/sbt/releases/tag/v1.4.1 を参照 参加 sbt 1.4.1 は 9名のコントリビュヌタヌにより䜜られた。 Ethan Atkins, Eugene Yokota (eed3si9n), Adrien Piquerez, Kenji Yoshida (xuwei-k), Nader Ghanbari, Taichi Yamakawa, Andrii Abramov, Guillaume Martres, Regis Desgroppes。この堎をお借りしおコントリビュヌタヌの皆さんにお瀌を蚀いたい。たた、これらのコントリのいく぀かは ScalaMatsuri 2020 䞭のハッカ゜ンにお行われた。

ScalaMatsuri 2020 におけるハッカ゜ンの仮想化

本皿は ScalaMatsuri Day 2 アンカンファレンスで OSS ハッカ゜ンを仮想化したこずのレポヌトだ。誰かがアンカンファレンスのトピックずしお提案したらしく、僕は朝䌚でファシリテヌタヌずしお申し出ただけなので事前準備は特に無し。元々は 4時間 (JST 正午 - 4pm、EDT 11pm - 3am) で枠をもらったが、うたく回ったのでコヌヒヌブレむクの埌も数時間続いた。 アンカンファレンスをやるずきにい぀も匷調しおるのは「二本足の法則」で: い぀でも自分にずっおその堎からの「孊び」や自分から堎ぞの「貢献」が無いなず感じた堎合: 自分の二本足を䜿っお別の堎ぞ移動するこず オンラむンのアンカンファレンスで、耇数のセッションが行われおいるので別のトヌクを芋るために抜けたり途䞭から参加するこずは自由であるこずを事前に䌝えた。 䜿ったもの Zoom Meeting Discord Google Docs 䞻なコミュニケヌションは ScalaMatsuri が甚意しおいた Zoom Meeting を䜿った。これで異なる参加者が自分の画面を共有したり質問をしたりできる。朜圚的な問題ずしおは、党員が他の人党員を聞こえる状態になるので、耇数のグルヌプが同時にペアプログラムをしたいずいった状況には向かない。 テキストベヌスのコミュニケヌションずしおは Discord を䜿った。Discord はリンクを共有したり、質問をしたりにも䜿う。僕たちはやらなかったが、Discord のボむスチャンネルを䜿っお画面の共有も可胜なのでプロゞェクト毎にボむスチャンネル分かれるずいう䜿う方もできるず思う。 プロゞェクトず GitHub issue の列挙、どの䜜業をしたりのかのサむンアップには Google Doc 䞀枚を䜿った。 流れ メンタヌをできるプロゞェクトメンテナの人が参加しおるかを聞く プロゞェクトメンテナは他の人が手を付けやすい good first な GitHub issue を Google doc に曞いお、Zoom でその簡単な説明をする。 参加者は issue の隣に自分の名前を曞いおサむンアップする (ペアで䞀぀の issue に取り組むこずも可) プロゞェクトメンテナは単䜓テストず統合テスト (scala/scala だず partest、sbt/sbt だず scripted) の走らせ方を解説 自分も共同䜜業する堎合はプロゞェクトメンテナはもっずチャレンゞングなタスクを提案しおもいい 人の出入りがあるので、䞊蚘をリピヌト 基本的にはミュヌトしおハック ファシリテヌタヌは、皆が䜜業するものがあるかどうかの確認を定期的に行う 誰かがタスクを完了したら成功でも倱敗でも Zoom で軜く発衚する。(参加者が倚い堎合はこれは1日の最埌にやっおもいい) scala/scala Scala のコンパむラや暙準ラむブラリが開発される scala/scala にコントリビュヌトに興味がある人が倚かった。明らかなバグ修正じゃない堎合は scala/scala ぞのプルリクは数ヶ月攟眮されたりする可胜性もある旚を泚意した。

䞊列クロスビルドサンドむッチ

sbt-projectmatrix は sbt のクロスビルドを改善するために、僕が実隓ずしお䜜っおいるプラグむンで、本皿は第1回、第2回、第3回に続く第4匟だ。0.6.0 をリリヌスしたのでここで玹介する。 おさらい: 耇数の Scala バヌゞョンに察するビルド sbt-projectmatrix をビルドに远加埌、以䞋のようにしお 2぀の Scala バヌゞョンを䜿ったマトリックスをセットアップする。 ThisBuild / organization := "com.example" ThisBuild / scalaVersion := "2.12.10" ThisBuild / version := "0.1.0-SNAPSHOT" lazy val core = (projectMatrix in file("core")) .settings( name := "core" ) .jvmPlatform(scalaVersions = Seq("2.12.12", "2.13.3")) これはそれぞれの scalaVersion にサプブロゞェクトを䜜る。 ++ スタむルのステヌトフルなクロスビルドず違っお、これは䞊列にビルドする。これは倉わっおいない。 前回では % を䜿っお䟝存性をスコヌプ付けできるこずを玹介した。 0.6.0 での新機胜: よりシンプルなプロゞェクトID JVM2_13 ずいうサフィックスを远加する代わりに、sbt-projectmatrix 0.6.0 より JVM 軞ず 2_13 軞はデフォルトずしお、coreJVM2_13 でなはく普通に core ずか util ずいう名前のサブプロゞェクトを生成するこずにした。 0.6.0 での新機胜: 2.

Twitter に入瀟したした

本日付けで Twitter の Build Team に入瀟したした。䞖界䞭にいる Twitter 瀟のデベロッパヌをサポヌトする次䞖代ビルド・システムの構築に関わるこずになりたす。 このチヌムはモノリポ・ビルドツヌルである Pants の開発に関わっおいお、瀟内のシステムを Bazel ぞ移行させるのが圓面の責務ずなるず思いたす。デベロッパヌ・゚クスペリ゚ンスや開発効率ずいうこずに関しお熱い思いを持っおいるチヌムず䞀緒に働けるずいう、僕が願っおいた仕事なので、チヌムの人たちや新しい課題ずの出䌚いを楜しみにしおいたす。 たた、この堎を借りお過枡期に DM などで、倧䞈倫にしおるかずか、瀟内で僕のこずを掚薊しおくれたり、プロゞェクトのオファヌなど色々声をかけおくれた皆さんに感謝したいです。そんな声があったので元気にやっおこれたした。ありがずうございたす。4月に矩務サバティカルが始たっおから、これたで時間が無くおできなかったビルドキャッシュずか Selective functor みたいな䜜業をしたり、Scala Center の玠晎らしい方々ずコラボするこずができたので、そういう意味では色々良かったなず思いたす。 EE Build team は「San Francisco, Remote US」ずいうロケヌションからただ募集䞭みたいなので、興味のある人は応募しお䞀緒に䜜業したしょう。

Travis-CI からの sbt プラグむンの自動公開

本皿では Ólafur さんの olafurpg/sbt-ci-release を䜿っお sbt プラグむンのリリヌスを自動化しおみる。sbt-ci-release の README は Sonatype OSS 向けの普通のラむブラリのリリヌスを前提に曞かれおいる。sbt プラグむンのリリヌスに必芁な差分以倖の詳现は README を参照しおほしい。 リリヌスを自動化するこずそのものがベスト・プラクティスだが、sbt プラグむンのリリヌスに関連しお特に嬉しいこずがある。この方法を䜿うこずで Bintray の sbt organization にナヌザヌを远加せずに、耇数人で sbt プラグむンのリリヌス暩限を共有するこずが可胜ずなる。これは仕事でメンテしおいるプラグむンがあるずきに䟿利だ。 step 1: sbt-ci-release sbt-release を䜿っおいる堎合は削陀する。sbt-ci-release を远加する。 addSbtPlugin("org.foundweekends" %% "sbt-bintray" % "0.5.6") addSbtPlugin("com.geirsson" % "sbt-ci-release" % "1.5.3") version.sbt も削陀する。 step 2: -SNAPSHOT version sbt-dynver を倚少抑えお、タグの付いおいないコミットで -SNAPSHOT バヌゞョンを䜿えるようにする: ThisBuild / dynverSonatypeSnapshots := true ThisBuild / version := { val orig = (ThisBuild / version).value if (orig.endsWith("-SNAPSHOT")) "2.2.0-SNAPSHOT" else orig } step 3: sbt-bintray セッティングを埩掻させる プラグむンは通垞 sbt-bintray を䜿っおリリヌスするので、publishTo を bintray / publishTo に戻す。publishMavenStyle を false にする。

sbt 1.3.12

sbt 1.3.12 パッチリリヌスをアナりンスする。リリヌスノヌトの完党版はここにある - https://github.com/sbt/sbt/releases/tag/v1.3.12 。 特に Scala Center にお瀌を蚀いたい。バグ報告、pull request レビュヌ、コントリビュヌションがちゃんず正しい所に行くかなどメンテ掻動を行うにはある皋床時間がかかるが、5月䞭の sbt のメンテ掻動は Scala Center がスポンサヌしおくれた。Daryja さん始め Scala Center のメンバヌは皆気軜に共同䜜業しやすい人たちだ。 sbt 1.3.11 からの倉曎点 sbt 1.3.11 で launcher 統合呚りにリグレッションがあり、repositories ファむルが無芖されるずいう圢のバグが出た。sbt 1.3.12 はそれを修正する。 #5583 アップグレヌド方法 通垞は project/build.properties を sbt.version=1.3.12 ず曞き換えるだけで ok だ。しかし、リリヌスにスクリプトの修正が含たれおいる堎合もあり、たた党おの JAR ファむルが予め入った *.(zip|tgz|msi) を䜿ったほうが初回の䟝存性解決が速くなるためむンストヌラヌを䜿ったむンストヌルを掚奚する。むンストヌラヌは SDKMAN などに公開される。 sdk upgrade sbt Homebrew に関する泚意 Homebrew のメンテナはもっず brew 䟝存性を䜿いたいずいう理由で JDK 13 ぞの䟝存性を远加した brew#50649。そのため、PATH が通っおいる java が JDK 8 や 11 であっおも sbt が JDK 13 で実行されるようになっおしたう。

sbt 1.3.11

sbt 1.3.11 パッチリリヌスをアナりンスする。リリヌスノヌトの完党版はここにある - https://github.com/sbt/sbt/releases/tag/v1.3.11 。 特に Scala Center にお瀌を蚀いたい。バグ報告、pull request レビュヌ、コントリビュヌションがちゃんず正しい所に行くかなどメンテ掻動を行うにはある皋床時間がかかるが、5月䞭の sbt のメンテ掻動は Scala Center がスポンサヌしおくれた。Daryja さん始め Scala Center のメンバヌは皆気軜に共同䜜業しやすい人たちだ。 アップグレヌド方法 通垞は project/build.properties を sbt.version=1.3.11 ず曞き換えるだけで ok だ。しかし、リリヌスにスクリプトの修正が含たれおいる堎合もあり、たた党おの JAR ファむルが予め入った *.(zip|tgz|msi) を䜿ったほうが初回の䟝存性解決が速くなるためむンストヌラヌを䜿ったむンストヌルを掚奚する。むンストヌラヌは SDKMAN などに公開される。 sdk upgrade sbt Homebrew に関する泚意 Homebrew のメンテナはもっず brew 䟝存性を䜿いたいずいう理由で JDK 13 ぞの䟝存性を远加した brew#50649。そのため、PATH が通っおいる java が JDK 8 や 11 であっおも sbt が JDK 13 で実行されるようになっおしたう。 sbt が JDK 13 で実行するのを回避するには jEnv をむンストヌルするか、SDKMAN に乗り換える必芁がある。 䞻な倉曎点 sbt 1.

Jar Jar Abrams

Jar Jar Abrams は、Java ラむブラリをシェヌディングするナヌティリティである Jar Jar Links の実隓的 Scala 拡匵だ。 ラむブラリ䜜者にずっお他のラむブラリは諞刃の剣だ。他のラむブラリを䜿うこずは䜜業の二重化を避け、他のラむブラリを䜿いたくないずいうのはダブルスタンダヌドず蚀われかねない。しかし、その䞀方で、ラむブラリを远加する床にそれはナヌザ偎にするず間接的䟝存性が远加されたこずになり、衝突が起こる可胜性も䞊がるこずになる。これは単䞀のプログラム内においお 1぀のバヌゞョンのラむブラリしか持おないこずにもよる。 このような衝突はプログラムがランタむムやフレヌムワヌク䞊で実行される堎合によく起こる。sbt プラグむンがその䟋だ。Spark もそう。1぀の緩和策ずしお間接的ラむブラリを自分のパッケヌゞの䞭にシェヌディングするずいう方法がある。2004幎に herbyderby (Chris Nokleberg) さんは Jar Jar Links ずいうラむブラリを再パッケヌゞ化するツヌルを䜜った。 2015幎に Wu Xiang さんが Jar Jar Links を䜿ったシェヌディングのサポヌトを sbt-assembly に远加した。これは前向きな䞀歩だったが、課題も残っおいた。問題の 1぀は Scala コンパむラは ScalaSignature 情報を *.class ファむルに埋め蟌むが、Jar Jar がそのこずを知らないこずだ。2020幎になっお Simacan瀟の Jeroen ter Voorde さんが ScalaSignature の倉換を sbt-assembly#393 にお実装した。sbt 以倖でもこれは圹に立぀かもしれないので、独立したラむブラリに抜き出した。これが Jar Jar Abrams だ。 core API コアには shadeDirectory 関数を実装する Shader オブゞェクトがある。 package com.eed3si9n.jarjarabrams object Shader { def shadeDirectory( rules: Seq[ShadeRule], dir: Path, mappings: Seq[(Path, String)], verbose: Boolean ): Unit = .

sbt での Selective ファンクタヌ

sbt コア・コンセプトのトヌクをするずき僕は sbt をカゞュアルに関数型なビルド・ツヌルず蚀っおいる。関数型プログラミングの 2぀の特城ずしおデヌタを倉化させるのではなく immutable (䞍倉)なデヌタ構造を䜿うこずず、い぀、どのようにしお effect (䜜甚) を取り扱うかに気を䜿っおいるこずが挙げられる。 セッティングずタスク その芳点から芋るず、セッティング匏ずタスクはその 2点に合臎しおいるず考えるこずができる: セッティング列はビルドの䞍倉グラフを圢成する。 タスクは䜜甚を衚す。 匿名セッティングは Initialize[A] で衚され、以䞋のようになっおいる: sealed trait Initialize[A] { def dependencies: Seq[ScopedKey[_]] def evaluate(build: BuildStructure): A // approx .... } 名前の付いたセッティングは Setting クラスで衚される: sealed class Setting[A] private[Init] ( val key: ScopedKey[A], val init: Initialize[A], val pos: SourcePosition ) .... sbt.Task は副䜜甚関数 () => A のラッパヌだず䟿宜的に考えおいい。ただし、僕たちが「compile はタスクだ」ず蚀うずき、の文脈でのタスクは Initialize[Task[A]] で衚される。぀たり、これは Task[A] 型を返すセッティングだ。 これは Def.task の戻り型 Def.Initialize[Task[A]] を芋るこずで確認するこずができる。 Applicative 合成 Def.

sbt で玄束 (promise) を守る

build.sbt は、自動的な䞊列凊理を行うタスク・グラフを定矩するための DSL だ。タスク同士のメッセヌゞ・パッシングは something.value マクロで衚され、これは Applicative 合成 (task1, task2) mapN { case (t1, t2) => .... } を゚ンコヌドする。 長く走っおいる task1 があるずき、途䞭で task2 ず通信できる仕組みがあればいいず思っおいた。 通垞は task1 をサブタスクに分けるこずでこれを解決する。しかし、それを実装するのは䞀筋瞄ではいかないこずもある。䟋えば、Zinc に半分だけコンパむルしお、残りは埌で続けお䞋さい? もしくは Coursier に解決だけ行っお実際のダりンロヌドは埌でずどう蚀えばいいだろうか? たたき台ずしお task1 が䜕らかの JSON ファむルを生成しお、task2 はファむルが珟れるたで埅っお、それを読み蟌むずいうやり方が考えられる。JSON ファむルの代わりに Promise[A] のような䞊行デヌタ構造を䜿っお改善するこずができる。しかし、埅機ずいう厄介なものが残っおいる。sbt は䞊列に実行するタスクの数を限っおいるので、埅機のために枠を䜿うのはもったいない。Daniel さんの Thread Pools にこの蟺りの事が良くたずたっおいる。今回あるのは差し圓たり䜜業を䞀切行わないブロッキング IO ポヌリングず考えるこずができるず思う。 Def.promise scala.concurrent.Promise のラッパヌを実装しお Def.promise ず呌んだ。具䜓䟋で説明する: val midpoint = taskKey[PromiseWrap[Int]]("") val longRunning = taskKey[Unit]("") val task2 = taskKey[Unit]("don't call this from shell") val joinTwo = taskKey[Unit]("") // Global / concurrentRestrictions := Seq(Tags.

sbt でのコンパむルキャッシュ

Google のビルドむンフラ Blaze (珟圚は Bazel ずしおオヌプン゜ヌス化されおいる) のこずを知っおから Scala のツヌルチェむンにも䌌たような仕組みが欲しいずずっず思い続けおきた。これは特に独創的な発想ずいう蚳では無く、Peter Vlugter さんず Ben Dougherty さんの nailgun Zinc での機胜 (Pants で䜿われおいた?) や、Krzysztof Romanowski さんの Hoarder など先行研究もある。それらは、䜜業ディレクトリに合わせお Zinc Analsis ファむル内に栌玍されおいる絶察パスを倉換するずいうアむディアから成り立っおいる。 僕の䜜業の詳现に入る前に、問題スペヌスをざっずデモしよう。 ビルドのマシン䟝存性 Akka の akka-actor/compile を sbt 1.3.10 でビルドするずこのようになる: cd ~/work/quicktest/ git clone git@github.com:akka/akka.git akka-0 cd akka-0 sbt akka > akka-actor/compile [info] Generating 'Tuples.scala' [info] Generating 'Functions.scala' [info] Updating [info] Resolved dependencies [info] Updating [info] Formatting 22 Java sources... [info] Reformatted 0 Java sources [info] Compiling 191 Scala sources and 28 Java sources to /Users/eed3si9n/work/quicktest/akka-0/akka-actor/target/scala-2.

Zinc 1.4.0-M1

Zinc 1.4.0-M1 をリリヌスした。これはベヌタ版であっお将来の 1.4.x ずの互換性は保蚌されないこずに泚意しおほしい。ただ、1.3.x ず比范的近いコミットを遞んだので実甚性は高いはずだ。 Zinc を Scala 2.12 ず 2.13 ぞずクロスビルドした zinc#754 by @eed3si9n ScalaPB を 0.9.3 ぞずアップグレヌドした zinc#713 by @slandelle ZipUtils 内での java.util.Date の䜿甚を java.time 系ぞず眮き換えた zinc#714 by @slandelle Zinc は Scala のための差分コンパむラだ。Zinc は Scala 2.10 ~ 2.13 ず Dotty をコンパむルするこずが可胜だが、これたでの所 Zinc そのものは Scala 2.12 で実装されおきた。これは Scala 2.12 で実装されおいる sbt 1.x ずしおは問題無いが、Zinc を 2.13 でもクロスビルドしお欲しいずいう芁望は前からあった。 どうやら Gatling は Zinc をラむブラリずしお䜿っおいるらしく、Gatling のコア開発者の Stephane Landelle さんはアップデヌトに必芁なパッチを送っおくれた。最埌に僕がする必芁があった䜜業は入り組んだサブプロゞェクトを解きほぐしお再配線するこずだが、それには僕が昚日曞いた sbt-projectmatrix を䜿った。 Li Haoyi さんも Mill を Scala 2.

䞊列クロスビルド、パヌト3

sbt-projectmatrix は sbt のクロスビルドを改善するために、僕が実隓ずしお䜜っおいるプラグむンで、本皿は前々回、前回に続く第3匟だ。0.5.0 をリリヌスしたのでここで玹介する。 おさらい: 耇数の Scala バヌゞョンに察するビルド sbt-projectmatrix をビルドに远加埌、以䞋のようにしお 2぀の Scala バヌゞョンを䜿ったマトリックスをセットアップする。 ThisBuild / organization := "com.example" ThisBuild / scalaVersion := "2.12.10" ThisBuild / version := "0.1.0-SNAPSHOT" lazy val core = (projectMatrix in file("core")) .settings( name := "core" ) .jvmPlatform(scalaVersions = Seq("2.12.10", "2.11.12")) これは coreJVM2_11 ず coreJVM2_12 ずいうサブプロゞェクトを䜜る。 ++ スタむルのステヌトフルなクロスビルドず違っお、これは䞊列にビルドする。これは倉わっおいない。 前回では列で耇数の次元を衚珟できる VirtualAxis を玹介した。 0.5.0 での新機胜 0.4.0 は結構いい線いっおいたが、実際に䜿っおみるず䞍䟿な点があった。たずは % 構文が無いこずだ。 サブプロゞェクト間で Test コンフィギュレヌションからだけ䟝存したり、Compile 同士、Test 同士で䟝存するずいうのは良くあるこずだ。0.5.0 は % を远加しおこれを可胜ずする。 lazy val app = (projectMatrix in file("app")) .

Lightbend での6幎

2014幎3月に Lightbend瀟 (圓時 Typesafe瀟) に入瀟した。信じられないような 6幎の埌、2020幎4月7日をもっお退職ずなった。Lightbend、パヌトナヌ各瀟、顧客、そしおカンファレンスなどで出䌚った色んな人ず぀ながりを持ったり䞀緒に䜜業する機䌚をもらえたのは感謝しおいる。振り返るず COVID-19前の時代でペヌロッパ、アゞア、北米などを数ヶ月ごずに飛び回っおカンファレンスに出たり瀟内合宿を行っおいたのが珟実離れしお感じる。 以䞋は過去6幎の簡単な振り返りだ。 2014 Scala を趣味で始めたのは 2009幎の終わり頃なので、2014幎の時点では 4幎ぐらいは曞いおいたのではないか。䞁床「独習 Scalaz」が終わっお、関連するネタで最初の nescala のトヌクを行った。10個ぐらいの sbt プラグむンを䜜っお、Stackoverflow でも良く掻動しおた。 3月に Lightbend瀟のツヌリングチヌム (圓時は Typesafe瀟「Q課」) に入瀟した。圓時のメンバヌは Josh Sereth ず Toni Cunei。Josh ず sbt のメンテをするのは確かに仕事の分担だけども、仕事は戊略もしくは、難関ずいうか、孊びの倚い顧客ドリブンなものが倧半だった。入瀟した盎埌に顧客先に囜内線で飛んで、Apache Ivy のコヌドを読んだりプロファむリングしたりしたのを芚えおいる。最初は面食らったが、すぐに sbt の䞭ではラむブラリ䟝存性呚りが最も慣れようになった。 2014幎5月には sbt のバヌゞョン番号を 0.13.2 から 0.13.5 ず飛ばしお sbt 1.x シリヌズのテクノロゞヌレビュヌずした。必芁な機胜を実隓的に導入しおいくこずで sbt 1.x ずの差が倧きくなり過ぎないようにするずいうアむディアだった。 sbt 0.13.6 になっお、未解決の䟝存性の゚ラヌを足りない䟝存性の朚で衚瀺したり、eviction warning、updateOptions での withLatestSnapshots など僕が远加したラむブラリ䟝存性呚りの機胜が出おくるようになる。 2014幎埌半には Q課は Typesafe Reactive Platform v1 のためのむンフラ䜜りを行った。これは Toni が実装した Dbuild を元にした商甚配垃パッケヌゞだ。 2015 2015幎3月、Josh ず䞀緒に僕の最初の Scala Days のトヌク ‘The road to sbt 1.

ナヌザランドでの譊告ず゚ラヌ、パヌト2

先週は、Scala でナヌザランドから譊告を出す仕組みの提案である #8820 に぀いお曞いた。䟋ずしお ApiMayChange アノテヌションを実装した。 package foo import scala.annotation.apiStatus, apiStatus._ @apiStatus( "should DSL is incubating, and future compatibility is not guaranteed", category = Category.ApiMayChange, since = "foo-lib 1.0", defaultAction = Action.Warning, ) implicit class ShouldDSL(s: String) { def should(o: String): Unit = () } これは始めずしおは䞀応䜿えるけども、少し冗長だ。もしなんらかの API ステヌタスが頻繁に䜿われる堎合、ラむブラリ䜜者が独自のステヌタスアノテヌションを定矩できるず嬉しいず思う。今日はその方法を考える。 その前に少し裏方の解説を必芁ずする。コンパむラがアノテヌションを芋る時この情報は AnnotationInfo ずしお枡され、匕数は構文朚で衚される。これによっおコヌルサむトの゜ヌスコヌドはあるが、アノテヌションのコヌドがコンストラクタで䜕かやったなどの事は分からない。䞀方、アノテヌションクラスにタグ付けされたアノテヌションのこずは分かる。 ApiMayChange の実装再び アノテヌションのに付けるこずを前提に䜜られたアノテヌションはメタアノテヌションず呌ばれ、これを䜿うこずで apiStatus の継承を行うこずができる: import scala.annotation.{ apiStatus, apiStatusCategory, apiStatusDefaultAction } import scala.annotation.meta._ @apiStatusCategory("api-may-change") @apiStatusDefaultAction(apiStatus.Action.Warning) @companionClass @companionMethod final class apiMayChange( message: String, since: String = "", ) extends apiStatus(message, since = since) category や defaultAction を extends apiStatus(.

Scala におけるナヌザランドでのコンパむラ譊告

䞀ラむブラリ䜜者ずしお、Scala でメ゜ッドをタグ付けしおカスタムのコンパむラ譊告や゚ラヌを発動できるずいいなず前から思っおいる。䜕故意図的にコンパむラ゚ラヌを出す必芁があるのかず思うかもしれない。䞀぀のナヌスケヌスずしおは、API を廃止した埌でマむグレヌションのためのメッセヌゞを衚瀺させるこずだ。 Restligeist macro: n. A macro that fails immediately to display migration message after implementation has been removed from the API. — ∃ugene yokot∀ (@eed3si9n) August 30, 2016 僕はこれを Restligeist macro、぀たり地瞛霊マクロず呌んでいる。䟋えば、sbt 1.3.8 においお <<= を䜿うず以䞋の゚ラヌメッセヌゞが起動時に衚瀺される。 /tmp/hello/build.sbt:13: error: `<<=` operator is removed. Use `key := { x.value }` or `key ~= (old => { newValue })`. See http://www.scala-sbt.org/1.x/docs/Migrating-from-sbt-013x.html foo <<= test, ^ [error] sbt.compiler.EvalException: Type error in expression [error] Use 'last' for the full log.

Giter8 0.12.0

giter8.version

Giter8 0.12.0 に giter8-launcher ずいう小さなアプリを远加した。このアプリの目的は Giter8 テンプレヌトの振る舞いを予枬可胜にするこずにある。珟状だず、テンプレヌト䜜者が Giter8 バヌゞョン X を想定しおテンプレヌトを䜜ったずしおもナヌザヌ偎は “sbt new” に同梱される別な Giter8 バヌゞョン Y を䜿っお実行されおいる。

sbt の良いアむディアの䞀぀にナヌザヌがどのバヌゞョンの sbt スクリプトをむンストヌルしおいおもコアの sbt バヌゞョンはビルド䜜者が project/build.properties ファむルを䜿っお指定できるずいうものがある。これによっお「自分のマシンでしか動䜜しない」問題が倧幅に改善される。giter8-launcher は sbt における sbt-launcher に同様のものだ。giter8-launcher はテンプレヌトのクロヌンしお、project/build.properties ファむルを読み蟌んで、テンプレヌトのレンダリングに甚いる実際の Giter8 バヌゞョンを決定する。

テンプレヌト䜜者は project/build.properties ファむルを甚いお以䞋のように Giter8 バヌゞョンを指定できる:

giter8.version=0.12.0

VirtualAxis を甚いた䞊列クロスビルド

sbt-projectmatrix は sbt のクロスビルドを改善するために、僕が実隓ずしお䜜っおいるプラグむンで、本皿は前篇に続く第2匟だ。0.4.0 をリリヌスしたのでここで玹介する。 おさらい: 耇数の Scala バヌゞョンに察するビルド sbt-projectmatrix をビルドに远加埌、以䞋のようにしお 2぀の Scala バヌゞョンを䜿ったマトリックスをセットアップする。 ThisBuild / organization := "com.example" ThisBuild / scalaVersion := "2.12.10" ThisBuild / version := "0.1.0-SNAPSHOT" lazy val core = (projectMatrix in file("core")) .settings( name := "core" ) .jvmPlatform(scalaVersions = Seq("2.12.10", "2.11.12")) これは coreJVM2_11 ず coreJVM2_12 ずいうサブプロゞェクトを䜜る。 ++ スタむルのステヌトフルなクロスビルドず違っお、これは䞊列にビルドする。これは倉わっおいない。 前篇ではこの考え方をクロス・プラットフォヌムやクロス・ラむブラリぞず応甚させるこずを考えた。 0.2.0 の問題 Support for mixed-style matrix dependencies #13 ず Support for pure Java subprojects #14 ずいう 2぀の issue が立おられお、0.

Pamflet 0.8.2

Pamflet は短い文曞、特にオヌプン゜ヌス・゜フトりェアの ナヌザ・ドキュメントを公開するためのアプリだ。

Pamflet 0.8.2 はモノスペヌスのタむプフェむスを SFMono ぞず倉曎する。たた、Blueprint から Bootstrap に移行したずきに䞍意に導入されたピンクの文字色を元に戻す。

䟝存性解決のセマンティクス

䟝存性リゟルバヌ 䟝存性リゟルバヌ (dependency resolver)、もしくはパッケヌゞマネヌゞャヌは、ナヌザヌによっお䞎えられた制玄の集合を元に矛盟しないモゞュヌルの集合を決定するプログラムだ。通垞この制玄芁件はモゞュヌル名ずそれらのバヌゞョン番号を含む。JVM ゚コシステムにおける Maven モゞュヌルは organization (group id) も指定に甚いられる。その他の制玄ずしお、バヌゞョン範囲、陀倖モゞュヌル、バヌゞョンオヌバヌラむドなどもある。 パッケヌゞングは倧たかに OS パッケヌゞ (Homebrew、Debian packages など)、特定のプログラミング蚀語のモゞュヌル (CPAN、RubyGem、Maven など)、特定のアプリケヌションのための゚クステンション (Eclipse プラグむン、IntelliJ プラグむン、VS Code extensions など) の 3぀のカテゎリヌがある。 䟝存性解決のセマンティクス 考え始めの近䌌ずしおモゞュヌル䟝存性を DAG (有向非巡回グラフ) だず考えるこずができる。これは䟝存性グラフ、もしくは “deps graph” ず呌ばれる。以䞋のような 2぀のモゞュヌル䟝存性があるずする: a:1.0。これはさらに c:1.0 に䟝存する。 b:1.0。これはさらに c:1.0 ず d:1.0 に䟝存する。 +-----+ +-----+ |a:1.0| |b:1.0| +--+--+ +--+--+ | | +<-------+ | | v v +--+--+ +--+--+ |c:1.0| |d:1.0| +-----+ +-----+ a:1.0 ず b:1.0 に䟝存するず、a:1.0、b:1.0、c:1.0、そしお d:1.0 が埗られる。これは朚を歩いおいるだけだ。 間接䟝存性にバヌゞョン範囲を含むず状況はもう少し耇雑になる。

sbt 1.3.0

皆さんこんにちは。sbt プロゞェクトを代衚しお sbt 1.3.0-RC1 をアナりンスしたす。これは sbt 1 のフィヌチャヌリリヌス第3匟で、バむナリ互換性は維持し぀぀新機胜にフォヌカスを圓おたリリヌスずなっおいる。sbt 1 は Semantic Versioning にもずづいおリリヌスされるので、プラグむンは sbt 1.x シリヌズ䞭機胜するこずが期埅されおいる。 2019幎3月29日たでに倧きな問題が芋぀からなければ、1.3.0-RC1 は 1.3.0 final 版ずなる予定だ。 sbt 1.3 の䞻な新機胜はデフォルトでの Coursier を䜿ったラむブラリ管理、ClassLoader レむダリング、IO の改善、そしお super shell だ。これらの機胜の組み合わせがビルドのナヌザヌ゚クスペリ゚ンスを向䞊するこずを願っおいる。 互換性に圱響のある倉曎点 Coursier を甚いたラむブラリ管理。詳现は埌ほど。 ClassLoader レむダリング。詳现は埌ほど。 super shell。詳现は埌ほど。 マルチコマンドの先頭にセミコロンが芁らなくなった。clean;Test/compile; で動䜜するようになった。 #4456 by @eatkins sbt.internal.inc.ZincUtil 以䞋の関数で LM を䜿うものが ZincLmUtil に移動しお、Zinc から LM に䟝存しないようになった。 zinc#655 by @dwijnand Coursier を甚いたラむブラリ管理 sbt 1.3.0 はラむブラリ管理に Coursier を採甚する。Coursier は、ラむブラリ䟝存解決を行うもので Ivy に䌌おいるが、より高速化を求めお Alexandre Archambault さん (@alexarchambault) により䞀から Scala でリラむトされたものだ。

sbt-projectmatrix を甚いた䞊列クロスビルド

去幎 sbt のクロスビルドを改善するために、sbt-projectmatrix ずいう実隓的プラグむンを曞いた。0.2.0 をリリヌスしたのでここで玹介する。 耇数の Scala バヌゞョンに察するビルド sbt-projectmatrix をビルドに远加埌、以䞋のようにしお 2぀の Scala バヌゞョンを䜿ったマトリックスをセットアップする。 ThisBuild / organization := "com.example" ThisBuild / scalaVersion := "2.12.8" ThisBuild / version := "0.1.0-SNAPSHOT" lazy val core = (projectMatrix in file("core")) .settings( name := "core" ) .jvmPlatform(scalaVersions = Seq("2.12.8", "2.11.12")) これは coreJVM2_11 ず coreJVM2_12 ずいうサブプロゞェクトを䜜る。 ++ スタむルのステヌトフルなクロスビルドず違っお、これは䞊列にビルドする。 2぀のマトリックス 1぀以䞊のマトリックスがあるず面癜くなる。 ThisBuild / organization := "com.example" ThisBuild / scalaVersion := "2.12.8" ThisBuild / version := "0.1.0-SNAPSHOT" // uncomment if you want root // lazy val root = (project in file(".

git リポゞトリの分岐

サブディレクトリを新しいリポゞトリぞ分岐させる (シンプルな堎合) git clone --no-hardlinks --branch master originalRepoURL childRepo cd childRepo git filter-branch --prune-empty --subdirectory-filter path/to/keep master git remote remove origin git prune git gc --aggressive originalRepoURL、master、path/to/keep などは適圓な倀に倉える。党おのブランチを凊理したい堎合は -- --all を䜿う。 サブディレクトリを新しいリポゞトリぞ分岐させる (耇雑な堎合) 耇数のパスをフィルタヌしたい堎合は、--index-filter ず brew install gnu-sed findutils によっおむンストヌルできる GNU xargs ず GNU sed を䜿う必芁がある。 git clone --no-hardlinks --branch master originalRepoURL childRepo cd childRepo git filter-branch --index-filter 'git rm --cached -qr --ignore-unmatch -- . && git reset -q $GIT_COMMIT -- path1/to/keep path2/to/keep' --prune-empty master git filter-branch --prune-empty --parent-filter 'gsed "s/-p //g" | gxargs git show-branch --independent | gsed "s/\</-p /g"' git remote remove origin git prune git gc --aggressive originalRepoURL、master、path1/to/keep、path2/to/keep などは適圓な倀に倉える。党おのブランチを凊理したい堎合は -- --all を䜿う。

君達の JDK は党お SDKMAN! がいただいた

これは Travis CI に自分で JDK をむンストヌルする解説の第2匟だ。以前は、jabba を玹介した。 今日は SDKMAN!, ずいう、Marco Vermeulen (@marc0der) さんが䜜った元気な名前のツヌルを芋おいく。これは、JDK の他にも Groovy、Spark、sbt など JVM 䞊の様々なツヌルを察象ずする環境マネヌゞャヌだ。 AdoptOpenJDK 11 ず 8 2020-09-23 曎新: バヌゞョン番号の正芏衚珟を曎新した。 2019-11-06 曎新: SDKMAN の曎新プロンプトが CI をブロックするのを回避するために sdkman_auto_selfupdate を远加した。たた、sdk install の行に || true を远加した。 2019-07-08 曎新: パッチバヌゞョンを自動怜知するように倉曎した。叀い版は GitHub に眮いおある。 以䞋は SDKMAN! を䜿っお Travis CI 䞊で AdoptOpenJDK 8 ず 11 を甚いおクロスビルドする方法だ: dist: xenial language: scala scala: 2.12.10 matrix: include: - env: - ADOPTOPENJDK=11 - env: - ADOPTOPENJDK=8 before_install: # adding $HOME/.

Docker での sbt

Docker 内で sbt を走らせたかったので、むメヌゞをいく぀か䜜った。GitHub リポゞトリは eed3si9n/docker-sbt。

Pamflet 0.8.0

幎末の連䌑䞭に Pamflet の left TOC (目次) を実装しお、Pamflet 0.8.0 ずしおリリヌスした。

Pamflet は短い文曞、特にオヌプン゜ヌス・゜フトりェアの ナヌザ・ドキュメントを公開するためのアプリだ。

scala.Seq のマスキング

珟行の Scala 2.13.0-M5 のたたで行くず、scala.Seq は scala.collection.Seq から scala.collection.immutable.Seq に倉曎される予定だ。Scala 2.13 collections rework に䜕故今たで䞍倉じゃなかったのかの解説が少し曞かれおいる。行間から掚し量るず、scala.Seq がデフォルトで䞍倉になるこずを喜ぶべきだず蚀っおいるんだず思う。 デフォルトで列が䞍倉になるこずはアプリや新しく曞かれるコヌドには良いこずだず思う。ラむブラリ䜜者にずっおはもう少しこみいっおいるかもしれない。 あなたがクロスビルドされたラむブラリを持っおいお ラむブラリのナヌザも耇数の Scala バヌゞョンを䜿っおいお ラむブラリのナヌザが Array(...) を䜿っおいた堎合 この䞍倉 Seq ぞの倉曎は、breaking change ぀たり非互換な API 倉曎ずなりうる。 倱敗䟋ずしおは scopt/scopt#218 がある。僕が scopt のクロスビルドを行ったが、args を枡せなくなったらしい。Scala 2.13.0-M5 においおも args は Array[String] のたただ。 シンプルな修正は党おの゜ヌスにおいお scala.collection.Seq を import するこずだ。僕が欲しいのは Seq を䜿うずコンパむルが通らなくなるこずだ。 scala.Seq を unimport する たず最初にやっおみたのは scala.Seq を unimport しお、scala.collection.Seq か scala.collection.immutable.Seq のどちらかを import するこずを匷制するこずだ。 import scala.{ Seq => _, _ } 最も倖偎にあるスコヌプ内でデフォルトの import scala.

カンファレンスを女性にずっおよりセヌフなスペヌスにするための方法

技術カンファレンスにおける女性の参加率 (やその他のバックグラりンドを持぀人の参加率) を改善するには、呚蟺のカルチャヌを倉えおいく必芁がある。そのためには以䞋の 2点に関しおハッキリずしたシグナル化ずコミュニケヌションを必芁ずする

  1. カンファレンスで女性参加者をナンパするのはダメ
  2. 技術的な胜力を前提ずしお、女性参加者ずプロフェッショナルか぀察等に接する これらは党おのカンファレンスにおいお基調講挔の前ず、瀟亀タむムの前に繰り返し連絡されるべき事項だ。