diff --git a/.idea/kotlinx-rpc.iml b/.idea/kotlinx-rpc.iml index 5326dceee..1fdae3590 100644 --- a/.idea/kotlinx-rpc.iml +++ b/.idea/kotlinx-rpc.iml @@ -8,6 +8,7 @@ + \ No newline at end of file diff --git a/.puppeteerrc.cjs b/.puppeteerrc.cjs index cf9afa888..44011893f 100644 --- a/.puppeteerrc.cjs +++ b/.puppeteerrc.cjs @@ -1,6 +1,6 @@ const {join} = require('path'); -const isCI = process.env.TEAMCITY_VERSION +const isCI = process.env.TEAMCITY_VERSION || process.env.GITHUB_ACTIONS; if (isCI) { /** diff --git a/bom/build.gradle.kts b/bom/build.gradle.kts index ea1df3301..f1a3bf959 100644 --- a/bom/build.gradle.kts +++ b/bom/build.gradle.kts @@ -3,7 +3,7 @@ */ import util.KOTLINX_RPC_PREFIX -import util.isPublicModule +import util.other.isPublicModule plugins { `java-platform` diff --git a/build.gradle.kts b/build.gradle.kts index 58c89c461..ec71b2d56 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -3,87 +3,16 @@ */ import org.jetbrains.kotlin.gradle.plugin.getKotlinPluginVersion -import util.asDokkaVersion -import util.configureNpm -import util.configureProjectReport -import util.registerDumpPlatformTableTask -import util.registerChangelogTask -import util.libs -import util.registerVerifyPlatformTableTask -import java.time.Year plugins { alias(libs.plugins.serialization) apply false alias(libs.plugins.kotlinx.rpc) apply false + alias(libs.plugins.atomicfu) apply false alias(libs.plugins.conventions.kover) alias(libs.plugins.conventions.gradle.doctor) - alias(libs.plugins.dokka) - alias(libs.plugins.atomicfu) - id("build-util") + alias(libs.plugins.conventions.root) } -dokka { - val libDokkaVersion = libs.versions.kotlinx.rpc.get().asDokkaVersion() - - moduleVersion.set(libDokkaVersion) - - val pagesDirectory = layout.projectDirectory - .dir("docs") - .dir("pages") - - val dokkaVersionsDirectory = pagesDirectory - .dir("api") - .asFile - - val templatesDirectory = pagesDirectory - .dir("templates") - - pluginsConfiguration { - html { - customAssets.from( - "docs/pages/assets/logo-icon.svg", - "docs/pages/assets/homepage.svg", // Doesn't work due to https://github.com/Kotlin/dokka/issues/4007 - ) - - footerMessage = "© ${Year.now()} JetBrains s.r.o and contributors. Apache License 2.0" - homepageLink = "https://kotlin.github.io/kotlinx-rpc/get-started.html" - - // replace with homepage.svg once the mentioned issue is resolved - templatesDir.set(templatesDirectory) - } - - // enable versioning for stable -// versioning { -// version = libDokkaVersion -// olderVersionsDir = dokkaVersionsDirectory -// } - } - - dokkaPublications.html { - outputDirectory = dokkaVersionsDirectory - } - - tasks.clean { - delete(dokkaVersionsDirectory) - } - - dokkaGeneratorIsolation = ProcessIsolation { - // Configures heap size, use if start to fail with OOM on CI -// maxHeapSize = "4g" - } -} - -dependencies { - dokkaPlugin(libs.dokka.rpc.plugin) -} - -configureProjectReport() -configureNpm() - -registerDumpPlatformTableTask() -registerVerifyPlatformTableTask() -registerChangelogTask() - val kotlinVersion = rootProject.libs.versions.kotlin.lang.get() val kotlinCompiler = rootProject.libs.versions.kotlin.compiler.get() diff --git a/compiler-plugin/build.gradle.kts b/compiler-plugin/build.gradle.kts index a4e388966..7d6768c45 100644 --- a/compiler-plugin/build.gradle.kts +++ b/compiler-plugin/build.gradle.kts @@ -6,7 +6,6 @@ import util.whenForIde plugins { alias(libs.plugins.conventions.gradle.doctor) - id("build-util") } val rpcVersion: String = libs.versions.kotlinx.rpc.get() @@ -30,5 +29,5 @@ println( ) whenForIde { - println("For-ide project mode enabled") + println("[Compiler Plugin] For-ide project mode enabled") } diff --git a/compiler-plugin/compiler-plugin-k2/build.gradle.kts b/compiler-plugin/compiler-plugin-k2/build.gradle.kts index 2205f003b..31d312196 100644 --- a/compiler-plugin/compiler-plugin-k2/build.gradle.kts +++ b/compiler-plugin/compiler-plugin-k2/build.gradle.kts @@ -2,70 +2,23 @@ * Copyright 2023-2025 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. */ -import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar import org.jetbrains.kotlin.gradle.dsl.ExplicitApiMode import util.enableContextParameters -import util.otherwise import util.whenForIde import util.whenKotlinCompilerIsAtLeast plugins { alias(libs.plugins.conventions.jvm) alias(libs.plugins.compiler.specific.module) - alias(libs.plugins.shadow.jar) } -/* -This is a hack to solve the next problem: - -There is PsiElement class that is used in compiler and plugin. - -If we use kotlin-compiler-embeddable.jar to compile the module, -PsiElement is org.jetbrains.kotlin.com.jetbrains.intellij.PsiElement. -And it works ok in the user projects! - -But. - -If we run tests, which use kotlin-compiler.jar, we run into ClassNotFoundException. -Because the class it has in th classpath is com.jetbrains.intellij.PsiElement - -- Alright, we can use kotlin-compiler.jar to compile the plugin. -- No, because the same error now will occur in the user projects, - but it is com.jetbrains.intellij.PsiElement that is not found. - -- Ok, we can use kotlin-compiler-embeddable.jar to compile tests. -- Then we ran into java.lang.VerifyError: Bad type on operand stack, which I have no idea how to fix. - -This solution replaces org.jetbrains.kotlin.com.jetbrains.intellij.PsiElement usages in plugin -with com.jetbrains.intellij.PsiElement only for the tests, fixing both use cases. -It is basically a reverse engineering of what Kotlin does for the embedded jar. - */ -val shadowJar = tasks.named("shadowJar") { - configurations = listOf(project.configurations.compileClasspath.get()) - relocate("org.jetbrains.kotlin.com.intellij.psi", "com.intellij.psi") - - exclude("javaslang/**") - exclude("kotlin/**") - exclude("messages/**") - exclude("misc/**") - exclude("org/**") - - archiveFileName.set("plugin-k2-for-tests.jar") - - /** - * Same problem as above, but in IDE - */ +tasks.jar { + // important for IDEA plugin whenForIde { archiveClassifier.set("for-ide") - } otherwise { - archiveClassifier.set("tests") } } -tasks.jar { - finalizedBy(shadowJar) -} - kotlin { explicitApi = ExplicitApiMode.Disabled diff --git a/compiler-plugin/gradle.properties b/compiler-plugin/gradle.properties deleted file mode 120000 index 7677fb73b..000000000 --- a/compiler-plugin/gradle.properties +++ /dev/null @@ -1 +0,0 @@ -../gradle.properties \ No newline at end of file diff --git a/compiler-plugin/gradle.properties b/compiler-plugin/gradle.properties new file mode 100644 index 000000000..b64cbf878 --- /dev/null +++ b/compiler-plugin/gradle.properties @@ -0,0 +1,40 @@ +# +# Copyright 2023-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. +# + +kotlin.code.style=official + +kotlin.native.ignoreDisabledTargets=true + +kotlin.daemon.jvmargs=-Xmx6g -XX:+HeapDumpOnOutOfMemoryError +kotlin.daemon.useFallbackStrategy=false + +org.gradle.jvmargs=-Xmx6g -XX:+HeapDumpOnOutOfMemoryError -XX:+UseParallelGC -XX:MaxMetaspaceSize=768m +org.gradle.daemon=true +org.gradle.parallel=true +org.gradle.workers.max=8 +org.gradle.caching=true +org.gradle.configuration-cache=true + +org.jetbrains.dokka.experimental.gradle.pluginMode=V2Enabled +org.jetbrains.dokka.experimental.gradle.pluginMode.noWarn=true + +# development mode for kotlinx.rpc gradle plugin. Uses local project paths to apply the compiler plugin +kotlinx.rpc.plugin.internalDevelopment=true + +# uncomment to debug compilation process +#kotlin.compiler.execution.strategy=in-process + +# Uncomment to skip attempts to publish Develocity build scans +# Add this property to ~/.gradle/gradle.properties to avoid polluting git with unwanted changes +#kotlinx.rpc.develocity.skipBuildScans=true + +# Uncomment to skip adding git tags to Develocity build scan +# Add this property to ~/.gradle/gradle.properties to avoid polluting git with unwanted changes +#kotlinx.rpc.develocity.skipGitTags=true + +# Uncomment to sync IDEA when working with Kotlin master builds +#kotlinx.rpc.kotlinMasterBuild=true + +# set to true when building IDE compiler plugin artifacts +kotlinx.rpc.forIdeBuild=false diff --git a/core/build.gradle.kts b/core/build.gradle.kts index 8dc35d2da..5ce2f5b22 100644 --- a/core/build.gradle.kts +++ b/core/build.gradle.kts @@ -2,15 +2,12 @@ * Copyright 2023-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. */ -import util.applyAtomicfuPlugin - plugins { alias(libs.plugins.conventions.kmp) alias(libs.plugins.kotlinx.rpc) + alias(libs.plugins.atomicfu) } -applyAtomicfuPlugin() - kotlin { sourceSets { commonMain { diff --git a/docs/Multiple-Kotlin-Versions-Support.md b/docs/Multiple-Kotlin-Versions-Support.md deleted file mode 100644 index bcd040f51..000000000 --- a/docs/Multiple-Kotlin-Versions-Support.md +++ /dev/null @@ -1,13 +0,0 @@ -# Multiple Kotlin Versions Support - - -### Compiler specific dependencies releases: -- atomicfu: https://github.com/Kotlin/kotlinx-atomicfu/releases -- serialization: https://github.com/Kotlin/kotlinx.serialization/releases -- coroutines: https://github.com/Kotlin/kotlinx.coroutines/releases -- ktor: https://github.com/ktorio/ktor/releases -- detekt-gradle-plugin: https://github.com/detekt/detekt/releases -- kotlin-logging: https://github.com/oshai/kotlin-logging/releases -- gradle-kotlin-dsl: https://plugins.gradle.org/plugin/org.gradle.kotlin.kotlin-dsl -- binary-compatibility-validator: https://github.com/Kotlin/binary-compatibility-validator/releases -- kover: https://github.com/Kotlin/kotlinx-kover/releases diff --git a/dokka-plugin/build.gradle.kts b/dokka-plugin/build.gradle.kts index fa98a2889..66fceb1bd 100644 --- a/dokka-plugin/build.gradle.kts +++ b/dokka-plugin/build.gradle.kts @@ -4,17 +4,13 @@ plugins { alias(libs.plugins.conventions.gradle.doctor) - id("build-util") alias(libs.plugins.kotlin.jvm) } -val rpcVersion: String = libs.versions.kotlinx.rpc.get() -val kotlinLangVersion = libs.versions.kotlin.lang.get() - group = "org.jetbrains.kotlinx" -version = rpcVersion +version = libs.versions.kotlinx.rpc.get() -println("[Dokka Plugin] kotlinx.rpc project version: $version, Kotlin version: $kotlinLangVersion") +println("[Dokka Plugin] kotlinx.rpc project version: $version, Kotlin version: ${libs.versions.kotlin.lang.get()}") kotlin { jvmToolchain(8) @@ -26,7 +22,7 @@ dependencies { testImplementation(kotlin("test")) testImplementation(libs.dokka.base) - testImplementation("org.jetbrains.dokka:dokka-test-api:${libs.versions.dokka.get()}") - testImplementation("org.jetbrains.dokka:dokka-base-test-utils:${libs.versions.dokka.get()}") - testImplementation("org.jetbrains.dokka:analysis-kotlin-symbols:${libs.versions.dokka.get()}") + testImplementation(libs.dokka.test.api) + testImplementation(libs.dokka.base.test.utils) + testImplementation(libs.dokka.analysis.kotlin.symbols) } diff --git a/dokka-plugin/gradle.properties b/dokka-plugin/gradle.properties new file mode 100644 index 000000000..b64cbf878 --- /dev/null +++ b/dokka-plugin/gradle.properties @@ -0,0 +1,40 @@ +# +# Copyright 2023-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. +# + +kotlin.code.style=official + +kotlin.native.ignoreDisabledTargets=true + +kotlin.daemon.jvmargs=-Xmx6g -XX:+HeapDumpOnOutOfMemoryError +kotlin.daemon.useFallbackStrategy=false + +org.gradle.jvmargs=-Xmx6g -XX:+HeapDumpOnOutOfMemoryError -XX:+UseParallelGC -XX:MaxMetaspaceSize=768m +org.gradle.daemon=true +org.gradle.parallel=true +org.gradle.workers.max=8 +org.gradle.caching=true +org.gradle.configuration-cache=true + +org.jetbrains.dokka.experimental.gradle.pluginMode=V2Enabled +org.jetbrains.dokka.experimental.gradle.pluginMode.noWarn=true + +# development mode for kotlinx.rpc gradle plugin. Uses local project paths to apply the compiler plugin +kotlinx.rpc.plugin.internalDevelopment=true + +# uncomment to debug compilation process +#kotlin.compiler.execution.strategy=in-process + +# Uncomment to skip attempts to publish Develocity build scans +# Add this property to ~/.gradle/gradle.properties to avoid polluting git with unwanted changes +#kotlinx.rpc.develocity.skipBuildScans=true + +# Uncomment to skip adding git tags to Develocity build scan +# Add this property to ~/.gradle/gradle.properties to avoid polluting git with unwanted changes +#kotlinx.rpc.develocity.skipGitTags=true + +# Uncomment to sync IDEA when working with Kotlin master builds +#kotlinx.rpc.kotlinMasterBuild=true + +# set to true when building IDE compiler plugin artifacts +kotlinx.rpc.forIdeBuild=false diff --git a/gradle-conventions-settings/build.gradle.kts b/gradle-conventions-settings/build.gradle.kts index 57d367312..31bf34f98 100644 --- a/gradle-conventions-settings/build.gradle.kts +++ b/gradle-conventions-settings/build.gradle.kts @@ -3,7 +3,7 @@ */ plugins { - alias(libs.plugins.gradle.kotlin.dsl) + `kotlin-dsl` } dependencies { diff --git a/gradle-conventions-settings/develocity/build.gradle.kts b/gradle-conventions-settings/develocity/build.gradle.kts index 931ab66b6..92796cedb 100644 --- a/gradle-conventions-settings/develocity/build.gradle.kts +++ b/gradle-conventions-settings/develocity/build.gradle.kts @@ -3,10 +3,10 @@ */ plugins { - alias(libs.plugins.gradle.kotlin.dsl) + `kotlin-dsl` } dependencies { - implementation("com.gradle:develocity-gradle-plugin:3.17") - implementation("com.gradle:common-custom-user-data-gradle-plugin:2.2.1") + implementation(libs.develocity) + implementation(libs.common.custom.user.data) } diff --git a/gradle-conventions-settings/develocity/src/main/kotlin/conventions-develocity.settings.gradle.kts b/gradle-conventions-settings/develocity/src/main/kotlin/conventions-develocity.settings.gradle.kts index 89f7bd273..027d8d62d 100644 --- a/gradle-conventions-settings/develocity/src/main/kotlin/conventions-develocity.settings.gradle.kts +++ b/gradle-conventions-settings/develocity/src/main/kotlin/conventions-develocity.settings.gradle.kts @@ -16,6 +16,9 @@ develocity { server.set(DEVELOCITY_SERVER) buildScan { + termsOfUseUrl = "https://gradle.com/terms-of-service" + termsOfUseAgree = loadAgreement() + uploadInBackground.set(!isCIRun) // obfuscate NIC since we don't want to expose user real IP (will be relevant without VPN) @@ -35,7 +38,7 @@ develocity { .getOrElse("false") .toBooleanStrict() - publishing.onlyIf { !skipBuildScans } + publishing.onlyIf { termsOfUseAgree.get() == "yes" && !skipBuildScans } } } diff --git a/gradle-conventions-settings/develocity/src/main/kotlin/execute.kt b/gradle-conventions-settings/develocity/src/main/kotlin/execute.kt index fd12377d9..9df72e4a4 100644 --- a/gradle-conventions-settings/develocity/src/main/kotlin/execute.kt +++ b/gradle-conventions-settings/develocity/src/main/kotlin/execute.kt @@ -4,7 +4,6 @@ import org.gradle.api.initialization.Settings -@Suppress("UnstableApiUsage") fun Settings.execute(cmd: String): String { return settings.providers.exec { commandLine(cmd.split(" ")) diff --git a/gradle-conventions-settings/develocity/src/main/kotlin/loadAgreement.kt b/gradle-conventions-settings/develocity/src/main/kotlin/loadAgreement.kt new file mode 100644 index 000000000..454eca75a --- /dev/null +++ b/gradle-conventions-settings/develocity/src/main/kotlin/loadAgreement.kt @@ -0,0 +1,66 @@ +/* + * Copyright 2023-2025 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. + */ + +import org.gradle.api.GradleException +import org.gradle.api.initialization.Settings +import org.gradle.kotlin.dsl.extra +import java.nio.file.Path +import java.nio.file.StandardOpenOption +import kotlin.io.path.bufferedWriter +import kotlin.io.path.createFile +import kotlin.io.path.exists + +private const val TERMS_OF_USE_PROPERTY = "kotlinx.rpc.develocity.termsOfUseAgree" + +fun Settings.loadAgreement(): String { + if (isCIRun) { + return "yes" + } + + val localProperties = extra["localProperties"] as? java.util.Properties + ?: throw GradleException("'local.properties' property not found") + + when (val value = localProperties.getProperty(TERMS_OF_USE_PROPERTY)) { + "yes", "no" -> { + return value + } + + "" -> { + throw GradleException( + "'$TERMS_OF_USE_PROPERTY' property is not set in file://local.properties'. " + + "Please set this property to 'yes' or 'no'." + ) + } + + null -> { + val globalRootDir = extra["globalRootDir"] as? String + ?: throw GradleException("'globalRootDir' property not found. Contact developers.") + + val propFile = Path.of(globalRootDir).resolve("local.properties") + if (!propFile.exists()) { + propFile.createFile() + } + + propFile.bufferedWriter(Charsets.UTF_8, bufferSize = 1024, StandardOpenOption.APPEND).use { writer -> + writer.appendLine() + writer.appendLine("# Terms of Gradle use agreement: https://gradle.com/terms-of-service") + writer.appendLine("# Set to yes or no") + writer.appendLine("# Only needed for JetBrains maintainers") + writer.appendLine("$TERMS_OF_USE_PROPERTY=") + } + + throw GradleException( + "'$TERMS_OF_USE_PROPERTY' property not found in file://local.properties . " + + "Please add this property and set it to 'yes' or 'no'." + ) + } + + else -> { + throw GradleException( + "Invalid value for '$TERMS_OF_USE_PROPERTY' property: $value. " + + "Please set this property to 'yes' or 'no'." + ) + } + } +} diff --git a/gradle-conventions-settings/develocity/src/main/kotlin/params.kt b/gradle-conventions-settings/develocity/src/main/kotlin/params.kt index cb3a017a6..e45b27367 100644 --- a/gradle-conventions-settings/develocity/src/main/kotlin/params.kt +++ b/gradle-conventions-settings/develocity/src/main/kotlin/params.kt @@ -6,4 +6,4 @@ const val DEVELOCITY_SERVER = "https://ge.jetbrains.com" const val GITHUB_REPO = "https://github.com/Kotlin/kotlinx-rpc" const val TEAMCITY_URL = "https://krpc.teamcity.com" -val isCIRun = System.getenv("TEAMCITY_VERSION") != null +val isCIRun = System.getenv("TEAMCITY_VERSION") != null || System.getenv("GITHUB_ACTIONS") != null diff --git a/gradle-conventions-settings/empty/build.gradle.kts b/gradle-conventions-settings/empty/build.gradle.kts deleted file mode 100644 index 531de275e..000000000 --- a/gradle-conventions-settings/empty/build.gradle.kts +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2023-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. - */ - -import java.io.File -import java.nio.file.Files -import java.nio.file.Path - -plugins { - alias(libs.plugins.gradle.kotlin.dsl) -} - -fun Path.name() = fileName?.toString().orEmpty() - -fun filterDirectory(sourceSetPath: Path, filter: (Path) -> Boolean): List { - return Files.newDirectoryStream(sourceSetPath).use { it.toList() }.filter(filter).map { it.toFile() } -} - -val pluginsSource: Path = layout.projectDirectory.dir("../develocity/src/main/kotlin").asFile.toPath() - -val plugins = filterDirectory(pluginsSource) { - Files.isRegularFile(it) && it.name().endsWith(".settings.gradle.kts") -}.map { it.name.substringBefore('.') } - -plugins.forEach { name -> - gradlePlugin { - plugins { - create(name) { - id = name - implementationClass = "EmptySettingsPlugin" - } - } - - logger.info("Applied $name precompiled plugin as stub") - } -} diff --git a/gradle-conventions-settings/empty/src/main/kotlin/empty-settings.settings.gradle.kts b/gradle-conventions-settings/empty/src/main/kotlin/empty-settings.settings.gradle.kts deleted file mode 100644 index 01aede8e6..000000000 --- a/gradle-conventions-settings/empty/src/main/kotlin/empty-settings.settings.gradle.kts +++ /dev/null @@ -1,5 +0,0 @@ -/* - * Copyright 2023-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. - */ - -// Do not delete this. It is used as a stub plugin for latest-only plugins diff --git a/gradle-conventions-settings/src/main/kotlin/conventions-repositories.settings.gradle.kts b/gradle-conventions-settings/src/main/kotlin/conventions-repositories.settings.gradle.kts index 37630bdae..f7c468fb4 100644 --- a/gradle-conventions-settings/src/main/kotlin/conventions-repositories.settings.gradle.kts +++ b/gradle-conventions-settings/src/main/kotlin/conventions-repositories.settings.gradle.kts @@ -38,6 +38,7 @@ pluginManagement { .removeSuffix("/gradle-conventions-settings") .removeSuffix("/compiler-plugin") .removeSuffix("/gradle-plugin") + .removeSuffix("/dokka-plugin") ) val localFile = File(propertiesDir, "local.properties") if (localFile.exists()) { @@ -100,94 +101,99 @@ pluginManagement { } } -gradle.rootProject { - fun findGlobalRootDirPath(): java.nio.file.Path { - var path = file(".").toPath().toAbsolutePath() +fun findGlobalRootDirPath(): java.nio.file.Path { + var path = file(".").toPath().toAbsolutePath() - // we assume that the 'versions-root' folder can only be present in the root folder - while ( - java.nio.file.Files.newDirectoryStream(path).use { it.toList() }.none { - java.nio.file.Files.isDirectory(it) && it.fileName.toString() == "versions-root" - } - ) { - path = path.parent ?: error("Unable to find root path for kotlinx.rpc project") + // we assume that the 'versions-root' folder can only be present in the root folder + while ( + java.nio.file.Files.newDirectoryStream(path).use { it.toList() }.none { + java.nio.file.Files.isDirectory(it) && it.fileName.toString() == "versions-root" } - - return path + ) { + path = path.parent ?: error("Unable to find root path for kotlinx.rpc project") } - fun logAbsentProperty(name: String): Nothing? { - logger.info("Property '$name' is not present for repository credentials.") + return path +} - return null - } +fun logAbsentProperty(name: String): Nothing? { + logger.info("Property '$name' is not present for repository credentials.") - fun getEnv(propertyName: String): String? = System.getenv( - propertyName.replace(".", "_").uppercase() - )?.ifEmpty { null } + return null +} - fun getLocalProperties(): java.util.Properties { - return java.util.Properties().apply { - val propertiesDir = File( - rootDir.path - .removeSuffix("/gradle-conventions") - .removeSuffix("/gradle-conventions-settings") - .removeSuffix("/compiler-plugin") - .removeSuffix("/gradle-plugin") - ) - val localFile = File(propertiesDir, "local.properties") - if (localFile.exists()) { - localFile.inputStream().use { load(it) } - } +fun getEnv(propertyName: String): String? = System.getenv( + propertyName.replace(".", "_").uppercase() +)?.ifEmpty { null } + +fun getLocalProperties(): java.util.Properties { + return java.util.Properties().apply { + val propertiesDir = File( + rootDir.path + .removeSuffix("/gradle-conventions") + .removeSuffix("/gradle-conventions-settings") + .removeSuffix("/compiler-plugin") + .removeSuffix("/gradle-plugin") + .removeSuffix("/dokka-plugin") + ) + val localFile = File(propertiesDir, "local.properties") + if (localFile.exists()) { + localFile.inputStream().use { load(it) } } } +} - fun java.util.Properties.isUsingProxyRepositories(): Boolean { - val useProxyProperty = this["kotlinx.rpc.useProxyRepositories"] as String? - return useProxyProperty == null || useProxyProperty == "true" - } +fun java.util.Properties.isUsingProxyRepositories(): Boolean { + val useProxyProperty = this["kotlinx.rpc.useProxyRepositories"] as String? + return useProxyProperty == null || useProxyProperty == "true" +} - fun getSpacePassword(): String? { - val password = "kotlinx.rpc.team.space.password" - return getLocalProperties()[password] as String? - ?: settings.providers.gradleProperty(password).orNull - ?: getEnv(password) - ?: logAbsentProperty(password) - } +fun getSpacePassword(): String? { + val password = "kotlinx.rpc.team.space.password" + return getLocalProperties()[password] as String? + ?: settings.providers.gradleProperty(password).orNull + ?: getEnv(password) + ?: logAbsentProperty(password) +} - /** - * Creates a publishing repository targeting Space Packages on jetbrains.team. - * - * @param repoName the name of the Space Packages repository - */ - fun RepositoryHandler.jbTeamPackages(repoName: String) { - maven { - name = repoName.split("-").joinToString("") { it.replaceFirstChar { c -> c.titlecase() } } - url = uri("https://packages.jetbrains.team/maven/p/krpc/$repoName") +/** + * Creates a publishing repository targeting Space Packages on jetbrains.team. + * + * @param repoName the name of the Space Packages repository + */ +fun RepositoryHandler.jbTeamPackages(repoName: String) { + maven { + name = repoName.split("-").joinToString("") { it.replaceFirstChar { c -> c.titlecase() } } + url = uri("https://packages.jetbrains.team/maven/p/krpc/$repoName") - val spacePassword = getSpacePassword() + val spacePassword = getSpacePassword() - if (spacePassword != null) { - credentials(HttpHeaderCredentials::class.java) { - name = "Authorization" - value = "Bearer $spacePassword" - } + if (spacePassword != null) { + credentials(HttpHeaderCredentials::class.java) { + name = "Authorization" + value = "Bearer $spacePassword" + } - authentication { - create("http_auth_header") - } - } else { - logger.info("Skipping adding credentials for Space repository '$repoName'") + authentication { + create("http_auth_header") } + } else { + logger.info("Skipping adding credentials for Space repository '$repoName'") } } +} - fun RepositoryHandler.buildDeps() = jbTeamPackages(repoName = "build-deps") - fun RepositoryHandler.buildDepsEap() = jbTeamPackages(repoName = "build-deps-eap") +fun RepositoryHandler.buildDeps() = jbTeamPackages(repoName = "build-deps") +fun RepositoryHandler.buildDepsEap() = jbTeamPackages(repoName = "build-deps-eap") - allprojects { - val localProps = getLocalProperties() +val localProps = getLocalProperties() + +settings.extra["spacePassword"] = getSpacePassword() +settings.extra["localProperties"] = localProps +settings.extra["useProxyRepositories"] = localProps.isUsingProxyRepositories() +gradle.rootProject { + allprojects { this.extra["spacePassword"] = getSpacePassword() this.extra["localProperties"] = localProps this.extra["useProxyRepositories"] = localProps.isUsingProxyRepositories() diff --git a/gradle-conventions-settings/src/main/kotlin/conventions-version-resolution.settings.gradle.kts b/gradle-conventions-settings/src/main/kotlin/conventions-version-resolution.settings.gradle.kts index 0f07e7fd6..596b91d9a 100644 --- a/gradle-conventions-settings/src/main/kotlin/conventions-version-resolution.settings.gradle.kts +++ b/gradle-conventions-settings/src/main/kotlin/conventions-version-resolution.settings.gradle.kts @@ -37,7 +37,6 @@ object SettingsConventions { const val VERSIONS_ROOT_PATH = "versions-root" const val LIBS_VERSION_CATALOG_PATH = "$VERSIONS_ROOT_PATH/libs.versions.toml" - const val KOTLIN_VERSIONS_LOOKUP_PATH = "$VERSIONS_ROOT_PATH/kotlin-versions-lookup.csv" } // ### VERSION RESOLVING SECTION ### @@ -65,47 +64,9 @@ fun findGlobalRootDirPath(start: Path): Path { } } - return path -} - -// Resolves 'versions-root/kotlin-versions-lookup.csv' -fun loadLookupTable(rootDir: Path, kotlinVersion: String): Pair, String> { - val file = rootDir.resolve(SettingsConventions.KOTLIN_VERSIONS_LOOKUP_PATH).toFile() - - var latest = kotlinVersion - val table = file.readText() - .split("\n") - .takeIf { it.size >= 2 } - ?.run { - first().asCsvValues() to when (val versionsRow = singleOrNull { it.startsWith(kotlinVersion) }) { - // resolve latest for an unknown version - // considers that unknown versions are too new and not yet added - null -> { - latest = kotlinVersion - get(1).asCsvValues() - } - - else -> { - latest = get(1).substringBefore(',') - versionsRow.asCsvValues() - } - } - } - ?.takeIf { (keys, values) -> keys.size == values.size } - ?.let { (keys, values) -> - keys.zip(values) - }?.associate { it } - ?: error( - "Malformed Kotlin version in lookup table, " + - "should be proper CSV file with horizontal header of version names " + - "and vertical headers of Kotlin versions." - ) - - return table to latest -} + settings.extra["globalRootDir"] = path.toAbsolutePath().toString() -fun String.asCsvValues(): List { - return split(",").map { it.trim() }.drop(1) + return path } // Resolves [versions] section from 'versions-root/libs.versions.toml' into map @@ -156,7 +117,7 @@ fun VersionCatalogBuilder.resolveKotlinVersion(versionCatalog: Map - logger.info("$name -> $version") - version(name, version) - } } } } diff --git a/gradle-conventions-settings/src/main/kotlin/util/KotlinVersionActions.kt b/gradle-conventions-settings/src/main/kotlin/util/KotlinVersionActions.kt deleted file mode 100644 index 566e9c3bf..000000000 --- a/gradle-conventions-settings/src/main/kotlin/util/KotlinVersionActions.kt +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright 2023-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. - */ - -package util - -import org.gradle.api.plugins.ExtensionAware -import org.gradle.kotlin.dsl.extra -import org.gradle.kotlin.dsl.provideDelegate - - -enum class ActionApplied { - Applied, NotApplied; -} - -@Suppress("unused") -inline fun ExtensionAware.whenKotlinCompilerIsAtLeast( - major: Int, - minor: Int, - patch: Int = 0, - action: () -> Unit = {}, -): ActionApplied { - val kotlinCompilerVersion: KotlinVersion by extra - - if (kotlinCompilerVersion.isAtLeast(major, minor, patch)) { - action() - - return ActionApplied.Applied - } - - return ActionApplied.NotApplied -} - -@Suppress("unused") -inline fun ExtensionAware.whenKotlinLatest(action: () -> Unit): ActionApplied { - val isLatestKotlinVersion: Boolean by extra - - if (isLatestKotlinVersion) { - action() - return ActionApplied.Applied - } - - return ActionApplied.NotApplied -} - -infix fun ActionApplied.otherwise(body: () -> Unit) { - if (this == ActionApplied.NotApplied) { - body() - } -} diff --git a/gradle-conventions/build.gradle.kts b/gradle-conventions/build.gradle.kts index 3687d55b4..049e30536 100644 --- a/gradle-conventions/build.gradle.kts +++ b/gradle-conventions/build.gradle.kts @@ -2,20 +2,19 @@ * Copyright 2023-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. */ -import util.otherwise -import util.whenKotlinLatest - plugins { - alias(libs.plugins.gradle.kotlin.dsl) + `kotlin-dsl` } dependencies { - implementation(project(":common")) - implementation(":gradle-conventions-settings") + implementation(libs.kotlin.gradle.plugin) + implementation(libs.detekt.gradle.plugin) + implementation(libs.dokka.gradle.plugin) + implementation(libs.gradle.doctor.gradle.plugin) + implementation(libs.gradle.publish.gradle.plugin) + + implementation(libs.kover.gradle.plugin) - project.whenKotlinLatest { - implementation(project(":latest-only")) - } otherwise { - implementation(project(":empty")) - } + // https://stackoverflow.com/questions/76713758/use-version-catalog-inside-precompiled-gradle-plugin + implementation(files(libs.javaClass.superclass.protectionDomain.codeSource.location)) } diff --git a/gradle-conventions/common/build.gradle.kts b/gradle-conventions/common/build.gradle.kts deleted file mode 100644 index b47ecfdd0..000000000 --- a/gradle-conventions/common/build.gradle.kts +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright 2023-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. - */ - -plugins { - alias(libs.plugins.gradle.kotlin.dsl) -} - -val isLatestKotlinVersion: Boolean by extra - -dependencies { - implementation(":gradle-conventions-settings") - - api(libs.kotlin.gradle.plugin) - api(libs.detekt.gradle.plugin) - api(libs.dokka.gradle.plugin) - - if (isLatestKotlinVersion) { - api(libs.kover.gradle.plugin) - } - - // https://stackoverflow.com/questions/76713758/use-version-catalog-inside-precompiled-gradle-plugin - api(files(libs.javaClass.superclass.protectionDomain.codeSource.location)) -} diff --git a/gradle-conventions/common/src/main/kotlin/build-util.gradle.kts b/gradle-conventions/common/src/main/kotlin/build-util.gradle.kts deleted file mode 100644 index a646b2141..000000000 --- a/gradle-conventions/common/src/main/kotlin/build-util.gradle.kts +++ /dev/null @@ -1,5 +0,0 @@ -/* - * Copyright 2023-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. - */ - -// empty diff --git a/gradle-conventions/common/src/main/kotlin/util/OptInForInternalApi.kt b/gradle-conventions/common/src/main/kotlin/util/OptInForInternalApi.kt deleted file mode 100644 index 190e9749b..000000000 --- a/gradle-conventions/common/src/main/kotlin/util/OptInForInternalApi.kt +++ /dev/null @@ -1,14 +0,0 @@ -/* - * Copyright 2023-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. - */ - -package util - -import org.jetbrains.kotlin.gradle.dsl.KotlinProjectExtension - -fun KotlinProjectExtension.optInForRpcApi() { - sourceSets.all { - languageSettings.optIn("kotlinx.rpc.internal.utils.InternalRpcApi") - languageSettings.optIn("kotlinx.rpc.internal.utils.ExperimentalRpcApi") - } -} diff --git a/gradle-conventions/common/src/main/kotlin/util/StringCase.kt b/gradle-conventions/common/src/main/kotlin/util/StringCase.kt deleted file mode 100644 index c9bb2cb1d..000000000 --- a/gradle-conventions/common/src/main/kotlin/util/StringCase.kt +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright 2023-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. - */ - -package util - -import java.util.* - -fun String.capitalized(): String { - if (isEmpty()) { - return "" - } - val firstChar = get(0) - return replaceFirst(firstChar, Character.toTitleCase(firstChar)) -} - -@Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN", "NOTHING_TO_INLINE") -inline fun String.lowercase(): String = (this as java.lang.String).toLowerCase(Locale.ROOT) diff --git a/gradle-conventions/common/src/main/kotlin/util/apiValidation.kt b/gradle-conventions/common/src/main/kotlin/util/apiValidation.kt deleted file mode 100644 index 3be8568a9..000000000 --- a/gradle-conventions/common/src/main/kotlin/util/apiValidation.kt +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2023-2025 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. - */ - -package util - -import org.gradle.api.Project -import org.gradle.kotlin.dsl.configure -import org.jetbrains.kotlin.gradle.dsl.abi.AbiValidationExtension -import org.jetbrains.kotlin.gradle.dsl.abi.AbiValidationMultiplatformExtension -import org.jetbrains.kotlin.gradle.dsl.abi.AbiValidationVariantSpec -import org.jetbrains.kotlin.gradle.dsl.abi.ExperimentalAbiValidation - -@OptIn(ExperimentalAbiValidation::class) -fun Project.configureApiValidation() { - when (project.name) { - "krpc-test", - "krpc-compatibility-tests", - "compiler-plugin-tests", - -> return - } - - withKotlinJvmExtension { - extensions.configure { - enabled.set(true) - - configureFilters() - } - } - - withKotlinKmpExtension { - extensions.configure { - enabled.set(true) - - klib { - enabled.set(true) - } - - configureFilters() - } - } -} - -@OptIn(ExperimentalAbiValidation::class) -private fun AbiValidationVariantSpec.configureFilters() { - filters { - excluded { - annotatedWith.add("kotlinx.rpc.internal.utils.InternalRpcApi") - byNames.add("kotlinx.rpc.internal.**") - byNames.add("kotlinx.rpc.krpc.internal.**") - } - } -} diff --git a/gradle-conventions/common/src/main/kotlin/util/atomicfu.kt b/gradle-conventions/common/src/main/kotlin/util/atomicfu.kt deleted file mode 100644 index 018ec5035..000000000 --- a/gradle-conventions/common/src/main/kotlin/util/atomicfu.kt +++ /dev/null @@ -1,11 +0,0 @@ -/* - * Copyright 2023-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. - */ - -package util - -import org.gradle.api.Project - -fun Project.applyAtomicfuPlugin() { - plugins.apply(libs.plugins.atomicfu.get().pluginId) -} diff --git a/gradle-conventions/common/src/main/kotlin/util/dokka.kt b/gradle-conventions/common/src/main/kotlin/util/dokka.kt deleted file mode 100644 index af2a73c69..000000000 --- a/gradle-conventions/common/src/main/kotlin/util/dokka.kt +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright 2023-2025 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. - */ - -package util - -import org.gradle.api.Project -import org.gradle.api.plugins.ExtensionAware -import org.gradle.kotlin.dsl.configure -import org.jetbrains.dokka.gradle.DokkaExtension -import org.jetbrains.dokka.gradle.engine.parameters.VisibilityModifier -import org.jetbrains.dokka.gradle.engine.plugins.DokkaHtmlPluginParameters -import java.time.Year - -fun String.asDokkaVersion() = removeSuffix("-SNAPSHOT") - -fun Project.applyDokka() { - if (!isPublicModule) { - return - } - - plugins.apply(libs.plugins.dokka.get().pluginId) - - configure { - pluginsConfiguration.apply { - (this as ExtensionAware).extensions.configure { - footerMessage.set("© ${Year.now()} JetBrains s.r.o and contributors. Apache License 2.0") - } - } - - moduleName.set("$KOTLINX_RPC_PREFIX-${project.name}") - - dokkaSourceSets.configureEach { - sourceLink { - localDirectory.set(rootDir) - remoteUrl("https://github.com/Kotlin/kotlinx-rpc/blob/${libs.versions.kotlinx.rpc.get().asDokkaVersion()}") - remoteLineSuffix.set("#L") - - documentedVisibilities.set( - setOf( - VisibilityModifier.Public, - VisibilityModifier.Protected, - ) - ) - } - } - - dokkaPublications.configureEach { - suppressObviousFunctions.set(true) - failOnWarning.set(true) - } - } - - dependencies.add("dokkaPlugin", libs.dokka.rpc.plugin) - - val thisProject = project - - rootProject.configurations.matching { it.name == "dokka" }.all { - rootProject.dependencies.add("dokka", thisProject) - } -} diff --git a/gradle-conventions/common/src/main/kotlin/util/projectReport.kt b/gradle-conventions/common/src/main/kotlin/util/projectReport.kt deleted file mode 100644 index 16621b4bf..000000000 --- a/gradle-conventions/common/src/main/kotlin/util/projectReport.kt +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright 2023-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. - */ - -package util - -import org.gradle.api.Project - -// useful for dependencies introspection -// run ./gradlew htmlDependencyReport -// Report can normally be found in build/reports/project/dependencies/index.html -fun Project.configureProjectReport() { - allprojects { - plugins.apply("project-report") - } -} diff --git a/gradle-conventions/common/src/main/kotlin/util/properties.kt b/gradle-conventions/common/src/main/kotlin/util/properties.kt deleted file mode 100644 index 5dcb95e40..000000000 --- a/gradle-conventions/common/src/main/kotlin/util/properties.kt +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright 2023-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. - */ - -@file:Suppress("DuplicatedCode") - -package util - -import org.gradle.api.Project -import org.gradle.kotlin.dsl.extra - -val Project.spacePassword get(): String? { - return (this.extra["spacePassword"] as String?) -} - -val Project.localProperties get(): java.util.Properties { - return (this.extra["localProperties"] as java.util.Properties) -} - -val Project.useProxyRepositories get(): Boolean { - return (this.extra["useProxyRepositories"] as Boolean) -} diff --git a/gradle-conventions/empty/build.gradle.kts b/gradle-conventions/empty/build.gradle.kts deleted file mode 100644 index c46c43bbf..000000000 --- a/gradle-conventions/empty/build.gradle.kts +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2023-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. - */ - -import java.io.File -import java.nio.file.Files -import java.nio.file.Path - -plugins { - alias(libs.plugins.gradle.kotlin.dsl) -} - -fun Path.name() = fileName?.toString().orEmpty() - -fun filterDirectory(sourceSetPath: Path, filter: (Path) -> Boolean): List { - return Files.newDirectoryStream(sourceSetPath).use { it.toList() }.filter(filter).map { it.toFile() } -} - -val pluginsSource: Path = layout.projectDirectory.dir("../latest-only/src/main/kotlin").asFile.toPath() - -val plugins = filterDirectory(pluginsSource) { - Files.isRegularFile(it) && it.name().endsWith(".gradle.kts") -}.map { it.name.substringBefore('.') } - -plugins.forEach { name -> - gradlePlugin { - plugins { - create(name) { - id = name - implementationClass = "EmptyPlugin" - } - } - - logger.info("Applied $name precompiled plugin as stub") - } -} diff --git a/gradle-conventions/empty/src/main/kotlin/empty.gradle.kts b/gradle-conventions/empty/src/main/kotlin/empty.gradle.kts deleted file mode 100644 index 01aede8e6..000000000 --- a/gradle-conventions/empty/src/main/kotlin/empty.gradle.kts +++ /dev/null @@ -1,5 +0,0 @@ -/* - * Copyright 2023-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. - */ - -// Do not delete this. It is used as a stub plugin for latest-only plugins diff --git a/gradle-conventions/gradle.properties b/gradle-conventions/gradle.properties deleted file mode 100644 index 0de4acfb8..000000000 --- a/gradle-conventions/gradle.properties +++ /dev/null @@ -1,6 +0,0 @@ -# -# Copyright 2023-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. -# - -kotlin.mpp.stability.nowarn=true -kotlinx.rpc.preserveDefaultSourceDirectories=true diff --git a/gradle-conventions/latest-only/build.gradle.kts b/gradle-conventions/latest-only/build.gradle.kts deleted file mode 100644 index 70c9995bc..000000000 --- a/gradle-conventions/latest-only/build.gradle.kts +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright 2023-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. - */ - -plugins { - alias(libs.plugins.gradle.kotlin.dsl) -} - -dependencies { - implementation(project(":common")) - - implementation(":gradle-conventions-settings") - implementation(libs.kotlin.gradle.plugin) - implementation(libs.kover.gradle.plugin) - implementation(libs.gradle.doctor.plugin) -} diff --git a/gradle-conventions/latest-only/src/main/kotlin/conventions-gradle-doctor.gradle.kts b/gradle-conventions/latest-only/src/main/kotlin/conventions-gradle-doctor.gradle.kts deleted file mode 100644 index 81a649c64..000000000 --- a/gradle-conventions/latest-only/src/main/kotlin/conventions-gradle-doctor.gradle.kts +++ /dev/null @@ -1,14 +0,0 @@ -/* - * Copyright 2023-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. - */ - -plugins { - id("com.osacky.doctor") -} - -doctor { - enableTestCaching = false - warnWhenNotUsingParallelGC = true - disallowMultipleDaemons = false - GCFailThreshold = 0.5f -} diff --git a/gradle-conventions/settings.gradle.kts b/gradle-conventions/settings.gradle.kts index f6633b542..27bf81b29 100644 --- a/gradle-conventions/settings.gradle.kts +++ b/gradle-conventions/settings.gradle.kts @@ -2,28 +2,27 @@ * Copyright 2023-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. */ -import util.otherwise -import util.whenKotlinLatest - rootProject.name = "gradle-conventions" enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS") pluginManagement { + repositories { + gradlePluginPortal() + } + includeBuild("../gradle-conventions-settings") } -includeBuild("../gradle-conventions-settings") - plugins { id("conventions-repositories") id("conventions-version-resolution") } -include(":common") - -whenKotlinLatest { - include(":latest-only") -} otherwise { - include(":empty") +dependencyResolutionManagement { + // Additional repositories for build-logic + @Suppress("UnstableApiUsage") + repositories { + gradlePluginPortal() + } } diff --git a/gradle-conventions/src/main/kotlin/compiler-specific-module.gradle.kts b/gradle-conventions/src/main/kotlin/compiler-specific-module.gradle.kts index 8a093a885..a7cad6933 100644 --- a/gradle-conventions/src/main/kotlin/compiler-specific-module.gradle.kts +++ b/gradle-conventions/src/main/kotlin/compiler-specific-module.gradle.kts @@ -4,12 +4,12 @@ import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet import util.* +import util.other.DirectoryNames import java.nio.file.Files import java.nio.file.Path import kotlin.text.lowercase val kotlinCompilerVersion: KotlinVersion by extra -val preserveDefaultSourceDirectories by optionalProperty() fun NamedDomainObjectContainer.applyCompilerSpecificSourceSets() { forEach { set -> @@ -25,7 +25,7 @@ fun NamedDomainObjectContainer.applyCompilerSpecificSourceSets( return@forEach } - val core = sourceSetPath.resolve(Dir.CORE_SOURCE_DIR).toFile() + val core = sourceSetPath.resolve(DirectoryNames.CORE_SOURCE_DIR).toFile() // version-specific source sets val vsSets = filterSourceDirsForCSM(sourceSetPath) @@ -40,11 +40,7 @@ fun NamedDomainObjectContainer.applyCompilerSpecificSourceSets( val newSourceDirectories = listOfNotNull(core, mostSpecificApplicable) - if (preserveDefaultSourceDirectories) { - set.kotlin.srcDirs(newSourceDirectories) - } else { - set.kotlin.setSrcDirs(newSourceDirectories) // 'core' source set instead of 'kotlin' - } + set.kotlin.setSrcDirs(newSourceDirectories) // 'core' source set instead of 'kotlin' set.configureResources(sourceSetPath) @@ -62,7 +58,7 @@ fun KotlinSourceSet.configureResources(sourceSetPath: Path) { } // only works for jvm projects - val resourcesName = if (name.lowercase().contains(Dir.MAIN_SOURCE_SET)) Dir.MAIN_RESOURCES else Dir.TEST_RESOURCES + val resourcesName = if (name.lowercase().contains(DirectoryNames.MAIN_SOURCE_SET)) DirectoryNames.MAIN_RESOURCES else DirectoryNames.TEST_RESOURCES val resourcesDir = parent.resolve(resourcesName) if (!Files.exists(resourcesDir)) { @@ -72,7 +68,7 @@ fun KotlinSourceSet.configureResources(sourceSetPath: Path) { val mostSpecificApplicable = filterSourceDirsForCSM(resourcesDir) .mostSpecificVersionOrLatest(kotlinCompilerVersion) - val versionNames = listOfNotNull(Dir.CORE_SOURCE_DIR, mostSpecificApplicable?.name) + val versionNames = listOfNotNull(DirectoryNames.CORE_SOURCE_DIR, mostSpecificApplicable?.name) resources.srcDirs(versionNames.map { resourcesDir.resolve(it).toFile() }) } diff --git a/gradle-conventions/src/main/kotlin/conventions-common.gradle.kts b/gradle-conventions/src/main/kotlin/conventions-common.gradle.kts index 1c0c3c62b..ebf7294c3 100644 --- a/gradle-conventions/src/main/kotlin/conventions-common.gradle.kts +++ b/gradle-conventions/src/main/kotlin/conventions-common.gradle.kts @@ -3,22 +3,19 @@ */ import io.gitlab.arturbosch.detekt.Detekt -import util.configureApiValidation -import util.libs -import util.whenKotlinLatest +import util.other.libs plugins { id("io.gitlab.arturbosch.detekt") id("conventions-publishing") id("conventions-kotlin-version") + id("conventions-dokka-public") } val globalRootDir: String by extra val globalDetektDir = "$globalRootDir/detekt" -configureApiValidation() - // https://detekt.dev/docs/gettingstarted/gradle#options-for-detekt-configuration-closure detekt { toolVersion = libs.versions.detekt.analyzer.get() @@ -55,12 +52,10 @@ afterEvaluate { } } -whenKotlinLatest { - apply(plugin = "org.jetbrains.kotlinx.kover") +apply(plugin = "org.jetbrains.kotlinx.kover") - val thisProject = project +val thisProject = project - rootProject.configurations.matching { it.name == "kover" }.all { - rootProject.dependencies.add("kover", thisProject) - } +rootProject.configurations.matching { it.name == "kover" }.all { + rootProject.dependencies.add("kover", thisProject) } diff --git a/gradle-conventions/src/main/kotlin/conventions-dokka-public.gradle.kts b/gradle-conventions/src/main/kotlin/conventions-dokka-public.gradle.kts new file mode 100644 index 000000000..c9e5b2167 --- /dev/null +++ b/gradle-conventions/src/main/kotlin/conventions-dokka-public.gradle.kts @@ -0,0 +1,10 @@ +import util.other.isPublicModule +import util.other.libs + +/* + * Copyright 2023-2025 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. + */ + +if (isPublicModule) { + plugins.apply(libs.plugins.conventions.dokka.spec.get().pluginId) +} diff --git a/gradle-conventions/src/main/kotlin/conventions-dokka-spec.gradle.kts b/gradle-conventions/src/main/kotlin/conventions-dokka-spec.gradle.kts new file mode 100644 index 000000000..2618dfc0b --- /dev/null +++ b/gradle-conventions/src/main/kotlin/conventions-dokka-spec.gradle.kts @@ -0,0 +1,51 @@ +/* + * Copyright 2023-2025 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. + */ + +import org.jetbrains.dokka.gradle.engine.parameters.VisibilityModifier +import util.KOTLINX_RPC_PREFIX +import util.other.asDokkaVersion +import util.other.libs +import java.time.Year + +plugins { + id("org.jetbrains.dokka") +} + +dokka { + pluginsConfiguration { + html { + footerMessage = "© ${Year.now()} JetBrains s.r.o and contributors. Apache License 2.0" + } + } + + moduleName = "$KOTLINX_RPC_PREFIX-${project.name}" + + dokkaSourceSets.configureEach { + sourceLink { + localDirectory = rootDir + remoteUrl("https://github.com/Kotlin/kotlinx-rpc/blob/${libs.versions.kotlinx.rpc.get().asDokkaVersion()}") + remoteLineSuffix = "#L" + + documentedVisibilities = setOf( + VisibilityModifier.Public, + VisibilityModifier.Protected, + ) + } + } + + dokkaPublications.configureEach { + suppressObviousFunctions = true + failOnWarning = true + } +} + +dependencies { + dokkaPlugin(libs.dokka.rpc.plugin) +} + +val thisProject = project + +rootProject.configurations.matching { it.name == "dokka" }.all { + rootProject.dependencies.dokka(thisProject) +} diff --git a/gradle-conventions/src/main/kotlin/conventions-gradle-doctor.gradle.kts b/gradle-conventions/src/main/kotlin/conventions-gradle-doctor.gradle.kts new file mode 100644 index 000000000..6a0ed71c2 --- /dev/null +++ b/gradle-conventions/src/main/kotlin/conventions-gradle-doctor.gradle.kts @@ -0,0 +1,14 @@ +/* + * Copyright 2023-2025 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. + */ + +plugins { + id("com.osacky.doctor") +} + +doctor { + enableTestCaching.assign(false) + warnWhenNotUsingParallelGC.assign(true) + disallowMultipleDaemons.assign(false) + GCFailThreshold.assign(0.5f) +} diff --git a/gradle-conventions/latest-only/src/main/kotlin/conventions-gradle-publish.gradle.kts b/gradle-conventions/src/main/kotlin/conventions-gradle-publish.gradle.kts similarity index 89% rename from gradle-conventions/latest-only/src/main/kotlin/conventions-gradle-publish.gradle.kts rename to gradle-conventions/src/main/kotlin/conventions-gradle-publish.gradle.kts index 750000f8a..7bb04c3a3 100644 --- a/gradle-conventions/latest-only/src/main/kotlin/conventions-gradle-publish.gradle.kts +++ b/gradle-conventions/src/main/kotlin/conventions-gradle-publish.gradle.kts @@ -2,10 +2,11 @@ * Copyright 2023-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. */ -apply(plugin = "com.gradle.plugin-publish") +plugins { + id("com.gradle.plugin-publish") +} -@Suppress("UnstableApiUsage") -the().apply { +gradlePlugin { website.set("https://kotlinlang.org") vcsUrl.set("https://github.com/Kotlin/kotlinx-rpc") @@ -50,7 +51,7 @@ fun getSensitiveProperty(name: String?): String? { error("Expected not null property 'name' for publication repository config") } - return project.findProperty(name) as? String + return findProperty(name) as? String ?: System.getenv(name) ?: System.getProperty(name) } diff --git a/gradle-conventions/src/main/kotlin/conventions-jvm.gradle.kts b/gradle-conventions/src/main/kotlin/conventions-jvm.gradle.kts index 72c3e1130..77b1bea6c 100644 --- a/gradle-conventions/src/main/kotlin/conventions-jvm.gradle.kts +++ b/gradle-conventions/src/main/kotlin/conventions-jvm.gradle.kts @@ -2,10 +2,12 @@ * Copyright 2023-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. */ -import org.jetbrains.kotlin.gradle.dsl.KotlinJvmProjectExtension -import util.configureJvm -import util.optInForRpcApi -import util.applyDokka +@file:OptIn(ExperimentalAbiValidation::class) + +import org.jetbrains.kotlin.gradle.dsl.abi.ExperimentalAbiValidation +import util.configureAbiFilters +import util.enableAbiValidation +import util.targets.configureJvm plugins { id("conventions-common") @@ -16,16 +18,18 @@ java { withSourcesJar() } -configure { +kotlin { jvmToolchain { languageVersion.set(JavaLanguageVersion.of(8)) } - optInForRpcApi() - explicitApi() + + abiValidation { + enabled = enableAbiValidation + + configureAbiFilters() + } } configureJvm(isKmp = false) - -applyDokka() diff --git a/gradle-conventions/src/main/kotlin/conventions-kmp.gradle.kts b/gradle-conventions/src/main/kotlin/conventions-kmp.gradle.kts index d946a54fb..bf8d777ff 100644 --- a/gradle-conventions/src/main/kotlin/conventions-kmp.gradle.kts +++ b/gradle-conventions/src/main/kotlin/conventions-kmp.gradle.kts @@ -2,27 +2,39 @@ * Copyright 2023-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. */ -import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension +@file:OptIn(ExperimentalAbiValidation::class) + +import org.jetbrains.kotlin.gradle.dsl.abi.ExperimentalAbiValidation import util.* -import util.applyDokka +import util.targets.configureJs +import util.targets.configureJvm +import util.targets.configureKotlinExtension +import util.targets.configureWasm +import util.targets.withKmpConfig plugins { id("conventions-common") id("org.jetbrains.kotlin.multiplatform") } -configure { - optInForRpcApi() - +kotlin { explicitApi() + + abiValidation { + enabled = enableAbiValidation + + klib { + enabled = enableAbiValidation + } + + configureAbiFilters() + } } -withKotlinConfig { - configureKotlin() +withKmpConfig { + configureKotlinExtension() configureJs() configureWasm() } configureJvm(isKmp = true) - -applyDokka() diff --git a/gradle-conventions/latest-only/src/main/kotlin/conventions-kotlin-version.gradle.kts b/gradle-conventions/src/main/kotlin/conventions-kotlin-version.gradle.kts similarity index 78% rename from gradle-conventions/latest-only/src/main/kotlin/conventions-kotlin-version.gradle.kts rename to gradle-conventions/src/main/kotlin/conventions-kotlin-version.gradle.kts index 6c37f5a92..156f1a790 100644 --- a/gradle-conventions/latest-only/src/main/kotlin/conventions-kotlin-version.gradle.kts +++ b/gradle-conventions/src/main/kotlin/conventions-kotlin-version.gradle.kts @@ -1,14 +1,21 @@ /* - * Copyright 2023-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. + * Copyright 2023-2025 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. */ import org.jetbrains.kotlin.gradle.dsl.KotlinCommonCompilerOptions +import org.jetbrains.kotlin.gradle.dsl.KotlinProjectExtension import org.jetbrains.kotlin.gradle.dsl.KotlinVersion import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation -import util.lowercase import util.withKotlinJvmExtension import util.withKotlinKmpExtension +fun KotlinProjectExtension.optInForRpcApi() { + sourceSets.all { + languageSettings.optIn("kotlinx.rpc.internal.utils.InternalRpcApi") + languageSettings.optIn("kotlinx.rpc.internal.utils.ExperimentalRpcApi") + } +} + /** * Set the compatibility mode to the lower supported language version. * @@ -23,6 +30,8 @@ fun KotlinCommonCompilerOptions.setProjectLanguageVersion() { } withKotlinJvmExtension { + optInForRpcApi() + target.compilations .filter { it.isMain } .forEach { compilation -> @@ -33,6 +42,8 @@ withKotlinJvmExtension { } withKotlinKmpExtension { + optInForRpcApi() + targets.flatMap { it.compilations } .filter { it.isMain } .forEach { compilation -> diff --git a/gradle-conventions/latest-only/src/main/kotlin/conventions-kover.gradle.kts b/gradle-conventions/src/main/kotlin/conventions-kover.gradle.kts similarity index 80% rename from gradle-conventions/latest-only/src/main/kotlin/conventions-kover.gradle.kts rename to gradle-conventions/src/main/kotlin/conventions-kover.gradle.kts index 8606ede0c..c50370192 100644 --- a/gradle-conventions/latest-only/src/main/kotlin/conventions-kover.gradle.kts +++ b/gradle-conventions/src/main/kotlin/conventions-kover.gradle.kts @@ -1,15 +1,16 @@ /* - * Copyright 2023-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. + * Copyright 2023-2025 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. */ import kotlinx.kover.gradle.plugin.dsl.AggregationType import kotlinx.kover.gradle.plugin.dsl.CoverageUnit import kotlinx.kover.gradle.plugin.dsl.GroupingEntityType -import kotlinx.kover.gradle.plugin.dsl.KoverProjectExtension -apply(plugin = "org.jetbrains.kotlinx.kover") +plugins { + id("org.jetbrains.kotlinx.kover") +} -the().apply { +kover { reports { total { html { diff --git a/gradle-conventions/src/main/kotlin/conventions-publishing.gradle.kts b/gradle-conventions/src/main/kotlin/conventions-publishing.gradle.kts index 863f9c8b0..5763c1885 100644 --- a/gradle-conventions/src/main/kotlin/conventions-publishing.gradle.kts +++ b/gradle-conventions/src/main/kotlin/conventions-publishing.gradle.kts @@ -4,6 +4,8 @@ import org.gradle.kotlin.dsl.registering import util.* +import util.other.getSensitiveProperty +import util.other.isPublicModule val isGradlePlugin = project.name == "gradle-plugin" val publishingExtension = project.extensions.findByType() diff --git a/gradle-conventions/src/main/kotlin/conventions-root.gradle.kts b/gradle-conventions/src/main/kotlin/conventions-root.gradle.kts new file mode 100644 index 000000000..5454ad530 --- /dev/null +++ b/gradle-conventions/src/main/kotlin/conventions-root.gradle.kts @@ -0,0 +1,119 @@ +/* + * Copyright 2023-2025 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. + */ + +import util.other.asDokkaVersion +import util.other.libs +import util.tasks.configureNpm +import util.tasks.registerChangelogTask +import util.tasks.registerDumpPlatformTableTask +import util.tasks.registerVerifyPlatformTableTask +import java.time.Year +import kotlin.io.path.exists +import kotlin.io.path.isDirectory +import kotlin.io.path.listDirectoryEntries +import kotlin.io.path.name +import kotlin.io.path.readText +import java.nio.file.Path +import kotlin.io.path.createFile + +plugins { + id("org.jetbrains.dokka") +} + +// useful for dependencies introspection +// run ./gradlew htmlDependencyReport +// Report can normally be found in build/reports/project/dependencies/index.html +allprojects { + plugins.apply("project-report") +} + +dokka { + val libDokkaVersion = libs.versions.kotlinx.rpc.get().asDokkaVersion() + + moduleVersion.set(libDokkaVersion) + + val pagesDirectory = layout.projectDirectory + .dir("docs") + .dir("pages") + + val dokkaVersionsDirectory = pagesDirectory + .dir("api") + .asFile + + val templatesDirectory = pagesDirectory + .dir("templates") + + pluginsConfiguration { + html { + customAssets.from( + "docs/pages/assets/logo-icon.svg", + "docs/pages/assets/homepage.svg", // Doesn't work due to https://github.com/Kotlin/dokka/issues/4007 + ) + + footerMessage = "© ${Year.now()} JetBrains s.r.o and contributors. Apache License 2.0" + homepageLink = "https://kotlin.github.io/kotlinx-rpc/get-started.html" + + // replace with homepage.svg once the mentioned issue is resolved + templatesDir.set(templatesDirectory) + } + } + + dokkaPublications.html { + outputDirectory = dokkaVersionsDirectory + } + + tasks.clean { + delete(dokkaVersionsDirectory) + } +} + +dependencies { + dokkaPlugin(libs.dokka.rpc.plugin) +} + +configureNpm() + +registerDumpPlatformTableTask() +registerVerifyPlatformTableTask() +registerChangelogTask() + +fun Project.forEachSubproject(action: (String, Path, Path) -> Unit) { + val globalRootDir: String by extra + val root = Path.of(globalRootDir) + val rootProperties = root.resolve("gradle.properties").readText() + root.listDirectoryEntries() + .filter { it.isDirectory() && it.name != "gradle-conventions-settings" && it.name != "gradle-conventions" } + .forEach { + val subProjectProperties = it.resolve("gradle.properties") + val subProjectSettings = it.resolve("settings.gradle.kts") + if (subProjectSettings.exists()) { + action(rootProperties, it, subProjectProperties) + } + } +} + +val updateProperties = tasks.register("updateProperties") { + forEachSubproject { rootProperties, _, subProjectProperties -> + if (!subProjectProperties.exists()) { + subProjectProperties.createFile() + } + + subProjectProperties.toFile().writeText(rootProperties) + } +} + +gradle.afterProject { + if (gradle.startParameter.taskNames.singleOrNull() == updateProperties.name) { + return@afterProject + } + + forEachSubproject { rootProperties, parent, subProjectProperties -> + if (!subProjectProperties.exists() || subProjectProperties.readText() != rootProperties) { + throw GradleException( + "'gradle.properties' file in ${parent.name} included project is not up-to-date with root. " + + "Please, run `./gradlew ${updateProperties.name}" + ) + } + } +} diff --git a/gradle-conventions/src/main/kotlin/util/apiValidation.kt b/gradle-conventions/src/main/kotlin/util/apiValidation.kt new file mode 100644 index 000000000..5bbf2f661 --- /dev/null +++ b/gradle-conventions/src/main/kotlin/util/apiValidation.kt @@ -0,0 +1,28 @@ +/* + * Copyright 2023-2025 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. + */ + +package util + +import org.gradle.api.Project +import org.jetbrains.kotlin.gradle.dsl.abi.AbiValidationVariantSpec +import org.jetbrains.kotlin.gradle.dsl.abi.ExperimentalAbiValidation + +private val excludedProjects = setOf( + "krpc-test", + "krpc-compatibility-tests", + "compiler-plugin-tests", +) + +val Project.enableAbiValidation get() = name !in excludedProjects + +@OptIn(ExperimentalAbiValidation::class) +fun AbiValidationVariantSpec.configureAbiFilters() { + filters { + excluded { + annotatedWith.add("kotlinx.rpc.internal.utils.InternalRpcApi") + byNames.add("kotlinx.rpc.internal.**") + byNames.add("kotlinx.rpc.krpc.internal.**") + } + } +} diff --git a/gradle-conventions/common/src/main/kotlin/util/forIde.kt b/gradle-conventions/src/main/kotlin/util/forIde.kt similarity index 85% rename from gradle-conventions/common/src/main/kotlin/util/forIde.kt rename to gradle-conventions/src/main/kotlin/util/forIde.kt index 4c746750d..368dc34b3 100644 --- a/gradle-conventions/common/src/main/kotlin/util/forIde.kt +++ b/gradle-conventions/src/main/kotlin/util/forIde.kt @@ -5,6 +5,8 @@ package util import org.gradle.api.Project +import util.other.ActionApplied +import util.other.optionalProperty fun Project.whenForIde(block: () -> Unit): ActionApplied { val forIdeBuild by rootProject.optionalProperty() diff --git a/gradle-conventions/common/src/main/kotlin/util/KotlinExtension.kt b/gradle-conventions/src/main/kotlin/util/kotlinDsl.kt similarity index 100% rename from gradle-conventions/common/src/main/kotlin/util/KotlinExtension.kt rename to gradle-conventions/src/main/kotlin/util/kotlinDsl.kt diff --git a/gradle-conventions/common/src/main/kotlin/util/KotlinVersion.kt b/gradle-conventions/src/main/kotlin/util/kotlinVersion.kt similarity index 76% rename from gradle-conventions/common/src/main/kotlin/util/KotlinVersion.kt rename to gradle-conventions/src/main/kotlin/util/kotlinVersion.kt index e63f92385..cb0100d00 100644 --- a/gradle-conventions/common/src/main/kotlin/util/KotlinVersion.kt +++ b/gradle-conventions/src/main/kotlin/util/kotlinVersion.kt @@ -1,10 +1,16 @@ /* - * Copyright 2023-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. + * Copyright 2023-2025 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. */ package util +import org.gradle.api.plugins.ExtensionAware +import org.gradle.kotlin.dsl.extra import org.gradle.kotlin.dsl.provideDelegate +import util.other.ActionApplied +import util.other.DirectoryNames +import util.other.filterDirectory +import util.other.name import java.io.File import java.nio.file.Files import java.nio.file.Path @@ -14,12 +20,37 @@ fun String.kotlinVersionParsed(): KotlinVersion { return KotlinVersion(major, minor, patch) } +@Suppress("unused") +inline fun ExtensionAware.whenKotlinCompilerIsAtLeast( + major: Int, + minor: Int, + patch: Int = 0, + action: () -> Unit = {}, +): ActionApplied { + val kotlinCompilerVersion: KotlinVersion by extra + + if (kotlinCompilerVersion.isAtLeast(major, minor, patch)) { + action() + + return ActionApplied.Applied + } + + return ActionApplied.NotApplied +} + fun filterSourceDirsForCSM(sourceSetPath: Path): List { return filterDirectory(sourceSetPath) { Files.isDirectory(it) && it.name().matches(directoryNameRegex) } } +fun Collection.mostSpecificVersionOrLatest(kotlinVersion: KotlinVersion): File? { + return mostSpecificByVersionOrNull(kotlinVersion) + ?: singleOrNull { it.name == DirectoryNames.LATEST_SOURCE_DIR } +} + + + // Versioning is used to sort version-specific source sets in the 'first comes more specific' order // By 'more specific' we mean that '1.7.10' is more specific than '1.7'. // So [1.7, 1.7.10, 1.9.10, 1.7.22, 1.9, 1, 1.7.0, latest, 1.8] @@ -28,7 +59,7 @@ fun filterSourceDirsForCSM(sourceSetPath: Path): List { // For example, we may have '1.7' and '1' specific source sets. // That would mean that all 1.7.* versions we compile with the '1.7' source set, // and 1.8.+ up to 1.9.25 will be with the '1' source set -class CompilerModuleVersion(fullName: String, prefix: String) : Comparable { +private class CompilerModuleVersion(fullName: String, prefix: String) : Comparable { // For example, "v_1_7_10" -> "1.7.10" val version = fullName .removePrefix(prefix) @@ -61,11 +92,6 @@ private fun Collection.sortAndSelectBySemVer( ?.first } -fun Collection.mostSpecificVersionOrLatest(kotlinVersion: KotlinVersion): File? { - return mostSpecificByVersionOrNull(kotlinVersion) - ?: singleOrNull { it.name == Dir.LATEST_SOURCE_DIR } -} - private fun Collection.mostSpecificByVersionOrNull(kotlinVersion: KotlinVersion): File? { val (vPrefixed, prePrefixed) = partition { it.name.startsWith("v_") } diff --git a/gradle-conventions/src/main/kotlin/util/other/action.kt b/gradle-conventions/src/main/kotlin/util/other/action.kt new file mode 100644 index 000000000..f93bc60e1 --- /dev/null +++ b/gradle-conventions/src/main/kotlin/util/other/action.kt @@ -0,0 +1,16 @@ +/* + * Copyright 2023-2025 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. + */ + +package util.other + +enum class ActionApplied { + Applied, NotApplied; +} + +@Suppress("unused") +infix fun ActionApplied.otherwise(body: () -> Unit) { + if (this == ActionApplied.NotApplied) { + body() + } +} diff --git a/gradle-conventions/common/src/main/kotlin/util/Dir.kt b/gradle-conventions/src/main/kotlin/util/other/directoryNames.kt similarity index 58% rename from gradle-conventions/common/src/main/kotlin/util/Dir.kt rename to gradle-conventions/src/main/kotlin/util/other/directoryNames.kt index df31d5448..0996b8567 100644 --- a/gradle-conventions/common/src/main/kotlin/util/Dir.kt +++ b/gradle-conventions/src/main/kotlin/util/other/directoryNames.kt @@ -1,10 +1,10 @@ /* - * Copyright 2023-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. + * Copyright 2023-2025 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. */ -package util +package util.other -object Dir { +object DirectoryNames { const val MAIN_SOURCE_SET = "main" const val CORE_SOURCE_DIR = "core" @@ -12,6 +12,4 @@ object Dir { const val MAIN_RESOURCES = "main-resources" const val TEST_RESOURCES = "test-resources" - const val PROCESS_RESOURCES = "processResources" - const val PROCESS_TEST_RESOURCES = "processTestResources" } diff --git a/gradle-conventions/empty/src/main/kotlin/util/npm.kt b/gradle-conventions/src/main/kotlin/util/other/dokkaUtil.kt similarity index 56% rename from gradle-conventions/empty/src/main/kotlin/util/npm.kt rename to gradle-conventions/src/main/kotlin/util/other/dokkaUtil.kt index ecd985bca..5dadb2b64 100644 --- a/gradle-conventions/empty/src/main/kotlin/util/npm.kt +++ b/gradle-conventions/src/main/kotlin/util/other/dokkaUtil.kt @@ -2,10 +2,6 @@ * Copyright 2023-2025 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. */ -package util +package util.other -import org.gradle.api.Project - -fun Project.configureNpm() { - // only for latest -} +fun String.asDokkaVersion() = removeSuffix("-SNAPSHOT") diff --git a/gradle-conventions/common/src/main/kotlin/util/Path.kt b/gradle-conventions/src/main/kotlin/util/other/files.kt similarity index 86% rename from gradle-conventions/common/src/main/kotlin/util/Path.kt rename to gradle-conventions/src/main/kotlin/util/other/files.kt index 4ee3d65bd..10cb46493 100644 --- a/gradle-conventions/common/src/main/kotlin/util/Path.kt +++ b/gradle-conventions/src/main/kotlin/util/other/files.kt @@ -1,8 +1,8 @@ /* - * Copyright 2023-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. + * Copyright 2023-2025 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. */ -package util +package util.other import org.gradle.api.Project import java.io.File diff --git a/gradle-conventions-settings/src/main/kotlin/util/VersionCatalogForPlugins.kt b/gradle-conventions/src/main/kotlin/util/other/libs.kt similarity index 73% rename from gradle-conventions-settings/src/main/kotlin/util/VersionCatalogForPlugins.kt rename to gradle-conventions/src/main/kotlin/util/other/libs.kt index fffbe31c6..fcfc0be18 100644 --- a/gradle-conventions-settings/src/main/kotlin/util/VersionCatalogForPlugins.kt +++ b/gradle-conventions/src/main/kotlin/util/other/libs.kt @@ -1,8 +1,8 @@ /* - * Copyright 2023-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. + * Copyright 2023-2025 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. */ -package util +package util.other import org.gradle.accessors.dm.LibrariesForLibs import org.gradle.api.Project diff --git a/gradle-conventions/common/src/main/kotlin/util/OptionalProperty.kt b/gradle-conventions/src/main/kotlin/util/other/optionalProperty.kt similarity index 89% rename from gradle-conventions/common/src/main/kotlin/util/OptionalProperty.kt rename to gradle-conventions/src/main/kotlin/util/other/optionalProperty.kt index 845c0d0ec..14bdb0591 100644 --- a/gradle-conventions/common/src/main/kotlin/util/OptionalProperty.kt +++ b/gradle-conventions/src/main/kotlin/util/other/optionalProperty.kt @@ -1,8 +1,8 @@ /* - * Copyright 2023-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. + * Copyright 2023-2025 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. */ -package util +package util.other import org.gradle.api.Project import kotlin.reflect.KProperty @@ -16,7 +16,7 @@ class OptionalProperty(private val target: Project, private val subpaths: Array< } } -private fun Project.getValue(propertyName: String, subpaths: Array): Boolean { +fun Project.getValue(propertyName: String, subpaths: Array): Boolean { val subpathProperty = subpaths .joinToString(".", postfix = ".") .takeIf { it != "." && it.isNotEmpty() } diff --git a/gradle-conventions/src/main/kotlin/util/other/properties.kt b/gradle-conventions/src/main/kotlin/util/other/properties.kt new file mode 100644 index 000000000..a4be0269c --- /dev/null +++ b/gradle-conventions/src/main/kotlin/util/other/properties.kt @@ -0,0 +1,33 @@ +/* + * Copyright 2023-2025 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. + */ + +@file:Suppress("DuplicatedCode") + +package util.other + +import org.gradle.api.Project +import org.gradle.kotlin.dsl.extra +import java.util.Properties + +val Project.spacePassword get(): String? { + return (this.extra["spacePassword"] as String?) +} + +val Project.localProperties get(): Properties { + return (this.extra["localProperties"] as Properties) +} + +val Project.useProxyRepositories get(): Boolean { + return (this.extra["useProxyRepositories"] as Boolean) +} + +fun Project.getSensitiveProperty(name: String?): String? { + if (name == null) { + error("Expected not null property 'name' for publication repository config") + } + + return project.findProperty(name) as? String + ?: System.getenv(name) + ?: System.getProperty(name) +} diff --git a/gradle-conventions/common/src/main/kotlin/util/PublicModule.kt b/gradle-conventions/src/main/kotlin/util/other/publicModule.kt similarity index 79% rename from gradle-conventions/common/src/main/kotlin/util/PublicModule.kt rename to gradle-conventions/src/main/kotlin/util/other/publicModule.kt index 456f56aea..3b8f0cafe 100644 --- a/gradle-conventions/common/src/main/kotlin/util/PublicModule.kt +++ b/gradle-conventions/src/main/kotlin/util/other/publicModule.kt @@ -1,8 +1,8 @@ /* - * Copyright 2023-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. + * Copyright 2023-2025 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. */ -package util +package util.other import org.gradle.api.Project import org.gradle.kotlin.dsl.extra diff --git a/gradle-conventions/common/src/main/kotlin/util/PublicationUtils.kt b/gradle-conventions/src/main/kotlin/util/publication.kt similarity index 94% rename from gradle-conventions/common/src/main/kotlin/util/PublicationUtils.kt rename to gradle-conventions/src/main/kotlin/util/publication.kt index ff0623eb1..09b8dc4d5 100644 --- a/gradle-conventions/common/src/main/kotlin/util/PublicationUtils.kt +++ b/gradle-conventions/src/main/kotlin/util/publication.kt @@ -13,6 +13,7 @@ import org.gradle.api.publish.PublishingExtension import org.gradle.api.publish.maven.MavenPublication import org.gradle.kotlin.dsl.maven import org.jetbrains.kotlin.gradle.plugin.KotlinTarget +import util.other.getSensitiveProperty import java.io.File const val KOTLINX_RPC_PREFIX = "kotlinx-rpc" @@ -168,16 +169,6 @@ fun RepositoryHandler.configureRepository( project.logger.info("Configured ${config.name} repository for publication") } -fun Project.getSensitiveProperty(name: String?): String? { - if (name == null) { - error("Expected not null property 'name' for publication repository config") - } - - return project.findProperty(name) as? String - ?: System.getenv(name) - ?: System.getProperty(name) -} - -fun configError(parameterName: String): Nothing { +private fun configError(parameterName: String): Nothing { error("Expected not null $parameterName for publication repository config") } diff --git a/gradle-conventions/common/src/main/kotlin/util/TargetUtils.kt b/gradle-conventions/src/main/kotlin/util/targets/configure.kt similarity index 84% rename from gradle-conventions/common/src/main/kotlin/util/TargetUtils.kt rename to gradle-conventions/src/main/kotlin/util/targets/configure.kt index 904f53839..2656b1eeb 100644 --- a/gradle-conventions/common/src/main/kotlin/util/TargetUtils.kt +++ b/gradle-conventions/src/main/kotlin/util/targets/configure.kt @@ -1,8 +1,8 @@ /* - * Copyright 2023-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. + * Copyright 2023-2025 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. */ -package util +package util.targets import io.gitlab.arturbosch.detekt.extensions.DetektExtension import org.gradle.api.Action @@ -11,8 +11,10 @@ import org.gradle.jvm.toolchain.JavaLanguageVersion import org.gradle.kotlin.dsl.the import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension import org.jetbrains.kotlin.gradle.plugin.KotlinTarget +import util.kmp +import util.setPublicArtifactId -private fun KotlinMultiplatformExtension.configureTargets(config: ProjectKotlinConfig): List { +private fun KotlinMultiplatformExtension.configureTargets(config: KmpConfig): List { val targets = mutableListOf() if (config.native) { @@ -50,9 +52,9 @@ private fun Project.configureDetekt(targets: List) { the().source.from(sources) } -fun ProjectKotlinConfig.configureKotlin(action: Action = Action { }) { +fun KmpConfig.configureKotlinExtension(action: Action = Action { }) { kmp { - val includedTargets = configureTargets(this@configureKotlin) + val includedTargets = configureTargets(this@configureKotlinExtension) configureDetekt(includedTargets) diff --git a/gradle-conventions/common/src/main/kotlin/util/JsTarget.kt b/gradle-conventions/src/main/kotlin/util/targets/js.kt similarity index 79% rename from gradle-conventions/common/src/main/kotlin/util/JsTarget.kt rename to gradle-conventions/src/main/kotlin/util/targets/js.kt index 1cf8a06d6..36ea40f28 100644 --- a/gradle-conventions/common/src/main/kotlin/util/JsTarget.kt +++ b/gradle-conventions/src/main/kotlin/util/targets/js.kt @@ -2,28 +2,36 @@ * Copyright 2023-2025 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. */ -package util +package util.targets -import org.gradle.kotlin.dsl.getValue -import org.gradle.kotlin.dsl.getting import org.gradle.kotlin.dsl.invoke import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet import org.jetbrains.kotlin.gradle.targets.js.dsl.KotlinJsTargetDsl import org.jetbrains.kotlin.gradle.targets.js.ir.KotlinJsIrTarget +import util.kmp +import util.other.libs import java.io.File -fun ProjectKotlinConfig.configureJs() { +fun KmpConfig.configureJs() { if (!js) { return } kmp { js(IR) { + nodejs { + testTask { + useMocha { + timeout = "100s" + } + } + } + configureJsAndWasmJsTasks() } sourceSets { - val jsTest by getting { + jsTest { puppeteer(libs.versions.puppeteer.get()) } } @@ -37,14 +45,6 @@ fun KotlinSourceSet.puppeteer(version: String) { } fun KotlinJsTargetDsl.configureJsAndWasmJsTasks() { - nodejs { - testTask { - useMocha { - timeout = "100s" - } - } - } - (this as KotlinJsIrTarget).whenBrowserConfigured { testTask { useKarma { diff --git a/gradle-conventions/common/src/main/kotlin/util/jvm.kt b/gradle-conventions/src/main/kotlin/util/targets/jvm.kt similarity index 88% rename from gradle-conventions/common/src/main/kotlin/util/jvm.kt rename to gradle-conventions/src/main/kotlin/util/targets/jvm.kt index 4f3509dfd..0130e8c8a 100644 --- a/gradle-conventions/common/src/main/kotlin/util/jvm.kt +++ b/gradle-conventions/src/main/kotlin/util/targets/jvm.kt @@ -1,13 +1,15 @@ /* - * Copyright 2023-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. + * Copyright 2023-2025 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. */ -package util +package util.targets import org.gradle.api.Project import org.gradle.jvm.tasks.Jar import org.gradle.kotlin.dsl.attributes import org.gradle.kotlin.dsl.getByName +import util.other.files +import util.other.libs fun Project.configureJvm(isKmp: Boolean) { tasks.getByName(if (isKmp) "jvmJar" else "jar").apply { diff --git a/gradle-conventions/common/src/main/kotlin/util/ProjectKotlinConfig.kt b/gradle-conventions/src/main/kotlin/util/targets/kmpConfig.kt similarity index 88% rename from gradle-conventions/common/src/main/kotlin/util/ProjectKotlinConfig.kt rename to gradle-conventions/src/main/kotlin/util/targets/kmpConfig.kt index 6e5724fcf..66085b95d 100644 --- a/gradle-conventions/common/src/main/kotlin/util/ProjectKotlinConfig.kt +++ b/gradle-conventions/src/main/kotlin/util/targets/kmpConfig.kt @@ -2,7 +2,7 @@ * Copyright 2023-2025 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. */ -package util +package util.targets import groovy.json.JsonSlurper import org.gradle.api.Project @@ -10,12 +10,15 @@ import org.gradle.kotlin.dsl.extra import org.gradle.kotlin.dsl.provideDelegate import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension import org.jetbrains.kotlin.gradle.plugin.KotlinTarget +import util.kotlinVersionParsed +import util.other.optionalProperty +import util.other.optionalPropertyValue import java.io.File import kotlin.reflect.full.memberFunctions -const val UNSUPPORTED_TARGET = "-" -const val FULLY_SUPPORTED_TARGET = "*" -const val TARGETS_SINCE_KOTLIN_LOOKUP_PATH = "versions-root/targets-since-kotlin-lookup.json" +private const val UNSUPPORTED_TARGET = "-" +private const val FULLY_SUPPORTED_TARGET = "*" +private const val TARGETS_SINCE_KOTLIN_LOOKUP_PATH = "versions-root/targets-since-kotlin-lookup.json" /** * In the lookup table: @@ -32,7 +35,7 @@ private fun loadTargetsSinceKotlinLookupTable(rootDir: String): Map value != UNSUPPORTED_TARGET } } -class ProjectKotlinConfig( +class KmpConfig( project: Project, val kotlinVersion: KotlinVersion, ) : Project by project { @@ -83,10 +86,10 @@ class ProjectKotlinConfig( } } -fun Project.withKotlinConfig(configure: ProjectKotlinConfig.() -> Unit) { +fun Project.withKmpConfig(configure: KmpConfig.() -> Unit) { val kotlinVersion: KotlinVersion by extra - ProjectKotlinConfig( + KmpConfig( project = project, kotlinVersion = kotlinVersion, ).configure() diff --git a/gradle-conventions/src/main/kotlin/util/wasm.kt b/gradle-conventions/src/main/kotlin/util/targets/wasm.kt similarity index 86% rename from gradle-conventions/src/main/kotlin/util/wasm.kt rename to gradle-conventions/src/main/kotlin/util/targets/wasm.kt index 3810f7b41..34b3cb171 100644 --- a/gradle-conventions/src/main/kotlin/util/wasm.kt +++ b/gradle-conventions/src/main/kotlin/util/targets/wasm.kt @@ -2,14 +2,17 @@ * Copyright 2023-2025 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. */ -package util +package util.targets import org.gradle.kotlin.dsl.invoke +import org.jetbrains.kotlin.gradle.ExperimentalWasmDsl import org.jetbrains.kotlin.gradle.plugin.KotlinTarget -import org.jetbrains.kotlin.gradle.targets.js.dsl.ExperimentalWasmDsl +import util.kmp +import util.other.libs +import util.setPublicArtifactId @OptIn(ExperimentalWasmDsl::class) -fun ProjectKotlinConfig.configureWasm() { +fun KmpConfig.configureWasm() { fun KotlinTarget.configurePublication() { mavenPublication { setPublicArtifactId(project) diff --git a/gradle-conventions/common/src/main/kotlin/util/changelog.kt b/gradle-conventions/src/main/kotlin/util/tasks/changelog.kt similarity index 99% rename from gradle-conventions/common/src/main/kotlin/util/changelog.kt rename to gradle-conventions/src/main/kotlin/util/tasks/changelog.kt index 8ef63c472..a21fa271e 100644 --- a/gradle-conventions/common/src/main/kotlin/util/changelog.kt +++ b/gradle-conventions/src/main/kotlin/util/tasks/changelog.kt @@ -2,7 +2,7 @@ * Copyright 2023-2025 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. */ -package util +package util.tasks import org.gradle.api.DefaultTask import org.gradle.api.GradleException diff --git a/gradle-conventions/latest-only/src/main/kotlin/util/npm.kt b/gradle-conventions/src/main/kotlin/util/tasks/npm.kt similarity index 96% rename from gradle-conventions/latest-only/src/main/kotlin/util/npm.kt rename to gradle-conventions/src/main/kotlin/util/tasks/npm.kt index 059aa427c..d15224198 100644 --- a/gradle-conventions/latest-only/src/main/kotlin/util/npm.kt +++ b/gradle-conventions/src/main/kotlin/util/tasks/npm.kt @@ -2,7 +2,7 @@ * Copyright 2023-2025 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. */ -package util +package util.tasks import org.gradle.api.GradleException import org.gradle.api.Project @@ -12,6 +12,9 @@ import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootPlugin import org.jetbrains.kotlin.gradle.targets.js.yarn.YarnLockMismatchReport import org.jetbrains.kotlin.gradle.targets.js.yarn.YarnPlugin import org.jetbrains.kotlin.gradle.targets.js.yarn.YarnRootEnvSpec +import util.other.optionalProperty +import util.other.spacePassword +import util.other.useProxyRepositories import java.io.File fun Project.configureNpm() { diff --git a/gradle-conventions/common/src/main/kotlin/util/platformTable.kt b/gradle-conventions/src/main/kotlin/util/tasks/platformTable.kt similarity index 98% rename from gradle-conventions/common/src/main/kotlin/util/platformTable.kt rename to gradle-conventions/src/main/kotlin/util/tasks/platformTable.kt index 7078cc15d..e49005a61 100644 --- a/gradle-conventions/common/src/main/kotlin/util/platformTable.kt +++ b/gradle-conventions/src/main/kotlin/util/tasks/platformTable.kt @@ -2,7 +2,7 @@ * Copyright 2023-2025 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. */ -package util +package util.tasks import org.gradle.api.DefaultTask import org.gradle.api.GradleException @@ -20,6 +20,9 @@ import org.jetbrains.kotlin.gradle.targets.js.KotlinWasmTargetType import org.jetbrains.kotlin.gradle.targets.js.dsl.KotlinWasmJsTargetDsl import org.jetbrains.kotlin.gradle.targets.js.dsl.KotlinWasmWasiTargetDsl import org.jetbrains.kotlin.gradle.targets.js.ir.KotlinJsIrTarget +import util.KOTLIN_JVM_PLUGIN_ID +import util.KOTLIN_MULTIPLATFORM_PLUGIN_ID +import util.other.isPublicModule import java.io.File import java.nio.file.Files diff --git a/gradle-plugin/build.gradle.kts b/gradle-plugin/build.gradle.kts index a12f2f7ab..8390f7176 100644 --- a/gradle-plugin/build.gradle.kts +++ b/gradle-plugin/build.gradle.kts @@ -2,12 +2,11 @@ * Copyright 2023-2025 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. */ -import org.jetbrains.kotlin.gradle.dsl.ExplicitApiMode plugins { + `kotlin-dsl` alias(libs.plugins.conventions.jvm) alias(libs.plugins.conventions.gradle.publish) - alias(libs.plugins.gradle.kotlin.dsl) alias(libs.plugins.gradle.plugin.publish) alias(libs.plugins.conventions.gradle.doctor) } @@ -16,7 +15,7 @@ group = "org.jetbrains.kotlinx" version = rootProject.libs.versions.kotlinx.rpc.get() kotlin { - explicitApi = ExplicitApiMode.Disabled + explicitApi() } dependencies { @@ -51,13 +50,13 @@ abstract class GeneratePluginVersionTask @Inject constructor( ) : DefaultTask() { @TaskAction fun generate() { - val sourceFile = File(sourcesDir, "PluginVersion.kt") + val sourceFile = File(sourcesDir, "Versions.kt") sourceFile.writeText( """ package kotlinx.rpc - const val PLUGIN_VERSION = "$pluginVersion" + public const val PLUGIN_VERSION: String = "$pluginVersion" """.trimIndent() ) diff --git a/gradle-plugin/gradle.properties b/gradle-plugin/gradle.properties deleted file mode 120000 index 7677fb73b..000000000 --- a/gradle-plugin/gradle.properties +++ /dev/null @@ -1 +0,0 @@ -../gradle.properties \ No newline at end of file diff --git a/gradle-plugin/gradle.properties b/gradle-plugin/gradle.properties new file mode 100644 index 000000000..b64cbf878 --- /dev/null +++ b/gradle-plugin/gradle.properties @@ -0,0 +1,40 @@ +# +# Copyright 2023-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. +# + +kotlin.code.style=official + +kotlin.native.ignoreDisabledTargets=true + +kotlin.daemon.jvmargs=-Xmx6g -XX:+HeapDumpOnOutOfMemoryError +kotlin.daemon.useFallbackStrategy=false + +org.gradle.jvmargs=-Xmx6g -XX:+HeapDumpOnOutOfMemoryError -XX:+UseParallelGC -XX:MaxMetaspaceSize=768m +org.gradle.daemon=true +org.gradle.parallel=true +org.gradle.workers.max=8 +org.gradle.caching=true +org.gradle.configuration-cache=true + +org.jetbrains.dokka.experimental.gradle.pluginMode=V2Enabled +org.jetbrains.dokka.experimental.gradle.pluginMode.noWarn=true + +# development mode for kotlinx.rpc gradle plugin. Uses local project paths to apply the compiler plugin +kotlinx.rpc.plugin.internalDevelopment=true + +# uncomment to debug compilation process +#kotlin.compiler.execution.strategy=in-process + +# Uncomment to skip attempts to publish Develocity build scans +# Add this property to ~/.gradle/gradle.properties to avoid polluting git with unwanted changes +#kotlinx.rpc.develocity.skipBuildScans=true + +# Uncomment to skip adding git tags to Develocity build scan +# Add this property to ~/.gradle/gradle.properties to avoid polluting git with unwanted changes +#kotlinx.rpc.develocity.skipGitTags=true + +# Uncomment to sync IDEA when working with Kotlin master builds +#kotlinx.rpc.kotlinMasterBuild=true + +# set to true when building IDE compiler plugin artifacts +kotlinx.rpc.forIdeBuild=false diff --git a/gradle-plugin/src/main/kotlin/kotlinx/rpc/Extensions.kt b/gradle-plugin/src/main/kotlin/kotlinx/rpc/Extensions.kt index 6f71a2318..99f7d9cae 100644 --- a/gradle-plugin/src/main/kotlin/kotlinx/rpc/Extensions.kt +++ b/gradle-plugin/src/main/kotlin/kotlinx/rpc/Extensions.kt @@ -9,11 +9,12 @@ package kotlinx.rpc import org.gradle.api.Action import org.gradle.api.model.ObjectFactory import org.gradle.api.provider.Property +import org.gradle.api.provider.Provider import org.gradle.kotlin.dsl.newInstance import org.gradle.kotlin.dsl.property import javax.inject.Inject -open class RpcExtension @Inject constructor(objects: ObjectFactory) { +public open class RpcExtension @Inject constructor(objects: ObjectFactory) { /** * Controls `@Rpc` [annotation type-safety](https://github.com/Kotlin/kotlinx-rpc/pull/240) compile-time checkers. * @@ -21,31 +22,31 @@ open class RpcExtension @Inject constructor(objects: ObjectFactory) { * This option is only needed to prevent cases where type-safety analysis fails and valid code can't be compiled. */ @RpcDangerousApi - val annotationTypeSafetyEnabled = objects.property().convention(true) + public val annotationTypeSafetyEnabled: Provider = objects.property().convention(true) /** * Strict mode settings. * Allows configuring the reporting state of deprecated features. */ - val strict: RpcStrictModeExtension = objects.newInstance() + public val strict: RpcStrictModeExtension = objects.newInstance() /** * Strict mode settings. */ @Deprecated("Strict mode enabled irreversibly. This option can't change it.", level = DeprecationLevel.ERROR) - fun strict(configure: Action) { + public fun strict(configure: Action) { configure.execute(strict) } } -open class RpcStrictModeExtension @Inject constructor(objects: ObjectFactory) { +public open class RpcStrictModeExtension @Inject constructor(objects: ObjectFactory) { /** * `StateFlow`s in RPC services are deprecated, * due to their error-prone nature. * * Consider using plain flows and converting them to state on the application side. */ - val stateFlow: Property = objects.strictModeProperty() + public val stateFlow: Property = objects.strictModeProperty() /** * `SharedFlow`s in RPC services are deprecated, @@ -53,7 +54,7 @@ open class RpcStrictModeExtension @Inject constructor(objects: ObjectFactory) { * * Consider using plain flows and converting them to state on the application side. */ - val sharedFlow: Property = objects.strictModeProperty() + public val sharedFlow: Property = objects.strictModeProperty() /** * Nested flows in RPC services are deprecated, @@ -61,26 +62,26 @@ open class RpcStrictModeExtension @Inject constructor(objects: ObjectFactory) { * * Consider using plain flows and converting them to state on the application side. */ - val nestedFlow: Property = objects.strictModeProperty() + public val nestedFlow: Property = objects.strictModeProperty() /** * StreamScoped functions are deprecated. */ - val streamScopedFunctions: Property = objects.strictModeProperty() + public val streamScopedFunctions: Property = objects.strictModeProperty() /** * Suspending functions with server-streaming are deprecated in RPC. * * Consider returning a Flow in a non-suspending function. */ - val suspendingServerStreaming: Property = objects.strictModeProperty() + public val suspendingServerStreaming: Property = objects.strictModeProperty() /** * Not top-level flows in the return value are deprecated in RPC for streaming. * * Consider returning a Flow and requesting other data in a different method. */ - val notTopLevelServerFlow: Property = objects.strictModeProperty() + public val notTopLevelServerFlow: Property = objects.strictModeProperty() /** * Fields in RPC services are deprecated, @@ -89,7 +90,7 @@ open class RpcStrictModeExtension @Inject constructor(objects: ObjectFactory) { * Consider using regular streaming. */ @Deprecated("Field are deprecated with level ERROR. This option can't change it.") - val fields: Property = objects.strictModeProperty() + public val fields: Property = objects.strictModeProperty() private fun ObjectFactory.strictModeProperty( default: RpcStrictMode = RpcStrictMode.ERROR, @@ -98,8 +99,6 @@ open class RpcStrictModeExtension @Inject constructor(objects: ObjectFactory) { } } -enum class RpcStrictMode { +public enum class RpcStrictMode { NONE, WARNING, ERROR; - - fun toCompilerArg(): String = name.lowercase() } diff --git a/gradle-plugin/src/main/kotlin/kotlinx/rpc/KotlinCompilerPluginBuilder.kt b/gradle-plugin/src/main/kotlin/kotlinx/rpc/KotlinCompilerPluginBuilder.kt index b723c82ac..8190d2641 100644 --- a/gradle-plugin/src/main/kotlin/kotlinx/rpc/KotlinCompilerPluginBuilder.kt +++ b/gradle-plugin/src/main/kotlin/kotlinx/rpc/KotlinCompilerPluginBuilder.kt @@ -15,7 +15,7 @@ import org.jetbrains.kotlin.gradle.plugin.KotlinCompilerPluginSupportPlugin import org.jetbrains.kotlin.gradle.plugin.SubpluginArtifact import org.jetbrains.kotlin.gradle.plugin.SubpluginOption -class KotlinCompilerPluginBuilder { +internal class KotlinCompilerPluginBuilder { var applicable : (kotlinCompilation: KotlinCompilation<*>) -> Boolean = { true } var applyToCompilation: (kotlinCompilation: KotlinCompilation<*>) -> Provider> = { it.target.project.provider { emptyList() } @@ -64,6 +64,6 @@ class KotlinCompilerPluginBuilder { } } -fun compilerPlugin(builder: KotlinCompilerPluginBuilder.() -> Unit = {}): KotlinCompilerPluginSupportPlugin { +internal fun compilerPlugin(builder: KotlinCompilerPluginBuilder.() -> Unit = {}): KotlinCompilerPluginSupportPlugin { return KotlinCompilerPluginBuilder().apply(builder).build() } diff --git a/gradle-plugin/src/main/kotlin/kotlinx/rpc/RpcDangerousApi.kt b/gradle-plugin/src/main/kotlin/kotlinx/rpc/RpcDangerousApi.kt index 17efa87e3..d9941a492 100644 --- a/gradle-plugin/src/main/kotlin/kotlinx/rpc/RpcDangerousApi.kt +++ b/gradle-plugin/src/main/kotlin/kotlinx/rpc/RpcDangerousApi.kt @@ -5,4 +5,4 @@ package kotlinx.rpc @RequiresOptIn("This API is dangerous. It is not recommended to use it, unless you know what you are doing.") -annotation class RpcDangerousApi +public annotation class RpcDangerousApi diff --git a/gradle-plugin/src/main/kotlin/kotlinx/rpc/RpcGradlePlugin.kt b/gradle-plugin/src/main/kotlin/kotlinx/rpc/RpcGradlePlugin.kt index 96ccff1a1..8614f6e4b 100644 --- a/gradle-plugin/src/main/kotlin/kotlinx/rpc/RpcGradlePlugin.kt +++ b/gradle-plugin/src/main/kotlin/kotlinx/rpc/RpcGradlePlugin.kt @@ -9,7 +9,7 @@ import org.gradle.api.Project import org.gradle.kotlin.dsl.create @Suppress("unused") -class RpcGradlePlugin : Plugin { +public class RpcGradlePlugin : Plugin { override fun apply(target: Project) { target.extensions.create("rpc") diff --git a/gradle-plugin/src/main/kotlin/kotlinx/rpc/RpcPluginConst.kt b/gradle-plugin/src/main/kotlin/kotlinx/rpc/RpcPluginConst.kt index 387d021b2..689257ab6 100644 --- a/gradle-plugin/src/main/kotlin/kotlinx/rpc/RpcPluginConst.kt +++ b/gradle-plugin/src/main/kotlin/kotlinx/rpc/RpcPluginConst.kt @@ -9,7 +9,7 @@ import org.gradle.api.Project import org.jetbrains.kotlin.gradle.plugin.getKotlinPluginVersion import org.jetbrains.kotlin.gradle.utils.loadPropertyFromResources -object RpcPluginConst { +internal object RpcPluginConst { const val GROUP_ID = "org.jetbrains.kotlinx" const val PLUGIN_ID = "kotlinx-rpc" const val COMPILER_PLUGIN_ARTIFACT_ID = "kotlinx-rpc-compiler-plugin" @@ -31,7 +31,7 @@ object RpcPluginConst { } } -val Project.isInternalDevelopment: Boolean +internal val Project.isInternalDevelopment: Boolean get() { return (properties.getOrDefault(INTERNAL_DEVELOPMENT_PROPERTY, null) as String?) ?.toBoolean() ?: false diff --git a/gradle-plugin/src/main/kotlin/kotlinx/rpc/compilerPlugins.kt b/gradle-plugin/src/main/kotlin/kotlinx/rpc/compilerPlugins.kt index c70a82e61..fb74690ca 100644 --- a/gradle-plugin/src/main/kotlin/kotlinx/rpc/compilerPlugins.kt +++ b/gradle-plugin/src/main/kotlin/kotlinx/rpc/compilerPlugins.kt @@ -10,19 +10,19 @@ import org.gradle.kotlin.dsl.findByType import org.jetbrains.kotlin.gradle.plugin.KotlinCompilerPluginSupportPlugin import org.jetbrains.kotlin.gradle.plugin.SubpluginOption -class CompilerPluginK2 : KotlinCompilerPluginSupportPlugin by compilerPlugin({ +internal class CompilerPluginK2 : KotlinCompilerPluginSupportPlugin by compilerPlugin({ pluginSuffix = "-k2" }) -class CompilerPluginCommon : KotlinCompilerPluginSupportPlugin by compilerPlugin({ +internal class CompilerPluginCommon : KotlinCompilerPluginSupportPlugin by compilerPlugin({ pluginSuffix = "-common" }) -class CompilerPluginBackend : KotlinCompilerPluginSupportPlugin by compilerPlugin({ +internal class CompilerPluginBackend : KotlinCompilerPluginSupportPlugin by compilerPlugin({ pluginSuffix = "-backend" }) -class CompilerPluginCli : KotlinCompilerPluginSupportPlugin by compilerPlugin({ +internal class CompilerPluginCli : KotlinCompilerPluginSupportPlugin by compilerPlugin({ pluginSuffix = "-cli" applyToCompilation = { diff --git a/gradle.properties b/gradle.properties index 2c1780cb5..b64cbf878 100644 --- a/gradle.properties +++ b/gradle.properties @@ -12,7 +12,7 @@ kotlin.daemon.useFallbackStrategy=false org.gradle.jvmargs=-Xmx6g -XX:+HeapDumpOnOutOfMemoryError -XX:+UseParallelGC -XX:MaxMetaspaceSize=768m org.gradle.daemon=true org.gradle.parallel=true -org.gradle.workers.max=6 +org.gradle.workers.max=8 org.gradle.caching=true org.gradle.configuration-cache=true @@ -22,21 +22,9 @@ org.jetbrains.dokka.experimental.gradle.pluginMode.noWarn=true # development mode for kotlinx.rpc gradle plugin. Uses local project paths to apply the compiler plugin kotlinx.rpc.plugin.internalDevelopment=true -# https://github.com/gradle/gradle/issues/20416 -systemProp.org.gradle.kotlin.dsl.precompiled.accessors.strict=true - # uncomment to debug compilation process #kotlin.compiler.execution.strategy=in-process -# Otherwise produces: -# w: A compileOnly dependency is used in targets: Kotlin/JS. -# Dependencies: -# - org.jetbrains.kotlinx:atomicfu:0.22.0 (source sets: jsMain) -# -# Using compileOnly dependencies in these targets is not currently supported -# because compileOnly dependencies must be present during the compilation of projects that depend on this project. -kotlin.suppressGradlePluginWarnings=IncorrectCompileOnlyDependencyWarning - # Uncomment to skip attempts to publish Develocity build scans # Add this property to ~/.gradle/gradle.properties to avoid polluting git with unwanted changes #kotlinx.rpc.develocity.skipBuildScans=true diff --git a/jpms-check/build.gradle.kts b/jpms-check/build.gradle.kts index 2aa4410ca..d02ea18ac 100644 --- a/jpms-check/build.gradle.kts +++ b/jpms-check/build.gradle.kts @@ -2,8 +2,8 @@ * Copyright 2023-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. */ -import util.hasJavaModule -import util.javaModuleName +import util.targets.hasJavaModule +import util.targets.javaModuleName plugins { `java-library` diff --git a/krpc/krpc-client/build.gradle.kts b/krpc/krpc-client/build.gradle.kts index 195b9dabd..ff14c1633 100644 --- a/krpc/krpc-client/build.gradle.kts +++ b/krpc/krpc-client/build.gradle.kts @@ -2,17 +2,13 @@ * Copyright 2023-2025 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. */ -import kotlinx.rpc.RpcStrictMode -import util.applyAtomicfuPlugin - plugins { alias(libs.plugins.conventions.kmp) alias(libs.plugins.serialization) alias(libs.plugins.kotlinx.rpc) + alias(libs.plugins.atomicfu) } -applyAtomicfuPlugin() - kotlin { sourceSets { commonMain { diff --git a/krpc/krpc-core/build.gradle.kts b/krpc/krpc-core/build.gradle.kts index fe19a6840..d2ea2a8d0 100644 --- a/krpc/krpc-core/build.gradle.kts +++ b/krpc/krpc-core/build.gradle.kts @@ -2,17 +2,13 @@ * Copyright 2023-2025 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. */ -import kotlinx.rpc.RpcStrictMode -import util.applyAtomicfuPlugin - plugins { alias(libs.plugins.conventions.kmp) alias(libs.plugins.serialization) alias(libs.plugins.kotlinx.rpc) + alias(libs.plugins.atomicfu) } -applyAtomicfuPlugin() - kotlin { compilerOptions.freeCompilerArgs.add("-Xexpect-actual-classes") diff --git a/krpc/krpc-server/build.gradle.kts b/krpc/krpc-server/build.gradle.kts index 7d37f1c56..46a53f45f 100644 --- a/krpc/krpc-server/build.gradle.kts +++ b/krpc/krpc-server/build.gradle.kts @@ -2,16 +2,13 @@ * Copyright 2023-2025 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. */ -import util.applyAtomicfuPlugin - plugins { alias(libs.plugins.conventions.kmp) alias(libs.plugins.serialization) alias(libs.plugins.kotlinx.rpc) + alias(libs.plugins.atomicfu) } -applyAtomicfuPlugin() - kotlin { sourceSets { commonMain { diff --git a/krpc/krpc-test/build.gradle.kts b/krpc/krpc-test/build.gradle.kts index f559f01fa..dff27600b 100644 --- a/krpc/krpc-test/build.gradle.kts +++ b/krpc/krpc-test/build.gradle.kts @@ -5,25 +5,19 @@ import org.jetbrains.kotlin.gradle.dsl.ExplicitApiMode import org.jetbrains.kotlin.gradle.targets.js.testing.KotlinJsTest import org.jetbrains.kotlin.gradle.targets.jvm.tasks.KotlinJvmTest -import util.applyAtomicfuPlugin import java.nio.file.Files plugins { alias(libs.plugins.conventions.kmp) alias(libs.plugins.serialization) alias(libs.plugins.kotlinx.rpc) + alias(libs.plugins.atomicfu) } -applyAtomicfuPlugin() - kotlin { sourceSets { commonMain { dependencies { - // Workaround for - // KLIB resolver: Could not find "org.jetbrains.kotlinx:atomicfu" - api(libs.atomicfu) - api(projects.krpc.krpcCore) api(projects.krpc.krpcServer) api(projects.krpc.krpcClient) diff --git a/krpc/krpc-test/src/jvmTest/kotlin/kotlinx/rpc/krpc/test/api/util/GoldChecks.kt b/krpc/krpc-test/src/jvmTest/kotlin/kotlinx/rpc/krpc/test/api/util/GoldChecks.kt index a46c1548f..2c90c61ea 100644 --- a/krpc/krpc-test/src/jvmTest/kotlin/kotlinx/rpc/krpc/test/api/util/GoldChecks.kt +++ b/krpc/krpc-test/src/jvmTest/kotlin/kotlinx/rpc/krpc/test/api/util/GoldChecks.kt @@ -116,7 +116,8 @@ private fun goldFileLine(goldPath: String?): String { } } -private val isCI = System.getenv("TEAMCITY_VERSION") != null +private val isCI = System.getenv("TEAMCITY_VERSION") != null || + System.getenv("GITHUB_ACTIONS") != null object GoldUtils { val NewLine: String = System.lineSeparator() diff --git a/settings.gradle.kts b/settings.gradle.kts index 0656e77f7..89cfb8408 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -13,14 +13,6 @@ pluginManagement { includeBuild("gradle-plugin") apply(from = "gradle-conventions-settings/src/main/kotlin/conventions-repositories.settings.gradle.kts") - - resolutionStrategy { - eachPlugin { - if (requested.id.id == "kotlinx-atomicfu") { - useModule("org.jetbrains.kotlinx:atomicfu-gradle-plugin:${requested.version}") - } - } - } } plugins { diff --git a/tests/compiler-plugin-tests/build.gradle.kts b/tests/compiler-plugin-tests/build.gradle.kts index 51ecfb492..095972f1b 100644 --- a/tests/compiler-plugin-tests/build.gradle.kts +++ b/tests/compiler-plugin-tests/build.gradle.kts @@ -4,8 +4,6 @@ import org.jetbrains.kotlin.gradle.dsl.ExplicitApiMode import org.jetbrains.kotlin.gradle.tasks.KotlinCompile -import util.otherwise -import util.whenForIde plugins { java @@ -143,7 +141,7 @@ val generateTests = tasks.register("generateTests") { mainClass.set("kotlinx.rpc.codegen.test.GenerateTestsKt") } -val isCI = System.getenv("TEAMCITY_VERSION") != null +val isCI = System.getenv("TEAMCITY_VERSION") != null || System.getenv("GITHUB_ACTIONS") != null tasks.named("compileTestKotlin").configure { if (!isCI) { diff --git a/tests/krpc-compatibility-tests/build.gradle.kts b/tests/krpc-compatibility-tests/build.gradle.kts index 72e15ff9f..8b57ad1e6 100644 --- a/tests/krpc-compatibility-tests/build.gradle.kts +++ b/tests/krpc-compatibility-tests/build.gradle.kts @@ -3,16 +3,14 @@ */ import org.jetbrains.kotlin.gradle.dsl.ExplicitApiMode -import util.applyAtomicfuPlugin plugins { alias(libs.plugins.conventions.jvm) alias(libs.plugins.serialization) alias(libs.plugins.kotlinx.rpc) + alias(libs.plugins.atomicfu) } -applyAtomicfuPlugin() - val main: SourceSet by sourceSets.getting val test: SourceSet by sourceSets.getting diff --git a/utils/build.gradle.kts b/utils/build.gradle.kts index a1584fbeb..01b88cd94 100644 --- a/utils/build.gradle.kts +++ b/utils/build.gradle.kts @@ -2,14 +2,11 @@ * Copyright 2023-2025 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. */ -import util.applyAtomicfuPlugin - plugins { alias(libs.plugins.conventions.kmp) + alias(libs.plugins.atomicfu) } -applyAtomicfuPlugin() - kotlin { sourceSets { commonMain { diff --git a/versions-root/kotlin-versions-lookup.csv b/versions-root/kotlin-versions-lookup.csv deleted file mode 100644 index 61150fdaa..000000000 --- a/versions-root/kotlin-versions-lookup.csv +++ /dev/null @@ -1,10 +0,0 @@ -Kotlin,atomicfu,serialization,detekt-gradle-plugin,gradle-kotlin-dsl,binary-compatibility-validator,kover -2.2.0,0.27.0,1.8.1,1.23.8,5.1.2,0.17.0,0.9.1 -2.1.21,0.27.0,1.8.1,1.23.8,5.1.2,0.17.0,0.9.1 -2.1.20,0.27.0,1.8.1,1.23.8,5.1.2,0.17.0,0.9.1 -2.1.10,0.27.0,1.8.1,1.23.8,5.1.2,0.17.0,0.9.1 -2.1.0,0.27.0,1.8.1,1.23.8,5.1.2,0.17.0,0.9.1 -2.0.21,0.26.0,1.7.3,1.23.8,5.1.2,0.16.3,0.8.3 -2.0.20,0.26.0,1.7.3,1.23.8,5.1.2,0.16.3,0.8.3 -2.0.10,0.26.0,1.7.1,1.23.8,5.1.2,0.16.3,0.8.3 -2.0.0,0.26.0,1.7.1,1.23.8,5.1.2,0.16.3,0.8.3 diff --git a/versions-root/libs.versions.toml b/versions-root/libs.versions.toml index e21214067..d787f04bc 100644 --- a/versions-root/libs.versions.toml +++ b/versions-root/libs.versions.toml @@ -20,22 +20,14 @@ junit5 = "5.12.1" intellij = "241.19416.19" gradle-doctor = "0.10.0" kotlinx-browser = "0.3" -shadow-jar = "9.0.0-beta12" dokka = "2.0.0" - -# Stub versions – relpaced based on kotlin, mostly for gradle-related (plugins) dependencies -# but also for dependencies for compiler-specific modules. -# -# The current version is the one that is used with the latest Kotlin. -# -# NOTE: When updating kotlin-versions-lookup.csv, update the latest version here for the Renovate configs +puppeteer = "24.9.0" atomicfu = "0.27.0" serialization = "1.8.1" detekt-gradle-plugin = "1.23.8" -gradle-kotlin-dsl = "5.1.2" kover = "0.9.1" - -puppeteer = "24.9.0" +develocity = "3.17" +common-custom-user-data = "2.2.1" [libraries] # kotlinx.rpc – references to the included builds @@ -92,23 +84,32 @@ junit5-platform-launcher = { module = "org.junit.platform:junit-platform-launche junit5-platform-runner = { module = "org.junit.platform:junit-platform-runner" } junit5-platform-suite-api = { module = "org.junit.platform:junit-platform-suite-api" } +# dokka +dokka-core = { module = "org.jetbrains.dokka:dokka-core", version.ref = "dokka" } +dokka-base = { module = "org.jetbrains.dokka:dokka-base", version.ref = "dokka" } +dokka-test-api = { module = "org.jetbrains.dokka:dokka-test-api", version.ref = "dokka" } +dokka-base-test-utils = { module = "org.jetbrains.dokka:dokka-base-test-utils", version.ref = "dokka" } +dokka-analysis-kotlin-symbols = { module = "org.jetbrains.dokka:analysis-kotlin-symbols", version.ref = "dokka" } +dokka-rpc-plugin = { module = "org.jetbrains.kotlinx:dokka-rpc-plugin", version.ref = "kotlinx-rpc" } + # other kotlin-logging = { module = "io.github.oshai:kotlin-logging", version.ref = "kotlin-logging" } kotlin-logging-legacy = { module = "io.github.microutils:kotlin-logging", version.ref = "kotlin-logging" } coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "coroutines" } coroutines-test = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-test", version.ref = "coroutines" } coroutines-debug = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-debug", version.ref = "coroutines" } -detekt-gradle-plugin = { module = "io.gitlab.arturbosch.detekt:detekt-gradle-plugin", version.ref = "detekt-gradle-plugin" } -kover-gradle-plugin = { module = "org.jetbrains.kotlinx:kover-gradle-plugin", version.ref = "kover" } -dokka-core = { module = "org.jetbrains.dokka:dokka-core", version.ref = "dokka" } -dokka-base = { module = "org.jetbrains.dokka:dokka-base", version.ref = "dokka" } -dokka-gradle-plugin = { module = "org.jetbrains.dokka:dokka-gradle-plugin", version.ref = "dokka" } -dokka-rpc-plugin = { module = "org.jetbrains.kotlinx:dokka-rpc-plugin", version.ref = "kotlinx-rpc" } kotlin-js-wrappers = { module = "org.jetbrains.kotlin-wrappers:kotlin-js", version.ref = "kotlin-wrappers" } -gradle-kotlin-dsl-pluigns = { module = "org.gradle.kotlin:gradle-kotlin-dsl-plugins", version.ref = "gradle-kotlin-dsl" } intellij-util = { module = "com.jetbrains.intellij.platform:util", version.ref = "intellij" } -gradle-doctor-plugin = { module = "com.osacky.doctor:doctor-plugin", version.ref = "gradle-doctor" } atomicfu = { module = "org.jetbrains.kotlinx:atomicfu", version.ref = "atomicfu" } +develocity = { module = "com.gradle:develocity-gradle-plugin", version.ref = "develocity" } +common-custom-user-data = { module ="com.gradle:common-custom-user-data-gradle-plugin", version.ref = "common-custom-user-data" } + +# gradle plugins as lib deps +detekt-gradle-plugin = { module = "io.gitlab.arturbosch.detekt:detekt-gradle-plugin", version.ref = "detekt-gradle-plugin" } +kover-gradle-plugin = { module = "org.jetbrains.kotlinx:kover-gradle-plugin", version.ref = "kover" } +dokka-gradle-plugin = { module = "org.jetbrains.dokka:dokka-gradle-plugin", version.ref = "dokka" } +gradle-doctor-gradle-plugin = { module = "com.osacky.doctor:doctor-plugin", version.ref = "gradle-doctor" } +gradle-publish-gradle-plugin = { module = "com.gradle.publish:plugin-publish-plugin", version.ref = "gradle-plugin-publish" } [plugins] kotlin-multiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin-lang" } @@ -117,21 +118,22 @@ serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref detekt = { id = "io.gitlab.arturbosch.detekt", version.ref = "detekt-gradle-plugin" } atomicfu = { id = "org.jetbrains.kotlinx.atomicfu", version.ref = "atomicfu" } -gradle-kotlin-dsl = { id = "org.gradle.kotlin.kotlin-dsl", version.ref = "gradle-kotlin-dsl" } kover = { id = "org.jetbrains.kotlinx.kover", version.ref = "kover" } gradle-plugin-publish = { id = "com.gradle.plugin-publish", version.ref = "gradle-plugin-publish" } -shadow-jar = { id = "com.gradleup.shadow", version.ref = "shadow-jar" } dokka = { id = "org.jetbrains.dokka", version.ref = "dokka" } # gradle-conventions project -conventions-common = { id = "conventions-common", version.ref = "kotlinx-rpc" } -conventions-jvm = { id = "conventions-jvm", version.ref = "kotlinx-rpc" } -conventions-kmp = { id = "conventions-kmp", version.ref = "kotlinx-rpc" } -conventions-gradle-publish = { id = "conventions-gradle-publish", version.ref = "kotlinx-rpc" } -conventions-kover = { id = "conventions-kover", version.ref = "kotlinx-rpc" } -conventions-gradle-doctor = { id = "conventions-gradle-doctor", version.ref = "kotlinx-rpc" } -conventions-npm = { id = "conventions-npm", version.ref = "kotlinx-rpc" } -compiler-specific-module = { id = "compiler-specific-module", version.ref = "kotlinx-rpc" } +conventions-common = { id = "conventions-common" } +conventions-jvm = { id = "conventions-jvm" } +conventions-kmp = { id = "conventions-kmp" } +conventions-gradle-publish = { id = "conventions-gradle-publish" } +conventions-kover = { id = "conventions-kover" } +conventions-gradle-doctor = { id = "conventions-gradle-doctor" } +conventions-npm = { id = "conventions-npm" } +conventions-root = { id = "conventions-root" } +conventions-dokka-spec = { id = "conventions-dokka-spec" } +conventions-dokka-public = { id = "conventions-dokka-public" } +compiler-specific-module = { id = "compiler-specific-module" } # gradle-plugin project kotlinx-rpc = { id = "org.jetbrains.kotlinx.rpc.plugin" }