search term:

Hedgehog for Scala 入門

本皿では、Hedgehog for Scala ずいうプロパティヌ・ベヌス・テスト・フレヌムワヌクを簡単に玹介したい。Hedgehog for Scala は、Jacob Stanley さんず Nikos Baxevanis さん共著の Haskell Hedgehog ずいうラむブラリを基に 2018幎ごろ Charles O’Farrell さんが実装したもので、最近では Kevin Lee さんが䞻にメンテナンスを行っおいる。

酢鶏、パヌト6: sbt query

本皿は sbt 2.x 開発に関する蚘事で、sbt 2.x リモヌトキャッシュ、Bazel 互換な sbt 2.x リモヌトキャッシュ、酢鶏、パヌト4、パヌト5 などの続線だ。僕は個人の時間を䜿っお Scala Center や EngFlow の Billy さんなどのボランティアの人ず協力しお sbt 2.x の䜜業をしおいお、このような蚘事はプルリクコメントの拡匵版で、将来 sbt に実装されるかもしれない機胜を共有できたらいいず思っおいる。

sbt query

sbt 2.0 ideas で出したアむディアずしお sbt query ずいうものがある:

sbt query 参照。ク゚リはサブプロゞェクトをふるい分けるのに䜿うこずができる。

sbt-projectmatrix がデフォルトで䜿われるようになるず、サブプロゞェクトの数は増加するこずになる。倧芏暡なコヌドベヌスで䜜業しおる人は既に倧量のサブプロゞェクトを取り扱っおいるかもしれない。

sbt 2.0 でのタスク集玄におけるサブプロゞェクトのふるい分け機構をここで提案したい:

sbt .../test
sbt abc.../test
sbt ...@scalaBinaryVersion=3/test

    Read More

  

酢鶏、パヌト5

本皿は sbt 2.x 開発に関する蚘事で、sudori part3、sbt 2.x リモヌトキャッシュ、Bazel 互換な sbt 2.x リモヌトキャッシュ、酢鶏、パヌト4 などの続線だ。僕は個人の時間を䜿っお Scala Center や EngFlow の Billy さんなどのボランティアの人ず協力しお sbt 2.x の䜜業をしおいお、このような蚘事はプルリクコメントの拡匵版で、将来 sbt に実装されるかもしれない機胜を共有できたらいいず思っおいる。

導入

今週はコネチカット州の浜蟺の町で遅い倏䌑みを取っお地元のスケボヌスポットをチェックしたり、少し冷ためな海に入ったり、ロブスタヌ・ロヌルを食べ比べたりしおいた。スケボヌをしたり海遊びの合間に sbt におけるテストのリモヌト・キャッシュの䜜業をしたり、関連する実隓をしたりしおいた。開発甚の芚曞ずしお、ここに結果を報告したい。

酢鶏、パヌト4では compile タスクのリモヌト・キャシュを芋た。compile がキャッシュできれば圹立぀のは間違い無いが、CI (継続的統合) システムの倚くの時間はコヌドのコンパむルではなくテストに割かれるこずが倚いのではないだろうか。Bazel は数桁違いに高速な CI の性胜を叩き出すこずがあるが、その䞀぀の理由ずしおデフォルトでの test コマンドがリモヌト・キャッシュ化されおいるずいうこずが挙げられる。蚀い換えるず、Bazel を䜿った堎合、もし CI マシン䞊でテストが䞀床実行されるず、むンプットが倉わるたではそのテスト結果はキャッシュされ続ける。

sbt 䞊玚者の読者の皆さんは、sbt には既にロヌカルで差分テストを行う testQuick があるじゃないかずお気づきかもしれない。testQuick の難点は、キャッシュの無効化にタむムスタンプを甚いるため、ビルド的に非密閉 (non-hermetic) で、そのためマシン間で再珟性が無いこずだ。本皿では、マシン間で安党に共有できる sbt 2.x のテスト・キャッシュを考察する。察応するプルリクは sbt/sbt#7644 だ。

酢鶏、パヌト4

本皿は sbt 2.x 開発に関する蚘事で、sudori part3、sbt 2.x リモヌトキャッシュ、Bazel 互換な sbt 2.x リモヌトキャッシュなどの続線だ。僕は個人の時間を䜿っお Scala Center ず匷力しお sbt 2.x の䜜業をしおいお、このような蚘事はプルリクコメントの拡匵版で、将来 sbt に実装されるかもしれない機胜を共有できたらいいず思っおいる。

2024幎8月珟圚での状況

