KotlinlangのSlackでThank Youが明るくなった話

qiita.com

この記事はSwift/Kotlin愛好会 Advent Calendar 2023の3日目の記事になりました。


Kotlin言語には、JetBrainsの管理する公式Slackワークスペースが有ります。

kotlinlang.slack.com

このワークスペースでは、現在:thank-you-color:として以下のスタンプが使われています。

このスタンプの導入にまつわるJetBrainsさんの神対応について書きます。

以前のスタンプの問題点

以前のスタンプを再現すると、以下のようなものでした。

改行無しだったため見にくく、黒一色・透過有りだったせいで、ダークモードにすると更に読みにくくなっていました。
悪いことに、当時は:not-kotlin:という割と否定的な意味のスタンプも同様のフォーマットで存在しており、両者を見分けにくいという問題も有りました。

変更のきっかけ

この辺りのことが気になった自分は、変更を提案してみました。

slack-chats.kotlinlang.org

すると、何と約1日ほどでKotlinのテーマカラーを意識したスタンプを用意してもらうことができました。

現在古いスタンプは削除され、コミュニティの全員が感謝を鮮やかに示すことが出来るようになっています。

終わりに

KotlinlangSlackJetBrainsさんに神対応して頂いた話でした。

KotlinlangSlackには日々Kotlinの様々な話が流れており、様々な話題を読むことが出来るので、是非参加してみて下さい。
また、Kotlinlang本家のjapaneseチャンネルや、kotlinlang-jpSwift/Kotlin愛好会など、日本語コミュニティもお勧めです!

【Gradle】Windows環境でorg.gradle.api.InvalidUserDataException: Source directory ... is not a directory.になる問題への対処

一度ローカルからプロジェクトを消した上で、以下のようにcloneし直すことで解決します。

git clone -c core.symlinks=true https://github.com/<your_name_here>/<your_repository_here>

参考にさせて頂いたサイト

github.com

github.com

文脈

自分はokioをビルドしようとしてこの問題に当たりました。

github.com

KotlinプロジェクトでGradle 7.6.2 -> Gradle 8.3移行をした時の作業メモ

自分が取り組んでいるKotlinOSSプロジェクトにて、Gradle 7.6.2 -> Gradle 8.3の移行をやった際にハマったことのメモです。

github.com

きっかけ

このプロジェクトには、GitHub ActionsKotlin x Javaのバージョンを組み合わせ毎の挙動を確認するグリッドテストが有ります。

このテストにK2コンパイラを使うパターンも追加しようとした所、関係の無いはずのケースが失敗するようになりました。
エラーログを確認した所キャッシュ起因に見えたので、キャッシュを全消ししてやり直した所、当該箇所は直ったものの、今度はJava 20を使うケース全てが失敗するようになりました。

エラーログには以下のように表示されていました。

* What went wrong:
Could not open cp_init generic class cache for initialization script '/home/runner/.gradle/init.d/gradle-build-action.build-result-capture.init.gradle' (/home/runner/.gradle/caches/7.6.2/scripts/9b672n24db1z169ivld6c2v82).
> BUG! exception in phase 'semantic analysis' in source unit '_BuildScript_' Unsupported class file major version 64

対応

Gradleのアップデート

エラーログを検索したところ、Javaバージョンの不整合という情報が引っかかったため、Gradleバージョンの移行を決断しました。

discuss.gradle.org

バージョンアップは以下の2コマンドを実行することで行いました。

./gradlew wrapper --gradle-version=8.3
./gradlew wrapper

build.gradle.ktsの修正

buildDir -> layout.buildDirectory

プロジェクト内でbuildDirを参照している部分が有りましたが、当該プロパティは非推奨化していたので、以下のように変更を行いました。

- val generatedSrcPath = "$buildDir/generated/kotlin"
+ val generatedSrcPath = "${layout.buildDirectory.get()}/generated/kotlin"

compileTestKotlinへのjvmTarget指定

変更後、Kotlin 1.8以降 & Java 11以上の場合compileTestKotlinが落ちるようになりました。
エラーログは以下のようになっておりました。

* What went wrong:
Execution failed for task ':compileTestKotlin'.
> 'compileTestJava' task (current target is 1.8) and 'compileTestKotlin' task (current target is 11) jvm target compatibility should be set to the same Java version.
  Consider using JVM toolchain: https://kotl.in/gradle/jvm/toolchain

当該プロジェクトではjvmTargetJava 8を指定していますが、どうもKotlin 1.8以降の場合compileTestKotlin側にも同様の指定が無ければ不整合扱いになるようです。
以下の記述を追記して対応しました(もしかするとjvmTargetを消す方が望ましいかもしれません)。

tasks {
    /* 略 */
+   compileTestKotlin {
+       kotlinOptions.jvmTarget = "1.8"
+   }
    /* 略 */
}

感想

最初のバグは何だったのか、何故キャッシュ削除前はJava 20のテストが成功していたのか、深い謎が残りましたが、一旦K2のテストも成功しているので気にしないことにします……。

【Gradle】Windows環境でjmh-gradle-pluginの出力ファイルをUTF-8にする

