build.gradle.kts関係で、自分で2回以上検索したものです。自分の三回目用に。
基本Multiplatform志向。
環境
Ubuntuにgradleインストール
Note: aptでインストールすると標準リポジトリのは古い(gradle-4.4とか)。
Note: 多くの場合java+gradlewで事足りるのでInstall不要
本家 https://services.gradle.org/distributions/ から取得
version=8.7
wget https://services.gradle.org/distributions/gradle-$version-bin.zip
sudo unzip -d /opt/gradle gradle-$version-bin.zip
sudo ln -s /opt/gradle/gradle-$version/bin/gradle /usr/local/bin/
コンパイルオプション指定
tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile> {
kotlinOptions {
languageVersion = "1.7"
freeCompilerArgs = listOf("-Xcontext-receivers")
}
}
オブジェクト-文字列変換 - Serialization
plugins {
kotlin("plugin.serialization") version "2.0.0" // https://plugins.gradle.org/plugin/org.jetbrains.kotlin.plugin.serialization
}
//...
dependencies{
implementation("org.jetbrains.kotlin:kotlin-serialization-json:2.0.0") // https://mvnrepository.com/artifact/org.jetbrains.kotlin/kotlin-serialization
}
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.encodeToString
@Serializable
data class MyType(val a: Int)
val v: MyType = Json.decodeFromString("""{"a":42}""")
val s = Json.encodeToString(v)
Coroutine
dependencies{
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.2") // https://mvnrepository.com/artifact/org.jetbrains.kotlinx/kotlinx-coroutines-core
}
日時 - DateTime
dependencies {
implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.6.2")
// https://mvnrepository.com/artifact/org.jetbrains.kotlinx/kotlinx-datetime
}
val format_yyyyMMddHHmmss =
LocalDateTime.Format { year(); monthNumber(); dayOfMonth(); char('_'); hour(); minute();second() }
val localTime = now().toLocalDateTime(currentSystemDefault())
println(localTime.format(format_yyyyMMddHHmmss))
ファイル入出力 - okio
dependencies{
implementation("com.squareup.okio:okio:3.8.0")
// https://mvnrepository.com/artifact/com.squareup.okio/okio
}
val fileSystem=FileSystem.SYSTEM
// val fileSystem=NodeJsFileSystem // Kotlin/js(Node.js)の場合
val projRoot = fileSystem.canonicalize("../../../..".toPath())
val result = projRoot.resolve("build/count.txt").apply { fileSystem.delete(this) }
fileSystem.listRecursively(projRoot.resolve("src"))
.filter { it.name.endsWith(".kt") }
.map { it to fileSystem.read(it) { generateSequence { readUtf8Line() }.count() } }
.forEach { p -> fileSystem.appendingSink(result).buffer().use { sink -> sink.writeUtf8("$p\n") } }
データをファイルに保存 - KStore
WebAppフレームワーク - Ktor
dependencies {
val ktor_version="2.1.1" // https://mvnrepository.com/artifact/io.ktor/ktor-server-core
implementation("io.ktor:ktor-server-cio:$ktor_version")
implementation("io.ktor:ktor-server-content-negotiation:$ktor_version")
implementation("io.ktor:ktor-serialization-kotlinx-json:$ktor_version")
}
dependencies {
val ktor_version="2.1.1" // https://mvnrepository.com/artifact/io.ktor/ktor-server-core
implementation("io.ktor:ktor-client-cio:$ktor_version")
implementation("io.ktor:ktor-client-content-negotiation:$ktor_version")
implementation("io.ktor:ktor-serialization-kotlinx-json:$ktor_version")
}
Json Client サンプル
Ktor Clientで証明書チェックを無効化する例
既存タスクに処理を追加 - 例1:build後生成されたファイルコピー
tasks["build"].doLast {
copy {
from("$buildDir/distributions")
into("$projectDir/dist")
}
}
※task生成されるタイミングによってはtaskがまだ存在しなくてエラーになる可能性あり[TODO]
既存タスクに処理を追加 - 例2:build前に環境変数値をコードに挿入
tasks["build"].doFirst {
copy {
from("src/main/kotlin/Properties.kt.tmpl")
into("src/main/kotlin/")
rename { "Properties.kt" }
filter { it.replace("$[APPKEY]", System.getenv("APPKEY") ?: "'export APPKEY=...'") }
}
}
val appKey="$[APPKEY]"
※誤ってAPPKEYを含んだProperties.kt をコミットしないよう注意。 例: gitの場合、src/main/kotlin/.gitignore に Properties.kt
を追記
ローカルMavenリポジトリへのアップロード
ローカルリポジトリにデプロイ
plugins{
`maven-publish`
}
publishing {
publications {
create<MavenPublication>("maven") {
groupId = "jp.wjg.shokkaa"
artifactId = "myappname"
version = "1.0.0"
from(components["kotlin"])
}
}
}
gradlew publishToMavenLocal
ローカルリポジトリの場所: ~\.m2\repository\
repositories {
mavenLocal()
}
dependencies {
implementation("jp.wjg.shokkaa:myappname:1.0.0")
}
ソースコード配置フォルダ指定
sourceSets.main {
java.srcDirs("src/main/myJava", "src/main/myKotlin")
}
Logging
- Kotlin Multiplatform logging libraries(お試し中。使えるかは未確認)
テスト
dependencies {
testImplementation(kotlin("test"))
}
tasks.withType<Test>().configureEach {
useJUnitPlatform()
}
class Tests {
@Test fun test1() {assert(2 + 3 == 6)} // Assertion failed
}
dependencies {
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.1")
testImplementation(kotlin("test"))
testImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:1.8.1")
}
class MyTests {
@Test fun test2() = runTest { delay(1.seconds) }
}
sh gradlew test --tests 'Tests'
sh gradlew test --tests 'Tests#test1'
dependencies {
testImplementation(kotlin("test"))
testImplementation("io.kotest:kotest-framework-engine:5.9.1")
testImplementation("io.kotest:kotest-assertions-core:5.9.1")
testImplementation("io.kotest:kotest-property:5.9.1")
testImplementation("io.kotest:kotest-extensions-jvm:5.9.1")
}
class Tests : FunSpec({
test("1") { 1 + 2 shouldBe 3 }
test("sum2") { 1 + 2 shouldNotBe 5 }
})
class Test2 : FunSpec() {
override fun isolationMode(): IsolationMode = IsolationMode.InstancePerLeaf
init {
var c = 0
test("inc1") { ++c shouldBe 1 }
test("inc2") { ++c shouldBe 1 shouldNotBe 2 }
}
}
kotest_filter_specs='Tests' sh ./gradlew test # テストクラス名指定
kotest_filter_tests='sum*' sh ./gradlew test # test()で指定のテスト名の正規表現
plugins{
id("io.kotest") version "6.0.0.M2" // https://plugins.gradle.org/plugin/io.kotest
}
関連ファイルをダウンロード
plugins {
// ...
id("de.undercouch.download") version "5.0.5" // https://github.com/michel-kraemer/gradle-download-task
}
// OpenCVをダウンロードするタスクの例
val downloadFiles by tasks.registering {
doLast {
download.run {
src("https://sourceforge.net/projects/opencvlibrary/files/4.5.5/opencv-4.5.5-vc14_vc15.exe/download")
dest("$buildDir/libs/opencv.exe")
}
}
}
build中のzipファイル展開
7zipプラグイン
plugins {
// ...
id("io.freefair.compress.7z") version "6.4.3" // https://plugins.gradle.org/plugin/io.freefair.compress.7z
}
外部のプログラムの実行
// OpenCVの自己解凍exe形式ファイルを実行(展開)しコピーする例(Windows用)
val extractOpenCV by tasks.registering {
doLast {
exec {
commandLine("$buildDir/libs/opencv.exe", "-o$buildDir", "-y")
}
copy {
from(fileTree("$buildDir/opencv/build/java/x64/"))
into("$projectDir")
}
}
//dependsOn(downloadOpenCV)
}
task("listDir") {
doLast {
project.exec {
commandLine("cmd", "/c", "dir")
standardOutput = file("dir_output.txt").outputStream()
}
}
}
※設定キャッシュ(org.gradle.configuration-cache=true)を有効にするとエラー(TODO)
依存ファイルまとめて一つのjarファイルにしたい
Kotlin1.5.20, Shadow7.0.0 で確認
https://github.com/johnrengelman/shadow
https://imperceptiblethoughts.com/shadow/
https://plugins.gradle.org/plugin/com.github.johnrengelman.shadow
※Shadowのメジャーバージョンはgradleに対応している模様(Shadow Version 7.0.0以降はgradle7が必要)
設定
plugins{
application
id("com.github.johnrengelman.shadow") version "7.1.2" // https://plugins.gradle.org/plugin/com.github.johnrengelman.shadow
}
application {
mainClass.set("mypackage.MainKt") // package mypackageかつファイル名main.ktのmain()を実行する場合
}
ビルド
gradlew shadowJar
build/libs 以下にjarファイルが生成される
実行(例)
java -jar build/libs/app-1.0-SNAPSHOT-all.jar
gradleのVersion指定(gradlewやIntelliJ使用)
...
distributionUrl=https\://services.gradle.org/distributions/gradle-6.8-bin.zip
...
外部のJarファイルを参照
dependencies {
implementation(files("****.jar")) // jarファイル等
}
プロジェクトへの依存関係 Example.11
[TODO] TypeSafeな外部プロジェクト指定 (7.0時点で実験的機能) enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS")
依存モジュール
plugins{
id("org.owasp.dependencycheck") version "11.1.0"
// https://plugins.gradle.org/plugin/org.owasp.dependencycheck
}
// 最近はNVDの脆弱性DB取得にAPI_KEYが(事実上)必須な模様
// https://nvd.nist.gov/developers/request-an-api-key
dependencyCheck {
nvd { apiKey = System.getenv("NVD_API_KEY") }
}
export NVD_API_KEY=XXXXXX
sh gradlew dependencyCheckAnalyze
# 結果: build/reports/dependency-check-report.html
plugins{
id("org.cyclonedx.bom") version "1.10.0" // https://plugins.gradle.org/plugin/org.cyclonedx.bom
}
group = "my-group" // 自身のBOM生成に必要
version = "1.0-SNAPSHOT" // 自身のBOM生成に必要
sh gradlew cyclonedxBom
# 結果: build/reports/bon.json
Proxy設定
[Windows][日本語] ビルド時のエラーメッセージが化ける場合
tasks.withType<JavaCompile> { options.encoding = "UTF-8" }