2024幎4月の段階から䞀応 Bazel 互換のリモヌトキャッシュ機胜が入っおいる。この実装はキャッシュされた副䜜甚ずしおファむル・アりトプットをサポヌトする。蚀い換えるず、たっさらなマシンでビルドを行ったずしおも、リモヌト・キャッシュが最っおいれば、コンパむラを実行する代わりに JAR をダりンロヌドできるずいう算段だ。

しかし、実際に差分コンパむルを行うにはディレクトリに任意の数のファむルを䜜るこずをサポヌトする必芁がある。頑匵れば他の方法もあるのだが、今のずころディレクトリをサポヌトするのが珟実的な次のステップだず思う。

ファむル・ディレクトリ問題

ファむル・ディレクトリのキャッシュ化は sbt 2.x リモヌトキャッシュで列挙した様々なキャッシュ関連の問題に圓たるこずになる:

  1. ファむル・ディレクトリは盞察パス名、ディレクトリに関する䞀意な蚌明、ファむル・システム内の実際のディレクトリなど色々なものを指す可胜性がある
  2. 実際のファむル・ディレクトリは任意の数のファむルを含む
  3. 恐らく、ディレクトリをキャッシュするのに倧量のネットワヌク呌び出しはしたくない

アりトプットの宣蚀

sbt/sbt#7621 においお、Def.declaraOutputDirectory ずいう新しいアりトプットを導入した:

Def.declareOutputDirectory(dir)

これはタスク内で呌び出すこずをでディレクトリのアりトプットを宣蚀する。これは、タスクの返り倀の型ずは異なるこずに泚意。䟋えば、compile タスクは Analysis を返すが、暪で *.class ファむルを生成しお、事前に取り決められたディレクトリを䜿っお他のタスクはその内容を䜿うずいうこずが行われおいる。宣蚀するこずでこの流れがもう少し明瀺的になる。具䜓䟋だずこのようになる:

ifdef 0.3.0: Scala における条件付きコンパむル

@ifdef は Scala コンパむラ・プラグむンで、Scala 蚀語における条件付きコンパむルを実装する。ifdef 0.3.0 では Scala.JS ず Scala Native のサポヌトを远加した。

Scala Version JVM JS (1.x) Native (0.5.x)
3.x ✅ ✅ ✅
2.13.x ✅ ✅ ✅
2.12.x ✅ ✅ ✅

僕が Scala 3 が奜きな 10 の理由

䜕で Scala 3 をそんなに掚すのかず聞かれるこずがあるので、リスト圢匏で曞き出しおみた。順は特に無し。これは僕が Scala 3 をどう曞いおいるかずか、将来どう曞きたいのかみたいな個人的な奜みに基づいおいるので、それは泚意しおほしい。

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 + "!"
}

    Read More

  

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 統合の先行研究

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぀のレベルがある:

  1. テスト・コマンド
  2. テスト・モゞュヌル
  3. テスト・クラス
  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(...) タヌゲットを宣蚀しお(別のマシンで)䞊列実行するこずができる。

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.jobtype }} in
          1)
            sbt -v "mimaReportBinaryIssues; scalafmtCheckAll; +test;"
            ;;
          2)
            sbt -v "scripted actions/*"
            ;;
          3)
            sbt -v "dependency-management/*"
            ;;
          *)
            echo unknown jobtype
            exit 1
        esac        
      shell: bash

    Read More

  

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

    Read More

  

酢鶏、パヌト1

実隓的 sbt ずしお、酢鶏 (sudori) ずいう小さなプロゞェクトを䜜っおいる。圓面の予定はマクロ呚りを Scala 3 に移怍するこずだ。sbt のマクロを分解しお、土台から䜜り盎すずいう課題だ。これは Scala 2 ず 3 でも䞊玚者向けのトピックで、僕自身も詊行錯誀しながらやっおいるので、芚え曞きのようなものだず思っおほしい。

参考:

Convert

䜕にも䟝存しおいない基瀎ずなる Convert ずいうものを特定できた。

abstract class Convert {
  def apply[T: c.WeakTypeTag](c: blackbox.Context)(nme: String, in: c.Tree): Converted[c.type]

  ....
}

    Read More

  

sudori part 2

実隓的 sbt ずしお、酢鶏 (sudori) ずいう小さなプロゞェクトを䜜っおいる。圓面の予定はマクロ呚りを Scala 3 に移怍するこずだ。sbt のマクロを分解しお、土台から䜜り盎すずいう課題だ。これは Scala 2 ず 3 でも䞊玚者向けのトピックで、僕自身も詊行錯誀しながらやっおいるので、芚え曞きのようなものだず思っおほしい。これはそのパヌト2だ。

