Skip to content
Draft
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
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@ java {
withSourcesJar()
}

configureJavaCompatibility(8)
if (project.name != "gradle-plugin") {
configureJavaCompatibility(8)
}

configureKotlinCompatibility("2.0.0")

kotlin {
Expand Down
30 changes: 19 additions & 11 deletions gradle-conventions/src/main/kotlin/util/other/generateSource.kt
Original file line number Diff line number Diff line change
Expand Up @@ -40,20 +40,28 @@ fun Project.generateSource(
text: String,
chooseSourceSet: NamedDomainObjectContainer<KotlinSourceSet>.() -> NamedDomainObjectProvider<KotlinSourceSet>,
) {
val sourcesDir = File(project.layout.buildDirectory.asFile.get(), "generated-sources/kotlin")

val generatePluginVersionTask =
tasks.register<GenerateSourceTask>("generateSources_$name", name, text, sourcesDir)

withKotlinJvmExtension {
chooseSourceSet(sourceSets).configure {
kotlin.srcDir(generatePluginVersionTask.map { it.sourcesDir })
}
generateSource(sourceSets, name, text, chooseSourceSet)
}

withKotlinKmpExtension {
chooseSourceSet(sourceSets).configure {
kotlin.srcDir(generatePluginVersionTask.map { it.sourcesDir })
}
generateSource(sourceSets, name, text, chooseSourceSet)
}
}

private fun Project.generateSource(
sourceSets: NamedDomainObjectContainer<KotlinSourceSet>,
name: String,
text: String,
chooseSourceSet: NamedDomainObjectContainer<KotlinSourceSet>.() -> NamedDomainObjectProvider<KotlinSourceSet>,
) {
val sourceSet = chooseSourceSet(sourceSets)
val sourcesDir = File(project.layout.buildDirectory.asFile.get(), "generated-sources/kotlin/${sourceSet.name}")

val generatePluginVersionTask =
tasks.register<GenerateSourceTask>("generateSources_$name", name, text, sourcesDir)

sourceSet.configure {
kotlin.srcDir(generatePluginVersionTask.map { it.sourcesDir })
}
}
6 changes: 1 addition & 5 deletions gradle-plugin/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,6 @@
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
import util.other.generateSource

/*
* Copyright 2023-2025 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
*/

plugins {
`kotlin-dsl`
alias(libs.plugins.conventions.jvm)
Expand All @@ -22,7 +18,7 @@ version = rootProject.libs.versions.kotlinx.rpc.get()
kotlin {
explicitApi()

jvmToolchain(11)
jvmToolchain(17)
}

tasks.withType<KotlinCompile>().configureEach {
Expand Down
51 changes: 43 additions & 8 deletions gradle-plugin/src/main/kotlin/kotlinx/rpc/Extensions.kt
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ internal fun Project.rpcExtensionOrNull(): RpcExtension? = extensions.findByType
internal fun Project.rpcExtension(): RpcExtension = rpcExtensionOrNull()
?: error("Rpc extension not found. Please apply the plugin to the project")

public open class RpcExtension @Inject constructor(objects: ObjectFactory, private val project: Project) {
public open class RpcExtension @Inject constructor(objects: ObjectFactory, project: Project) {
/**
* Controls `@Rpc` [annotation type-safety](https://github.com/Kotlin/kotlinx-rpc/pull/240) compile-time checkers.
*
Expand All @@ -48,25 +48,60 @@ public open class RpcExtension @Inject constructor(objects: ObjectFactory, priva
configure.execute(strict)
}

internal val protocApplied = AtomicBoolean(false)

/**
* Protoc settings.
*
* Can't be called in a lazy context if not initialized.
*/
public val protoc: ProtocExtension by lazy {
if (protocApplied.get()) {
error("Illegal access to protoc extension during DefaultProtocExtension.init")
public val protoc: Provider<ProtocExtension> = project.provider {
if (!protocApplied.get()) {
error("""
Protoc extension was not initialized.
Please, apply the plugin by using the following declaration:

rpc {
protoc()
}

If the error persists, check if you are using this property lazily,
i.e. by calling 'protoc.map { }' and not 'protoc.get()',
otherwise the order of initialization may be wrong.
""".trimIndent())
}

protocApplied.set(true)
objects.newInstance<DefaultProtocExtension>()
protocInternal
}

/**
* Protoc settings.
*/
public fun protoc(configure: Action<ProtocExtension> = Action {}) {
configure.execute(protoc)
configure.execute(protocInternal)
}

internal val protocApplied = AtomicBoolean(false)

internal val protocInternal by lazy {
if (protocApplied.get()) {
error("Illegal access to protoc extension during DefaultProtocExtension.init")
}

protocApplied.set(true)
objects.newInstance<DefaultProtocExtension>().apply {
callbacks.forEach { it.execute(this) }
}
}

private val callbacks = mutableListOf<Action<ProtocExtension>>()

internal fun whenProtocApplied(action: Action<ProtocExtension>) {
if (protocApplied.get()) {
action.execute(protoc.get())
return
}

callbacks.add(action)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import kotlin.time.Duration
*
* @see <a href="https://buf.build/docs/reference/cli/buf/">buf commands</a>
*/
public open class BufExtension @Inject constructor(objects: ObjectFactory) {
public open class BufExtension @Inject internal constructor(objects: ObjectFactory) {
/**
* `--config` argument value.
*
Expand Down Expand Up @@ -101,17 +101,17 @@ public open class BufExtension @Inject constructor(objects: ObjectFactory) {
/**
* Allows registering custom Buf tasks that can operate on the generated workspace.
*/
public open class BufTasksExtension @Inject constructor(internal val project: Project) {
public open class BufTasksExtension @Inject internal constructor(internal val project: Project) {

/**
* Registers a custom Buf task that operates on the generated workspace.
*
* Name conventions:
* `lint` input for [name] will result in tasks
* named 'bufLintMain' and 'bufLintTest' for Kotlin/JVM projects
* and 'bufLintCommonMain' and 'bufLintCommonTest' for Kotlin/Multiplatform projects.
* and 'bufLintCommonMain', 'bufLintCommonTest', 'bufLintNativeMain', etc., for Kotlin/Multiplatform projects.
*
* Note the by default 'test' task doesn't depend on 'main' task.
* Note the by default 'test' task doesn't depend on the 'main' task.
*/
public fun <T : BufExecTask> registerWorkspaceTask(
kClass: KClass<T>,
Expand All @@ -129,7 +129,6 @@ public open class BufTasksExtension @Inject constructor(internal val project: Pr
return provider
}


/**
* Registers a custom Buf task that operates on the generated workspace.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ internal fun <T : BufExecTask> Project.registerBufExecTask(
bufExecutable.set(executableConfiguration.singleFile)
this.workingDir.set(workingDir)

val buf = provider { rpcExtension().protoc.buf }
val buf = provider { rpcExtension().protoc.get().buf }
configFile.set(buf.flatMap { it.configFile })
logFormat.set(buf.flatMap { it.logFormat })
bufTimeoutInWholeSeconds.set(buf.flatMap { it.timeout.map { duration -> duration.inWholeSeconds } })
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ internal fun Project.registerBufGenerateTask(
group = PROTO_GROUP
description = "Generates code from .proto files using 'buf generate'"

val generate = provider { rpcExtension().protoc.buf.generate }
val generate = provider { rpcExtension().protoc.get().buf.generate }

includeImports.set(generate.flatMap { it.includeImports })
includeWkt.set(generate.flatMap { it.includeWkt })
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,19 +137,13 @@ public abstract class GenerateBufGenYaml : DefaultTask() {
internal fun Project.registerGenerateBufGenYamlTask(
name: String,
buildSourceSetsDir: File,
protocPlugins: Provider<List<ProtocPlugin>>,
protocPlugins: Provider<Set<ProtocPlugin>>,
configure: GenerateBufGenYaml.() -> Unit = {},
): TaskProvider<GenerateBufGenYaml> {
val capitalizeName = name.replaceFirstChar { it.uppercase() }
return project.tasks.register<GenerateBufGenYaml>("${GenerateBufGenYaml.NAME_PREFIX}$capitalizeName") {
val pluginsProvider = project.provider {
protocPlugins.get().map { plugin ->
if (!plugin.artifact.isPresent) {
throw GradleException(
"Artifact is not specified for protoc plugin ${plugin.name}. " +
"Use `local {}` or `remote {}` to specify it.")
}

val artifact = plugin.artifact.get()
val locator = when (artifact) {
is ProtocPlugin.Artifact.Local -> artifact.executor.get()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@
package kotlinx.rpc.buf.tasks

import kotlinx.rpc.buf.BUF_YAML
import kotlinx.rpc.protoc.DefaultProtoSourceSet
import kotlinx.rpc.protoc.PROTO_GROUP
import kotlinx.rpc.util.ensureRegularFileExists
import org.gradle.api.DefaultTask
import org.gradle.api.Project
import org.gradle.api.provider.Property
import org.gradle.api.provider.Provider
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.OutputFile
import org.gradle.api.tasks.TaskAction
Expand Down Expand Up @@ -88,7 +90,7 @@ internal fun Project.registerGenerateBufYamlTask(
buildSourceSetsDir: File,
buildSourceSetsProtoDir: File,
buildSourceSetsImportDir: File,
withImport: Boolean,
withImport: Provider<Boolean>,
configure: GenerateBufYaml.() -> Unit = {},
): TaskProvider<GenerateBufYaml> {
val capitalizeName = name.replaceFirstChar { it.uppercase() }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ package kotlinx.rpc.internal
import kotlinx.rpc.buf.tasks.BufGenerateTask
import kotlinx.rpc.protoc.grpcKotlinMultiplatform
import kotlinx.rpc.protoc.kotlinMultiplatform
import kotlinx.rpc.protoc.protoSourceSets
import kotlinx.rpc.rpcExtension
import org.gradle.api.Project
import org.gradle.internal.extensions.core.extra
Expand All @@ -21,9 +20,7 @@ public fun Project.configureLocalProtocGenDevelopmentDependency(
val globalRootDir: String by extra

// init
rpcExtension().protoc()

protoSourceSets.all {
rpcExtension().protoc {
plugins {
kotlinMultiplatform {
local {
Expand Down
Loading
Loading