TL;DR

  • gradle.propertiesorg.gradle.jvmargs-Dfile.encoding=UTF-8を指定するのが良さそう
  • jmh-gradle-pluginに指定する方法は無さそう

背景

jmh-gradle-plugin(me.champeau.gradle.jmh)は、環境に合わせた文字コードhumanOutputFileを出力します。
このため、何も指定しない場合Windows環境ではShift-JISで出力されます。

ここで、IntelijからhumanOutputFileを開く場合、この挙動によって±が文字化けし、コピペも難しくなる問題が有ります。

対処

C:\Users\${ユーザー名}\.gradlegradle.propertiesファイルを用意し、以下の内容を追記しました。

org.gradle.jvmargs=-Xmx2g -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8

重要なのは-Dfile.encoding=UTF-8オプションで、これによって出力の文字コードUTF-8になります。

jmh-gradle-plugin側のオプションも確認しましたが、出力ファイルの文字コードを変更するようなオプションは無いようでした。

補足: 指定内容について

この指定内容はGradle公式ドキュメントの以下の記述からコピーしたものです。

docs.gradle.org

この指定では、デフォルトより多くメモリを消費します。
自分のローカルではメモリ容量に余裕が有ったため、パフォーマンス向上を目的にこのオプションを指定しています。

【Flyway】特定イベント後に実行するSQLファイルを設定する

やりたいこと

flywayによるマイグレーションでテーブルが追加された場合に、共通のトリガー設定SQLを動かすようなことをします。
生で書いてしまった場合1度しか実行されないため、これを実現するには工夫が必要です。

やり方

Callback機能を利用することで実現できます。
自分の場合マイグレーション成功時にのみ実行したかったため、afterMigrate__${識別用の名前}.sqlを作成・配置しました。

その他どのようなCallbackが存在するかは公式資料をご覧下さい。

documentation.red-gate.com

【Googleスプレッドシート】複数の範囲を1列にまとめる(結合する)

この辺り知識が薄いので、もっと良いやり方が有りましたらコメント頂けると嬉しいです。

やり方

FLATTEN関数を使えばできるようでした。

support.google.com

例えば、「E2:E40の範囲からB2より大きいものをFILTERした結果とG2:G40の範囲からB2より大きいものをFILTERした結果を結合する」場合、=FLATTEN(FILTER(E2:E40, B2 <= E2:E40), FILTER(G2:G40, B2 <= G2:G40))というように書けます。

注意点

この関数は、例えば複数列有るデータに対して適用した場合も1列に均してしまう点に注意が必要です。
例えば以下のように変換されてしまいます。

E2 F2
E3 F3

=FLATTEN(E2:F3)

E2
F2
E3
F3

フィルタ対象のデータと値になるデータが分かれている場合、=FLATTEN(...を複数回書くなり、他の方法で結合する必要が有ります。

【Gradle】プラグインバージョンを対象にグリッドテストを作成する【GitHub Actions】

TL;DR

  • gradle.kts利用の場合、引数をpluginsブロックで参照することはできないようだった
  • 代替案としては、環境変数に設定 -> System.getenvで読み出す形式にするのが一番シンプルそうだった

やり方

紹介する内容は以下からの抜粋です(余計なdiffが入ってしまっていますが、lint-and-test-main.ymlbuild.gradle.ktsだけ見て頂ければ大丈夫です)。
Kotlinのバージョンが対象です。

github.com

build.gradle.kts側の設定

環境変数から設定を取得し、取得できなければデフォルトを用いるように設定しています。

plugins {
    val kotlinVersion: String = System.getenv("KOTLIN_VERSION")?.takeIf { it.isNotEmpty() } ?: "1.7.21"
    kotlin("jvm") version kotlinVersion

    /* ... */

}

GitHub Actions側の設定

最低限の設定を抜き出した部分は以下の通りです。

    strategy:
      matrix:
        kotlin-version: [ '1.7.21', '1.8.10', '1.8.20-Beta' ]
    env:
      KOTLIN_VERSION: ${{ matrix.kotlin-version }}

補足

引数での指定について

pluginsブロックで引数(コマンドライン-PkotlinVersion=1.7.21のように入力する)を参照する方法が見つからず、とりあえず動いた環境変数での指定を採用しました。
厳密に言うと環境変数は環境によって影響を受ける可能性が有るため、あまり利用したくありませんでしたが、現在ktsでこれを回避する方法は無いようでした。
この問題は以下のイシューで議論されています。

github.com

Version Catalogを利用している場合

Version Catalogを利用している場合、以下のようにすることでできました。

github.com

やっていることの簡単な説明です。

  1. gradle/libs.versions.tomlKotlinのデフォルトバージョンと、関連して利用する依存を記述
  2. settings.gradle.ktsdependencyResolutionManagementブロックで、環境変数から必要に応じて1で指定したバージョンを上書き
  3. build.gradle.ktsではプラグインalias(libs.plugins.${pluginsブロックに指定した名前})で参照する(バグでエラー表示が出るため抑制も行う)

自分も全体は理解し切れていませんが、以下のプロジェクトを参考に作成しました。

github.com