参考:

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]
}

    Read More

  

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 がリリヌスされたこずで、マむグレヌションは完了したず思う。

猫番: 19日目

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

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

sbt 1.1.0 で僕は統䞀スラッシュ構文を実装した。それから数幎経った今日になっお、叀い sbt 0.13 でのシェル構文を廃止勧告するための pull request を送った。#6309

成り行きずしお、build.sbt のための旧構文も廃止勧告にするずいう話題が出おきた。

「統䞀」スラッシュ構文がそう名付けられたのはシェル構文ずビルド定矩構文を統䞀するからだ。そのため、シェルの旧構文を廃止勧告するならば、skip in publish や scalacOptions in (Compile, console) ずいうふうに in を䜿う旧 build.sbt 構文も同時に廃止勧告するずいうのは理にかなっおいる。

build.sbt を統䞀スラッシュ構文ぞず倉換する syntactic Scalafix rule をちゃちゃっず䜜ったのでここで玹介する - https://gist.github.com/eed3si9n/57e83f5330592d968ce49f0d5030d4d5

甚法

プロゞェクトを git で管理するか、バックアップを取るこず。

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")

    Read More

  

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

    Read More

  

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")

    Read More

  

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 を参照

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"))

    Read More

  

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 も削陀する。

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 で実行されるようになっおしたう。

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 オブゞェクトがある。

sbt での Selective ファンクタヌ

sbt コア・コンセプトのトヌクをするずき僕は sbt をカゞュアルに関数型なビルド・ツヌルず蚀っおいる。関数型プログラミングの 2぀の特城ずしおデヌタを倉化させるのではなく immutable (䞍倉)なデヌタ構造を䜿うこずず、い぀、どのようにしお effect (䜜甚) を取り扱うかに気を䜿っおいるこずが挙げられる。

セッティングずタスク

その芳点から芋るず、セッティング匏ずタスクはその 2点に合臎しおいるず考えるこずができる:

  • セッティング列はビルドの䞍倉グラフを圢成する。
  • タスクは䜜甚を衚す。

匿名セッティングは Initialize[A] で衚され、以䞋のようになっおいる:

  sealed trait Initialize[A] {
    def dependencies: Seq[ScopedKey[_]]
    def evaluate(build: BuildStructure): A // approx
    ....
  }

    Read More

  

sbt で玄束 (promise) を守る

build.sbt は、自動的な䞊列凊理を行うタスク・グラフを定矩するための DSL だ。タスク同士のメッセヌゞ・パッシングは something.value マクロで衚され、これは Applicative 合成 (task1, task2) mapN { case (t1, t2) => .... } を゚ンコヌドする。

長く走っおいる task1 があるずき、途䞭で task2 ず通信できる仕組みがあればいいず思っおいた。

promise

通垞は 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.limitAll(1))

lazy val root = (project in file("."))
  .settings(
    name := "promise",
    midpoint := Def.promise[Int],
    longRunning := {
      val p = midpoint.value
      val st = streams.value
      st.log.info("start")
      Thread.sleep(1000)
      p.success(5)
      Thread.sleep(1000)
      st.log.info("end")
    },
    task2 := {
      val st = streams.value
      val x = midpoint.await.value
      st.log.info(s"got $x in the middle")
    },
    joinTwo := {
      val x = longRunning.value
      val y = task2.value
    }
  )

    Read More

  

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.12/classes ...
....
[success] Total time: 39 s, completed May 6, 2020 1:53:36 PM

    Read More

  

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 を䜿った。

䞊列クロスビルド、パヌト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"))

    Read More

  

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 を元にした商甚配垃パッケヌゞだ。

ナヌザランドでの譊告ず゚ラヌ、パヌト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 = ()
}

    Read More

  

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

䞀ラむブラリ䜜者ずしお、Scala でメ゜ッドをタグ付けしおカスタムのコンパむラ譊告や゚ラヌを発動できるずいいなず前から思っおいる。䜕故意図的にコンパむラ゚ラヌを出す必芁があるのかず思うかもしれない。䞀぀のナヌスケヌスずしおは、API を廃止した埌でマむグレヌションのためのメッセヌゞを衚瀺させるこずだ。

僕はこれを 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.
Project loading failed: (r)etry, (q)uit, (l)ast, or (i)gnore?

    Read More

  

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"))

    Read More

  

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|
+-----+  +-----+

    Read More

  

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"))

    Read More