From 01b94b1c4c07dcdde87c82c30e3ce42b666d78bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Quenaudon?= Date: Wed, 22 Jul 2026 08:07:14 +0100 Subject: [PATCH] Gradle plugin: register generated sources for third-party WireOutput subclasses SourceRoots matched on the built-in output classes and threw "Wire output X is not supported" for any other WireOutput subclass, breaking plugins that add their own outputs (a regression from Wire 6, which dispatched on the produced Target and supported CustomTarget from any output). Treat unknown outputs like CustomOutput: their targets are wildcards, so register the output directory on both the Java and Kotlin source sets. Co-Authored-By: Claude Fable 5 --- .../wire/gradle/kotlin/SourceRoots.kt | 19 ++----- .../squareup/wire/gradle/WirePluginTest.kt | 9 ++++ .../projects/third-party-output/build.gradle | 53 +++++++++++++++++++ .../third-party-output/settings.gradle | 9 ++++ .../main/proto/squareup/geology/period.proto | 16 ++++++ 5 files changed, 91 insertions(+), 15 deletions(-) create mode 100644 wire-gradle-plugin/src/test/projects/third-party-output/build.gradle create mode 100644 wire-gradle-plugin/src/test/projects/third-party-output/settings.gradle create mode 100644 wire-gradle-plugin/src/test/projects/third-party-output/src/main/proto/squareup/geology/period.proto 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 c47a35dae5..1c0505b633 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,7 +17,6 @@ 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 @@ -144,16 +143,11 @@ private class JvmOrKmpSource( is KotlinOutput -> { registerKotlinGeneratedSources(kotlinSourceSet, outputDirectory) } - is CustomOutput -> { - // Custom targets are wildcards, so we add all output directories. + else -> { + // Custom and third-party outputs are wildcards, so we add all output directories. javaSourceDirectorySet?.srcDir(outputDirectory) registerKotlinGeneratedSources(kotlinSourceSet, outputDirectory) } - else -> { - throw IllegalArgumentException( - "Wire output ${output::class.simpleName} is not supported in project ${project.path}", - ) - } } } } @@ -181,16 +175,11 @@ private class AndroidSource( // Registering with variant.sources.kotlin can hide handwritten sources from KSP. variant.sources.java?.addGeneratedSourceDirectory(wireTask) { it.outputDirectoriesList[index] } } - is CustomOutput -> { - // Custom targets are wildcards, so we add all output directories. + else -> { + // Custom and third-party outputs are wildcards, so we add all output directories. variant.sources.java?.addGeneratedSourceDirectory(wireTask) { it.outputDirectoriesList[index] } variant.sources.kotlin?.addGeneratedSourceDirectory(wireTask) { it.outputDirectoriesList[index] } } - else -> { - throw IllegalArgumentException( - "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/WirePluginTest.kt b/wire-gradle-plugin/src/test/kotlin/com/squareup/wire/gradle/WirePluginTest.kt index 5565e19e48..b4432765dd 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 @@ -954,6 +954,15 @@ class WirePluginTest { .contains("Couldn't find SchemaHandlerClass 'NoSuchClass'") } + @Test + fun thirdPartyOutputRegistersGeneratedSources() { + val fixtureRoot = File("src/test/projects/third-party-output") + + val result = fixtureGradleRunner(fixtureRoot, "printSourceDirs").build() + assertThat(result.task(":printSourceDirs")).isNotNull() + assertThat(result.output).contains("generated${File.separator}thirdParty") + } + @Test fun customOutputProviderBackedDsl() { val fixtureRoot = File("src/test/projects/custom-output-provider-kotlin-dsl") diff --git a/wire-gradle-plugin/src/test/projects/third-party-output/build.gradle b/wire-gradle-plugin/src/test/projects/third-party-output/build.gradle new file mode 100644 index 0000000000..1e1eec8102 --- /dev/null +++ b/wire-gradle-plugin/src/test/projects/third-party-output/build.gradle @@ -0,0 +1,53 @@ +import com.squareup.wire.gradle.WireOutput +import com.squareup.wire.schema.CustomTarget +import com.squareup.wire.schema.SchemaHandler +import com.squareup.wire.schema.Target +import org.jetbrains.annotations.NotNull + +buildscript { + dependencies { + classpath "com.squareup.wire:wire-gradle-plugin:$wireVersion" + } + + repositories { + maven { + url new File(rootDir, "../../../../../build/localMaven").toURI().toString() + } + mavenCentral() + google() + } +} + +apply plugin: 'application' +apply plugin: 'com.squareup.wire' + +class ThirdPartyHandlerFactory implements SchemaHandler.Factory { + @Override + SchemaHandler create(@NotNull List includes, @NotNull List excludes, + boolean exclusive, @NotNull String outDirectory, @NotNull Map options) { + throw new RuntimeException("this test only configures the project; the handler never runs") + } +} + +// A third-party WireOutput subclass, as plugins building on top of Wire define them. +abstract class ThirdPartyOutput extends WireOutput { + @Override + Target toTarget(String outputDirectory) { + return new CustomTarget(['*'], [], false, outputDirectory, [:], new ThirdPartyHandlerFactory()) + } +} + +wire { + sourcePath 'src/main/proto' +} + +def thirdPartyOutput = project.objects.newInstance(ThirdPartyOutput) +thirdPartyOutput.setOut("${buildDir}/generated/thirdParty") +wire.outputs.add(thirdPartyOutput) + +tasks.register('printSourceDirs') { + def srcDirs = project.provider { sourceSets.main.java.srcDirs } + doLast { + println "sourceDirs: ${srcDirs.get()}" + } +} diff --git a/wire-gradle-plugin/src/test/projects/third-party-output/settings.gradle b/wire-gradle-plugin/src/test/projects/third-party-output/settings.gradle new file mode 100644 index 0000000000..9ab26fd3ef --- /dev/null +++ b/wire-gradle-plugin/src/test/projects/third-party-output/settings.gradle @@ -0,0 +1,9 @@ +include ':' + +dependencyResolutionManagement { + versionCatalogs { + libs { + from(files('../../../../../gradle/libs.versions.toml')) + } + } +} diff --git a/wire-gradle-plugin/src/test/projects/third-party-output/src/main/proto/squareup/geology/period.proto b/wire-gradle-plugin/src/test/projects/third-party-output/src/main/proto/squareup/geology/period.proto new file mode 100644 index 0000000000..fc96fbeb73 --- /dev/null +++ b/wire-gradle-plugin/src/test/projects/third-party-output/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; +}