Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 24 additions & 7 deletions gradle-plugin/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* 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.ExplicitApiMode
Expand All @@ -16,10 +16,11 @@ group = "org.jetbrains.kotlinx"
version = rootProject.libs.versions.kotlinx.rpc.get()

kotlin {
explicitApi = ExplicitApiMode.Disabled
explicitApi = ExplicitApiMode.Strict
}

dependencies {
implementation(libs.protobuf.gradle.plugin)
compileOnly(libs.kotlin.gradle.plugin)
}

Expand All @@ -46,18 +47,28 @@ gradlePlugin {
}

abstract class GeneratePluginVersionTask @Inject constructor(
@get:Input val pluginVersion: String,
@get:Input val libraryVersion: String,
@get:Input val protobufVersion: String,
@get:Input val grpcVersion: String,
@get:Input val grpcKotlinVersion: String,
@get:OutputDirectory val sourcesDir: File
) : 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 LIBRARY_VERSION: String = "$libraryVersion"

@Deprecated("Use kotlinx.rpc.LIBRARY_VERSION instead", ReplaceWith("kotlinx.rpc.LIBRARY_VERSION"))
public const val PLUGIN_VERSION: String = LIBRARY_VERSION

public const val PROTOBUF_VERSION: String = "$protobufVersion"
public const val GRPC_VERSION: String = "$grpcVersion"
public const val GRPC_KOTLIN_VERSION: String = "$grpcKotlinVersion"

""".trimIndent()
)
Expand All @@ -66,8 +77,14 @@ abstract class GeneratePluginVersionTask @Inject constructor(

val sourcesDir = File(project.layout.buildDirectory.asFile.get(), "generated-sources/pluginVersion")

val generatePluginVersionTask =
tasks.register<GeneratePluginVersionTask>("generatePluginVersion", version.toString(), sourcesDir)
val generatePluginVersionTask = tasks.register<GeneratePluginVersionTask>(
"generatePluginVersion",
version.toString(),
libs.versions.protobuf.asProvider().get().toString(),
libs.versions.grpc.asProvider().get().toString(),
libs.versions.grpc.kotlin.get().toString(),
sourcesDir,
)

kotlin {
sourceSets {
Expand Down
46 changes: 33 additions & 13 deletions gradle-plugin/src/main/kotlin/kotlinx/rpc/Extensions.kt
Original file line number Diff line number Diff line change
@@ -1,67 +1,83 @@
/*
* 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.
*/

@file:Suppress("unused")

package kotlinx.rpc

import org.gradle.api.Action
import org.gradle.api.Project
import org.gradle.api.model.ObjectFactory
import org.gradle.api.provider.Property
import org.gradle.kotlin.dsl.findByType
import org.gradle.kotlin.dsl.newInstance
import org.gradle.kotlin.dsl.property
import javax.inject.Inject

open class RpcExtension @Inject constructor(objects: ObjectFactory) {
public fun Project.rpcExtension(): RpcExtension = extensions.findByType<RpcExtension>() ?: RpcExtension(objects)

public open class RpcExtension @Inject constructor(objects: ObjectFactory) {
/**
* Controls `@Rpc` [annotation type-safety](https://github.com/Kotlin/kotlinx-rpc/pull/240) compile-time checkers.
*
* CAUTION: Disabling is considered unsafe.
* 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<Boolean>().convention(true)
public val annotationTypeSafetyEnabled: Property<Boolean> = objects.property<Boolean>().convention(true)

/**
* Strict mode settings.
* Allows configuring the reporting state of deprecated features.
*/
val strict: RpcStrictModeExtension = objects.newInstance<RpcStrictModeExtension>()
public val strict: RpcStrictModeExtension = objects.newInstance<RpcStrictModeExtension>()

/**
* Strict mode settings.
* Allows configuring the reporting state of deprecated features.
*/
fun strict(configure: Action<RpcStrictModeExtension>) {
public fun strict(configure: Action<RpcStrictModeExtension>) {
configure.execute(strict)
}

/**
* Grpc settings.
*/
public val grpc: GrpcExtension = objects.newInstance<GrpcExtension>()

/**
* Grpc settings.
*/
public fun grpc(configure: Action<GrpcExtension>) {
configure.execute(grpc)
}
}

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<RpcStrictMode> = objects.strictModeProperty()
public val stateFlow: Property<RpcStrictMode> = objects.strictModeProperty()

/**
* `SharedFlow`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 sharedFlow: Property<RpcStrictMode> = objects.strictModeProperty()
public val sharedFlow: Property<RpcStrictMode> = objects.strictModeProperty()

/**
* Nested flows 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 nestedFlow: Property<RpcStrictMode> = objects.strictModeProperty()
public val nestedFlow: Property<RpcStrictMode> = objects.strictModeProperty()

/**
* WIP: https://youtrack.jetbrains.com/issue/KRPC-133
Expand All @@ -80,15 +96,15 @@ open class RpcStrictModeExtension @Inject constructor(objects: ObjectFactory) {
*
* Consider returning a Flow and requesting other data in a different method.
*/
val notTopLevelServerFlow: Property<RpcStrictMode> = objects.strictModeProperty()
public val notTopLevelServerFlow: Property<RpcStrictMode> = objects.strictModeProperty()

/**
* Fields in RPC services are deprecated,
* due to its error-prone nature.
*
* Consider using regular streaming.
*/
val fields: Property<RpcStrictMode> = objects.strictModeProperty()
public val fields: Property<RpcStrictMode> = objects.strictModeProperty()

private fun ObjectFactory.strictModeProperty(
default: RpcStrictMode = RpcStrictMode.WARNING,
Expand All @@ -97,8 +113,12 @@ open class RpcStrictModeExtension @Inject constructor(objects: ObjectFactory) {
}
}

enum class RpcStrictMode {
/**
* Strict mode inspections levels.
* Correspond to same compiler levels of messages.
*/
public enum class RpcStrictMode {
NONE, WARNING, ERROR;

fun toCompilerArg(): String = name.lowercase()
internal fun toCompilerArg(): String = name.lowercase()
}
Loading