diff --git a/docs/wire_compiler.md b/docs/wire_compiler.md index e088adfe0d..0873b028a0 100644 --- a/docs/wire_compiler.md +++ b/docs/wire_compiler.md @@ -9,7 +9,7 @@ Getting Started --------------- The best way to configure and execute the Wire compiler is via our [Gradle][gradle] plugin. It -requires Gradle 5.5 or newer. +requires Gradle 8.2 or newer. A typical project has `.proto` files in the standard `src/main/proto` directory. diff --git a/wire-gradle-plugin/api/wire-gradle-plugin.api b/wire-gradle-plugin/api/wire-gradle-plugin.api index c947120db2..83f1e7915e 100644 --- a/wire-gradle-plugin/api/wire-gradle-plugin.api +++ b/wire-gradle-plugin/api/wire-gradle-plugin.api @@ -1,11 +1,11 @@ public class com/squareup/wire/gradle/CustomOutput : com/squareup/wire/gradle/WireOutput { public fun ()V - public final fun getExcludes ()Ljava/util/List; - public final fun getExclusive ()Z - public final fun getIncludes ()Ljava/util/List; - public final fun getOptions ()Ljava/util/Map; - public final fun getSchemaHandlerFactory ()Lcom/squareup/wire/schema/SchemaHandler$Factory; - public final fun getSchemaHandlerFactoryClass ()Ljava/lang/String; + public final fun getExcludes ()Lorg/gradle/api/provider/ListProperty; + public final fun getExclusive ()Lorg/gradle/api/provider/Property; + public final fun getIncludes ()Lorg/gradle/api/provider/ListProperty; + public final fun getOptions ()Lorg/gradle/api/provider/MapProperty; + public final fun getSchemaHandlerFactory ()Lorg/gradle/api/provider/Property; + public final fun getSchemaHandlerFactoryClass ()Lorg/gradle/api/provider/Property; public final fun setExcludes (Ljava/util/List;)V public final fun setExclusive (Z)V public final fun setIncludes (Ljava/util/List;)V @@ -160,7 +160,8 @@ public final class com/squareup/wire/gradle/WireExtension$ProtoRootSet { public abstract class com/squareup/wire/gradle/WireOutput { public fun ()V - public final fun getOut ()Ljava/lang/String; + protected fun getObjectFactory ()Lorg/gradle/api/model/ObjectFactory; + public final fun getOut ()Lorg/gradle/api/provider/Property; public final fun setOut (Ljava/lang/String;)V public abstract fun toTarget (Ljava/lang/String;)Lcom/squareup/wire/schema/Target; } diff --git a/wire-gradle-plugin/src/main/kotlin/com/squareup/wire/gradle/WireOutput.kt b/wire-gradle-plugin/src/main/kotlin/com/squareup/wire/gradle/WireOutput.kt index 216f70efa3..a249f1bbf7 100644 --- a/wire-gradle-plugin/src/main/kotlin/com/squareup/wire/gradle/WireOutput.kt +++ b/wire-gradle-plugin/src/main/kotlin/com/squareup/wire/gradle/WireOutput.kt @@ -25,7 +25,14 @@ import com.squareup.wire.schema.ProtoTarget import com.squareup.wire.schema.SchemaHandler import com.squareup.wire.schema.Target import com.squareup.wire.schema.newSchemaHandler +import java.io.File import javax.inject.Inject +import kotlin.LazyThreadSafetyMode.NONE +import org.gradle.api.model.ObjectFactory +import org.gradle.api.provider.ListProperty +import org.gradle.api.provider.MapProperty +import org.gradle.api.provider.Property +import org.gradle.api.provider.Provider /** * Specifies Wire's outputs (expressed as a list of [Target] objects) using Gradle's DSL (expressed @@ -33,8 +40,24 @@ import javax.inject.Inject * directories with the project so they can be compiled after they are generated. */ abstract class WireOutput { + // Gradle decorates this getter for instances created with ObjectFactory.newInstance(). + @get:Inject + protected open val objectFactory: ObjectFactory + get() = throw UnsupportedOperationException("Injected by Gradle") + + val out: Property by lazy(NONE) { + objectFactory.property(String::class.java) + } + /** Set this to override the default output directory for this [WireOutput]. */ - var out: String? = null + fun setOut(value: String?) { + out.set(value) + } + + internal fun outputDirectory( + projectDir: File, + defaultOutputDirectory: Provider, + ): Provider = out.map { relativizeOutputDirectory(it, projectDir) }.orElse(defaultOutputDirectory) /** * Transforms this [WireOutput] into a [Target] for which Wire will generate code. The [Target] @@ -43,6 +66,16 @@ abstract class WireOutput { abstract fun toTarget(outputDirectory: String): Target } +internal fun relativizeOutputDirectory( + outputDirectory: String, + projectDir: File, +): String { + val file = File(outputDirectory) + if (!file.isAbsolute) return outputDirectory + return runCatching { file.relativeTo(projectDir).path } + .getOrElse { outputDirectory } +} + open class JavaOutput @Inject constructor() : WireOutput() { /** See [com.squareup.wire.schema.Target.includes] */ var includes: List? = null @@ -228,40 +261,78 @@ open class ProtoOutput @Inject constructor() : WireOutput() { } open class CustomOutput @Inject constructor() : WireOutput() { + val includes: ListProperty by lazy(NONE) { + objectFactory.listProperty(String::class.java) + } + + val excludes: ListProperty by lazy(NONE) { + objectFactory.listProperty(String::class.java) + } + + val exclusive: Property by lazy(NONE) { + objectFactory.property(Boolean::class.java).convention(true) + } + + val options: MapProperty by lazy(NONE) { + objectFactory.mapProperty(String::class.java, String::class.java) + } + + val schemaHandlerFactory: Property by lazy(NONE) { + objectFactory.property(SchemaHandler.Factory::class.java) + } + + val schemaHandlerFactoryClass: Property by lazy(NONE) { + objectFactory.property(String::class.java) + } + /** See [com.squareup.wire.schema.Target.includes] */ - var includes: List? = null + fun setIncludes(value: List?) { + includes.set(value) + } /** See [com.squareup.wire.schema.Target.excludes] */ - var excludes: List? = null + fun setExcludes(value: List?) { + excludes.set(value) + } /** See [com.squareup.wire.schema.Target.exclusive] */ - var exclusive: Boolean = true + fun setExclusive(value: Boolean) { + exclusive.set(value) + } - /** - * Black boxed payload which a caller can set for the custom [SchemaHandler.Factory] to receive. - */ - var options: Map? = null + /** Black boxed payload which a caller can set for the custom [SchemaHandler.Factory] to receive. */ + fun setOptions(value: Map?) { + options.set(value) + } /** Assign the schema handler factory instance. */ - var schemaHandlerFactory: SchemaHandler.Factory? = null + fun setSchemaHandlerFactory(value: SchemaHandler.Factory?) { + schemaHandlerFactory.set(value) + } /** * Assign the schema handler factory by name. If you use a class name, that class must have a * no-arguments constructor. */ - var schemaHandlerFactoryClass: String? = null + fun setSchemaHandlerFactoryClass(value: String?) { + schemaHandlerFactoryClass.set(value) + } override fun toTarget(outputDirectory: String): CustomTarget { - check((schemaHandlerFactory != null) || (schemaHandlerFactoryClass != null)) { + val configuredSchemaHandlerFactory = schemaHandlerFactory.orNull + val configuredSchemaHandlerFactoryClass = schemaHandlerFactoryClass.orNull + + check(configuredSchemaHandlerFactory != null || configuredSchemaHandlerFactoryClass != null) { "schemaHandlerFactory or schemaHandlerFactoryClass required" } + return CustomTarget( - includes = includes ?: listOf("*"), - excludes = excludes ?: listOf(), - exclusive = exclusive, + includes = includes.orNull ?: listOf("*"), + excludes = excludes.orNull ?: listOf(), + exclusive = exclusive.orElse(true).get(), outDirectory = outputDirectory, - options = options ?: mapOf(), - schemaHandlerFactory = schemaHandlerFactory ?: newSchemaHandler(schemaHandlerFactoryClass!!), + options = options.orNull ?: mapOf(), + schemaHandlerFactory = configuredSchemaHandlerFactory ?: newSchemaHandler(configuredSchemaHandlerFactoryClass!!), ) } } diff --git a/wire-gradle-plugin/src/main/kotlin/com/squareup/wire/gradle/WirePlugin.kt b/wire-gradle-plugin/src/main/kotlin/com/squareup/wire/gradle/WirePlugin.kt index 0c15594121..fbff3d7eba 100644 --- a/wire-gradle-plugin/src/main/kotlin/com/squareup/wire/gradle/WirePlugin.kt +++ b/wire-gradle-plugin/src/main/kotlin/com/squareup/wire/gradle/WirePlugin.kt @@ -19,7 +19,6 @@ import com.squareup.wire.gradle.internal.libraryProtoOutputPath import com.squareup.wire.gradle.internal.protoProjectDependenciesJvmConfiguration import com.squareup.wire.gradle.kotlin.WireSource import com.squareup.wire.gradle.kotlin.forEachWireSource -import com.squareup.wire.schema.ProtoTarget import com.squareup.wire.schema.newEventListenerFactory import com.squareup.wire.wireVersion import java.io.File @@ -85,12 +84,12 @@ class WirePlugin : Plugin { val existingProtoOutput = extension.outputs.get().filterIsInstance().singleOrNull() if (existingProtoOutput != null) { // There exists a `proto {}` target already, we only set the output path if need be. - if (existingProtoOutput.out == null) { - existingProtoOutput.out = File(project.libraryProtoOutputPath()).path + if (!existingProtoOutput.out.isPresent) { + existingProtoOutput.out.set(File(project.libraryProtoOutputPath()).path) } } else { extension.proto { protoOutput -> - protoOutput.out = File(project.libraryProtoOutputPath()).path + protoOutput.out.set(File(project.libraryProtoOutputPath()).path) } } } @@ -134,6 +133,11 @@ class WirePlugin : Plugin { source: WireSource, ) { val outputs = extension.outputs.get() + val nonProtoOutputs = outputs.filterNot { it is ProtoOutput } + val projectDir = project.projectDir + val projectDirectory = project.layout.projectDirectory + val defaultOutputPath = relativizeOutputDirectory(source.outputDir(project).path, projectDir) + val defaultOutputDirectory = project.providers.provider { defaultOutputPath } val protoSourceProtoRootSets = extension.protoSourceProtoRootSets.toMutableList() val protoPathProtoRootSets = extension.protoPathProtoRootSets.toMutableList() @@ -149,11 +153,13 @@ class WirePlugin : Plugin { } } - val targets = outputs.map { - it.toTarget(project.relativePath(it.out ?: source.outputDir(project))) + val targets = project.provider { + outputs.map { output -> + output.toTarget(output.outputDirectory(projectDir, defaultOutputDirectory).get()) + } } - val protoTarget = targets.filterIsInstance().singleOrNull() + val protoOutput = outputs.filterIsInstance().singleOrNull() val taskName = "generate${source.name.replaceFirstChar { it.uppercase() }}Protos" val task = project.tasks.register(taskName, WireTask::class.java) { task: WireTask -> @@ -177,24 +183,23 @@ class WirePlugin : Plugin { } } - targets - // Emitted `.proto` files have a special treatment. Their root should be a resource, not - // a source. We exclude the `ProtoTarget` and we'll add its output to the resources - // below. - .filterNot { it is ProtoTarget }.forEach { target -> - val dir = project.objects.directoryProperty() - dir.set( - project.tasks.named(taskName).map { - project.layout.projectDirectory.dir(target.outDirectory) - }, - ) - task.outputDirectoriesList.add(dir) - } + nonProtoOutputs.forEach { output -> + val dir = project.objects.directoryProperty() + dir.set( + project.tasks.named(taskName).map { + projectDirectory.dir(output.outputDirectory(projectDir, defaultOutputDirectory).get()) + }, + ) + task.outputDirectoriesList.add(dir) + } task.protoSourceConfiguration.setFrom(project.configurations.getByName("protoSource")) task.protoPathConfiguration.setFrom(project.configurations.getByName("protoPath")) task.projectDependenciesJvmConfiguration.setFrom(project.configurations.getByName("protoProjectDependenciesJvm")) - if (protoTarget != null) { - task.protoLibraryOutput.set(project.file(protoTarget.outDirectory)) + if (protoOutput != null) { + task.protoLibraryOutput.set( + protoOutput.outputDirectory(projectDir, defaultOutputDirectory) + .map { projectDirectory.dir(it) }, + ) } task.sourceInput.set(project.provider { protoSourceProtoRootSets.inputLocations }) task.protoInput.set(project.provider { protoPathProtoRootSets.inputLocations }) @@ -219,10 +224,10 @@ class WirePlugin : Plugin { task.eventListenerFactories.set(factories) } - source.registerGeneratedSources(project, task, targets) + source.registerGeneratedSources(project, task, nonProtoOutputs) val protoOutputDirectory = task.map { it.protoLibraryOutput } - if (protoTarget != null) { + if (protoOutput != null) { val sourceSets = project.extensions.getByType(SourceSetContainer::class.java) // Note that there are no source sets for some platforms such as native. // TODO(Benoit) Probably should be checking for other names than `main`. As well, source diff --git a/wire-gradle-plugin/src/main/kotlin/com/squareup/wire/gradle/kotlin/SourceRoots.kt b/wire-gradle-plugin/src/main/kotlin/com/squareup/wire/gradle/kotlin/SourceRoots.kt index c57f7dc400..1bf2a84d84 100644 --- a/wire-gradle-plugin/src/main/kotlin/com/squareup/wire/gradle/kotlin/SourceRoots.kt +++ b/wire-gradle-plugin/src/main/kotlin/com/squareup/wire/gradle/kotlin/SourceRoots.kt @@ -17,13 +17,12 @@ package com.squareup.wire.gradle.kotlin import com.android.build.api.variant.AndroidComponentsExtension import com.android.build.api.variant.Variant +import com.squareup.wire.gradle.CustomOutput +import com.squareup.wire.gradle.JavaOutput +import com.squareup.wire.gradle.KotlinOutput +import com.squareup.wire.gradle.WireOutput import com.squareup.wire.gradle.WireTask import com.squareup.wire.gradle.internal.targetDefaultOutputPath -import com.squareup.wire.schema.CustomTarget -import com.squareup.wire.schema.JavaTarget -import com.squareup.wire.schema.KotlinTarget -import com.squareup.wire.schema.ProtoTarget -import com.squareup.wire.schema.Target import java.io.File import org.gradle.api.Project import org.gradle.api.file.Directory @@ -106,7 +105,7 @@ internal abstract class WireSource( abstract fun registerGeneratedSources( project: Project, wireTask: TaskProvider, - targets: List, + outputs: List, ) } @@ -134,28 +133,25 @@ private class JvmOrKmpSource( override fun registerGeneratedSources( project: Project, wireTask: TaskProvider, - targets: List, + outputs: List, ) { - targets.forEachIndexed { index, target -> + outputs.forEachIndexed { index, output -> val outputDirectory = wireTask.flatMap { it.outputDirectoriesList[index] } - when (target) { - is JavaTarget -> { + when (output) { + is JavaOutput -> { javaSourceDirectorySet?.srcDir(outputDirectory) } - is KotlinTarget -> { + is KotlinOutput -> { registerKotlinGeneratedSources(kotlinSourceSet, outputDirectory) } - is CustomTarget -> { + is CustomOutput -> { // Custom targets are wildcards, so we add all output directories. javaSourceDirectorySet?.srcDir(outputDirectory) registerKotlinGeneratedSources(kotlinSourceSet, outputDirectory) } - is ProtoTarget -> { - // Do nothing - } else -> { throw IllegalArgumentException( - "Wire target ${target::class.simpleName} is not supported in project ${project.path}", + "Wire output ${output::class.simpleName} is not supported in project ${project.path}", ) } } @@ -173,27 +169,24 @@ private class AndroidSource( override fun registerGeneratedSources( project: Project, wireTask: TaskProvider, - targets: List, + outputs: List, ) { - targets.forEachIndexed { index, target -> - when (target) { - is JavaTarget -> { + outputs.forEachIndexed { index, output -> + when (output) { + is JavaOutput -> { variant.sources.java?.addGeneratedSourceDirectory(wireTask) { it.outputDirectoriesList[index] } } - is KotlinTarget -> { + is KotlinOutput -> { variant.sources.kotlin?.addGeneratedSourceDirectory(wireTask) { it.outputDirectoriesList[index] } } - is CustomTarget -> { + is CustomOutput -> { // Custom targets are wildcards, so we add all output directories. variant.sources.java?.addGeneratedSourceDirectory(wireTask) { it.outputDirectoriesList[index] } variant.sources.kotlin?.addGeneratedSourceDirectory(wireTask) { it.outputDirectoriesList[index] } } - is ProtoTarget -> { - // Do nothing - } else -> { throw IllegalArgumentException( - "Wire target ${target::class.simpleName} is not supported in Android project ${project.path}", + "Wire output ${output::class.simpleName} is not supported in Android project ${project.path}", ) } } diff --git a/wire-gradle-plugin/src/test/kotlin/com/squareup/wire/gradle/WireOutputProviderTest.kt b/wire-gradle-plugin/src/test/kotlin/com/squareup/wire/gradle/WireOutputProviderTest.kt new file mode 100644 index 0000000000..b4e0ecf57e --- /dev/null +++ b/wire-gradle-plugin/src/test/kotlin/com/squareup/wire/gradle/WireOutputProviderTest.kt @@ -0,0 +1,123 @@ +/* + * Copyright (C) 2025 Square, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.squareup.wire.gradle + +import assertk.assertThat +import assertk.assertions.containsExactly +import assertk.assertions.isEqualTo +import assertk.assertions.isFalse +import com.squareup.wire.schema.CustomTarget +import com.squareup.wire.schema.Extend +import com.squareup.wire.schema.Field +import com.squareup.wire.schema.SchemaHandler +import com.squareup.wire.schema.Service +import com.squareup.wire.schema.Type +import java.lang.reflect.Modifier +import okio.Path +import org.gradle.testfixtures.ProjectBuilder +import org.junit.Test + +class WireOutputProviderTest { + @Test + fun nestedOutputTypesRemainConcrete() { + assertThat(Modifier.isAbstract(JavaOutput::class.java.modifiers)).isFalse() + assertThat(JavaOutput::class.java.getConstructor().parameterCount).isEqualTo(0) + assertThat(Modifier.isAbstract(KotlinOutput::class.java.modifiers)).isFalse() + assertThat(KotlinOutput::class.java.getConstructor().parameterCount).isEqualTo(0) + assertThat(Modifier.isAbstract(ProtoOutput::class.java.modifiers)).isFalse() + assertThat(ProtoOutput::class.java.getConstructor().parameterCount).isEqualTo(0) + assertThat(Modifier.isAbstract(CustomOutput::class.java.modifiers)).isFalse() + assertThat(CustomOutput::class.java.getConstructor().parameterCount).isEqualTo(0) + } + + @Test + fun customOutputResolvesProviderBackedProperties() { + val project = ProjectBuilder.builder().build() + val output = project.objects.newInstance(CustomOutput::class.java) + + output.out.set(project.providers.provider { "build/generated/custom-wire" }) + output.includes.set(project.providers.provider { listOf("squareup.dinosaurs.Dinosaur") }) + output.excludes.set(project.providers.provider { listOf("squareup.geology.Period") }) + output.exclusive.set(project.providers.provider { false }) + output.options.set(project.providers.provider { mapOf("a" to "one", "b" to "two") }) + output.schemaHandlerFactory.set(TestSchemaHandlerFactory()) + + assertThat(output.out.orNull).isEqualTo("build/generated/custom-wire") + + val target = output.toTarget(output.out.get()) as CustomTarget + + assertThat(target.outDirectory).isEqualTo("build/generated/custom-wire") + assertThat(target.includes).containsExactly("squareup.dinosaurs.Dinosaur") + assertThat(target.excludes).containsExactly("squareup.geology.Period") + assertThat(target.exclusive).isFalse() + assertThat(target.options).isEqualTo(mapOf("a" to "one", "b" to "two")) + assertThat(target.newHandler()::class.java).isEqualTo(TestSchemaHandler::class.java) + } + + @Test + fun customOutputExclusiveFallsBackToConventionWhenProviderIsAbsent() { + val project = ProjectBuilder.builder().build() + val output = project.objects.newInstance(CustomOutput::class.java) + + output.exclusive.set(false) + output.exclusive.set(project.providers.gradleProperty("missing-exclusive").map(String::toBoolean)) + output.schemaHandlerFactory.set(TestSchemaHandlerFactory()) + + val target = output.toTarget("build/generated/custom-wire") as CustomTarget + + assertThat(target.exclusive).isEqualTo(true) + } + + @Test + fun customOutputSettersConfigureNamedProperties() { + val project = ProjectBuilder.builder().build() + val output = project.objects.newInstance(CustomOutput::class.java) + + output.setOut("build/generated/custom-wire") + output.setIncludes(listOf("squareup.dinosaurs.Dinosaur")) + output.setExcludes(listOf("squareup.geology.Period")) + output.setExclusive(false) + output.setOptions(mapOf("a" to "one", "b" to "two")) + output.setSchemaHandlerFactory(TestSchemaHandlerFactory()) + + val target = output.toTarget(output.out.get()) as CustomTarget + + assertThat(target.outDirectory).isEqualTo("build/generated/custom-wire") + assertThat(target.includes).containsExactly("squareup.dinosaurs.Dinosaur") + assertThat(target.excludes).containsExactly("squareup.geology.Period") + assertThat(target.exclusive).isFalse() + assertThat(target.options).isEqualTo(mapOf("a" to "one", "b" to "two")) + assertThat(target.newHandler()::class.java).isEqualTo(TestSchemaHandler::class.java) + } +} + +private class TestSchemaHandlerFactory : SchemaHandler.Factory { + override fun create( + includes: List, + excludes: List, + exclusive: Boolean, + outDirectory: String, + options: Map, + ): SchemaHandler = TestSchemaHandler() +} + +private class TestSchemaHandler : SchemaHandler() { + override fun handle(type: Type, context: Context): Path? = null + + override fun handle(service: Service, context: Context): List = listOf() + + override fun handle(extend: Extend, field: Field, context: Context): Path? = null +} diff --git a/wire-gradle-plugin/src/test/kotlin/com/squareup/wire/gradle/WirePluginTest.kt b/wire-gradle-plugin/src/test/kotlin/com/squareup/wire/gradle/WirePluginTest.kt index dec28cbf65..ff4fc49597 100644 --- a/wire-gradle-plugin/src/test/kotlin/com/squareup/wire/gradle/WirePluginTest.kt +++ b/wire-gradle-plugin/src/test/kotlin/com/squareup/wire/gradle/WirePluginTest.kt @@ -953,6 +953,15 @@ class WirePluginTest { .contains("Couldn't find SchemaHandlerClass 'NoSuchClass'") } + @Test + fun customOutputProviderBackedDsl() { + val fixtureRoot = File("src/test/projects/custom-output-provider-kotlin-dsl") + + val result = fixtureGradleRunner(fixtureRoot).buildAndFail() + assertThat(result.output) + .contains("Couldn't find SchemaHandlerClass 'NoSuchClass'") + } + @Test fun sinceUntil() { val fixtureRoot = File("src/test/projects/since-until") diff --git a/wire-gradle-plugin/src/test/projects/custom-output-provider-kotlin-dsl/build.gradle.kts b/wire-gradle-plugin/src/test/projects/custom-output-provider-kotlin-dsl/build.gradle.kts new file mode 100644 index 0000000000..29b1fb1d77 --- /dev/null +++ b/wire-gradle-plugin/src/test/projects/custom-output-provider-kotlin-dsl/build.gradle.kts @@ -0,0 +1,40 @@ +import com.squareup.wire.gradle.WireExtension + +buildscript { + val wireVersion = gradle.startParameter.projectProperties.getValue("wireVersion") + + dependencies { + classpath("com.squareup.wire:wire-gradle-plugin:$wireVersion") + } + + repositories { + maven { + url = uri(File(rootDir, "../../../../../build/localMaven")) + } + mavenCentral() + google() + } +} + +apply(plugin = "application") +apply(plugin = "com.squareup.wire") + +configure { + sourcePath("src/main/proto") + + custom { + out.set(providers.gradleProperty("wireOut")) + includes.set(providers.provider { listOf(providers.gradleProperty("includeType").get()) }) + excludes.set(providers.provider { listOf(providers.gradleProperty("excludeType").get()) }) + exclusive.set(providers.provider { providers.gradleProperty("exclusive").get().toBoolean() }) + options.set( + providers.provider { + mapOf( + "a" to providers.gradleProperty("optionA").get(), + "b" to providers.gradleProperty("optionB").get(), + ) + }, + ) + schemaHandlerFactoryClass.set(providers.gradleProperty("handlerClass")) + } +} diff --git a/wire-gradle-plugin/src/test/projects/custom-output-provider-kotlin-dsl/gradle.properties b/wire-gradle-plugin/src/test/projects/custom-output-provider-kotlin-dsl/gradle.properties new file mode 100644 index 0000000000..ae036ce6ae --- /dev/null +++ b/wire-gradle-plugin/src/test/projects/custom-output-provider-kotlin-dsl/gradle.properties @@ -0,0 +1,7 @@ +handlerClass=NoSuchClass +wireOut=build/generated/provider-custom-output +includeType=squareup.dinosaurs.Dinosaur +excludeType=squareup.geology.Period +exclusive=true +optionA=one +optionB=two diff --git a/wire-gradle-plugin/src/test/projects/custom-output-provider-kotlin-dsl/settings.gradle.kts b/wire-gradle-plugin/src/test/projects/custom-output-provider-kotlin-dsl/settings.gradle.kts new file mode 100644 index 0000000000..19d12e5ed3 --- /dev/null +++ b/wire-gradle-plugin/src/test/projects/custom-output-provider-kotlin-dsl/settings.gradle.kts @@ -0,0 +1 @@ +rootProject.name = "custom-output-provider-kotlin-dsl" diff --git a/wire-gradle-plugin/src/test/projects/custom-output-provider-kotlin-dsl/src/main/proto/squareup/geology/period.proto b/wire-gradle-plugin/src/test/projects/custom-output-provider-kotlin-dsl/src/main/proto/squareup/geology/period.proto new file mode 100644 index 0000000000..c95691315e --- /dev/null +++ b/wire-gradle-plugin/src/test/projects/custom-output-provider-kotlin-dsl/src/main/proto/squareup/geology/period.proto @@ -0,0 +1,16 @@ +syntax = "proto2"; + +package squareup.geology; + +option java_package = "com.squareup.geology"; + +enum Period { + /** 145.5 million years ago -- 66.0 million years ago. */ + CRETACEOUS = 1; + + /** 201.3 million years ago -- 145.0 million years ago. */ + JURASSIC = 2; + + /** 252.17 million years ago -- 201.3 million years ago. */ + TRIASSIC = 3; +}