diff --git a/samples/android-multi-module/dinosaurs/build.gradle.kts b/samples/android-multi-module/dinosaurs/build.gradle.kts new file mode 100644 index 0000000000..5ff0e679c9 --- /dev/null +++ b/samples/android-multi-module/dinosaurs/build.gradle.kts @@ -0,0 +1,42 @@ +plugins { + id("com.android.library") + id("org.jetbrains.kotlin.android") + id("com.squareup.wire") +} + +buildscript { + repositories { + mavenCentral() + google() + } + dependencies { + classpath(libs.pluginz.android) + classpath("com.squareup.wire:wire-gradle-plugin") + } +} + +android { + namespace = "com.squareup.wire.android.app.multi.dinosaurs" +} + +dependencies { + implementation(libs.androidx.appcompat) + implementation(libs.androidx.constraintLayout) + implementation(libs.androidMaterial) + testImplementation(libs.junit) +} + +wire { + sourcePath { + srcDir("src/main/proto") + } + + sourcePath { + srcProject(":samples:android-multi-module:location") + include("squareup/location/continent.proto") + } + + kotlin { + out = "src/main/kotlin" + } +} diff --git a/samples/android-multi-module/dinosaurs/src/main/proto/squareup/dinosaurs/dinosaur.proto b/samples/android-multi-module/dinosaurs/src/main/proto/squareup/dinosaurs/dinosaur.proto new file mode 100644 index 0000000000..7a0ccbb9d6 --- /dev/null +++ b/samples/android-multi-module/dinosaurs/src/main/proto/squareup/dinosaurs/dinosaur.proto @@ -0,0 +1,21 @@ +syntax = "proto2"; + +package squareup.dinosaurs; + +option java_package = "com.squareup.dinosaurs"; + +import "squareup/geology/period.proto"; +import "squareup/location/continent.proto"; + +message Dinosaur { + /** Common name of this dinosaur, like "Stegosaurus". */ + optional string name = 1; + + /** URLs with images of this dinosaur. */ + repeated string picture_urls = 2; + + optional double length_meters = 3; + optional double mass_kilograms = 4; + optional squareup.geology.Period period = 5; + optional squareup.location.Continent continent = 6; +} diff --git a/samples/android-multi-module/geology/build.gradle.kts b/samples/android-multi-module/geology/build.gradle.kts new file mode 100644 index 0000000000..f56525ba62 --- /dev/null +++ b/samples/android-multi-module/geology/build.gradle.kts @@ -0,0 +1,34 @@ +plugins { + id("com.android.library") + id("org.jetbrains.kotlin.android") + id("com.squareup.wire") +} + +buildscript { + repositories { + mavenCentral() + google() + } + dependencies { + classpath(libs.pluginz.android) + classpath("com.squareup.wire:wire-gradle-plugin") + } +} + +android { + namespace = "com.squareup.wire.android.app.multi.geology" +} + +dependencies { + implementation(libs.androidx.appcompat) + implementation(libs.androidx.constraintLayout) + implementation(libs.androidMaterial) + testImplementation(libs.junit) +} + +wire { + protoLibrary = true + + kotlin { + } +} diff --git a/samples/android-multi-module/geology/src/main/proto/squareup/geology/period.proto b/samples/android-multi-module/geology/src/main/proto/squareup/geology/period.proto new file mode 100644 index 0000000000..fc96fbeb73 --- /dev/null +++ b/samples/android-multi-module/geology/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; +} diff --git a/samples/android-multi-module/location/build.gradle.kts b/samples/android-multi-module/location/build.gradle.kts new file mode 100644 index 0000000000..b2dbf0c475 --- /dev/null +++ b/samples/android-multi-module/location/build.gradle.kts @@ -0,0 +1,55 @@ +plugins { + id("com.android.library") + id("org.jetbrains.kotlin.android") + id("com.squareup.wire") + id("maven-publish") +} + +buildscript { + repositories { + mavenCentral() + google() + } + dependencies { + classpath(libs.pluginz.android) + classpath("com.squareup.wire:wire-gradle-plugin") + } +} + +android { + namespace = "com.squareup.wire.android.app.multi.location" + + publishing { + singleVariant("debug") { + withSourcesJar() + } + } +} + +publishing { + publications { + create("debug", MavenPublication::class.java) { + groupId = "com.my-company" + artifactId = "my-library" + version = "1.0" + + afterEvaluate { + from(components.getByName("debug")) + } + } + } +} + +dependencies { + implementation(libs.androidx.appcompat) + implementation(libs.androidx.constraintLayout) + implementation(libs.androidMaterial) + testImplementation(libs.junit) +} + +wire { + protoLibrary = true + + kotlin { + } +} diff --git a/samples/android-multi-module/location/src/main/kotlin/london/Main.kt b/samples/android-multi-module/location/src/main/kotlin/london/Main.kt new file mode 100644 index 0000000000..5da1f61064 --- /dev/null +++ b/samples/android-multi-module/location/src/main/kotlin/london/Main.kt @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2024 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 london + +fun main() { + println("hello") +} diff --git a/samples/android-multi-module/location/src/main/proto/squareup/location/continent.proto b/samples/android-multi-module/location/src/main/proto/squareup/location/continent.proto new file mode 100644 index 0000000000..9de47d2bb2 --- /dev/null +++ b/samples/android-multi-module/location/src/main/proto/squareup/location/continent.proto @@ -0,0 +1,14 @@ +syntax = "proto2"; + +package squareup.location; + +option java_package = "com.squareup.location"; + +enum Continent { + AFRICA = 0; + AMERICA = 1; + ANTARCTICA = 2; + ASIA = 3; + AUSTRALIA = 4; + EUROPE = 5; +} diff --git a/samples/android-multi-module/location/src/main/proto/squareup/location/planet.proto b/samples/android-multi-module/location/src/main/proto/squareup/location/planet.proto new file mode 100644 index 0000000000..6b68394cbd --- /dev/null +++ b/samples/android-multi-module/location/src/main/proto/squareup/location/planet.proto @@ -0,0 +1,16 @@ +syntax = "proto2"; + +package squareup.location; + +option java_package = "com.squareup.location"; + +enum Planet { + MERCURY = 0; + VENUS = 1; + EARTH = 2; + MARS = 3; + JUPITER = 4; + SATURN = 5; + URANUS = 6; + NEPTUNE = 7; +} diff --git a/samples/multi-platform-multi-module/dinosaurs-native/build.gradle.kts b/samples/multi-platform-multi-module/dinosaurs-native/build.gradle.kts new file mode 100644 index 0000000000..426b718595 --- /dev/null +++ b/samples/multi-platform-multi-module/dinosaurs-native/build.gradle.kts @@ -0,0 +1,46 @@ +plugins { + kotlin("multiplatform") + id("com.squareup.wire") +} + +kotlin { + val hostOs = System.getProperty("os.name") + val isMingwX64 = hostOs.startsWith("Windows") + val nativeTarget = when { + hostOs == "Mac OS X" -> macosX64("native") + hostOs == "Linux" -> linuxX64("native") + isMingwX64 -> mingwX64("native") + else -> throw GradleException("Host OS is not supported in Kotlin/Native.") + } + + nativeTarget.apply { + binaries { + executable { + entryPoint = "main" + } + } + } + sourceSets { + val commonMain by getting + val nativeMain by getting + val nativeTest by getting + } +} + +dependencies { + protoPath(project(":samples:multi-platform-multi-module:geology-native")) +} + +wire { + sourcePath { + srcDir("src/main/proto") + } + + sourcePath { + srcProject(":samples:multi-platform-multi-module:location-js") + include("squareup/location/continent.proto") + } + + kotlin { + } +} diff --git a/samples/multi-platform-multi-module/dinosaurs-native/src/main/proto/squareup/dinosaurs/dinosaur.proto b/samples/multi-platform-multi-module/dinosaurs-native/src/main/proto/squareup/dinosaurs/dinosaur.proto new file mode 100644 index 0000000000..7a0ccbb9d6 --- /dev/null +++ b/samples/multi-platform-multi-module/dinosaurs-native/src/main/proto/squareup/dinosaurs/dinosaur.proto @@ -0,0 +1,21 @@ +syntax = "proto2"; + +package squareup.dinosaurs; + +option java_package = "com.squareup.dinosaurs"; + +import "squareup/geology/period.proto"; +import "squareup/location/continent.proto"; + +message Dinosaur { + /** Common name of this dinosaur, like "Stegosaurus". */ + optional string name = 1; + + /** URLs with images of this dinosaur. */ + repeated string picture_urls = 2; + + optional double length_meters = 3; + optional double mass_kilograms = 4; + optional squareup.geology.Period period = 5; + optional squareup.location.Continent continent = 6; +} diff --git a/samples/multi-platform-multi-module/geology-native/build.gradle.kts b/samples/multi-platform-multi-module/geology-native/build.gradle.kts new file mode 100644 index 0000000000..2734320c3b --- /dev/null +++ b/samples/multi-platform-multi-module/geology-native/build.gradle.kts @@ -0,0 +1,35 @@ +plugins { + kotlin("multiplatform") + id("com.squareup.wire") +} + +kotlin { + val hostOs = System.getProperty("os.name") + val isMingwX64 = hostOs.startsWith("Windows") + val nativeTarget = when { + hostOs == "Mac OS X" -> macosX64("native") + hostOs == "Linux" -> linuxX64("native") + isMingwX64 -> mingwX64("native") + else -> throw GradleException("Host OS is not supported in Kotlin/Native.") + } + + nativeTarget.apply { + binaries { + executable { + entryPoint = "main" + } + } + } + sourceSets { + val commonMain by getting + val nativeMain by getting + val nativeTest by getting + } +} + +wire { + protoLibrary = true + + kotlin { + } +} diff --git a/samples/multi-platform-multi-module/geology-native/src/main/proto/squareup/geology/period.proto b/samples/multi-platform-multi-module/geology-native/src/main/proto/squareup/geology/period.proto new file mode 100644 index 0000000000..fc96fbeb73 --- /dev/null +++ b/samples/multi-platform-multi-module/geology-native/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; +} diff --git a/samples/multi-platform-multi-module/location-js/build.gradle.kts b/samples/multi-platform-multi-module/location-js/build.gradle.kts new file mode 100644 index 0000000000..8e40edfb34 --- /dev/null +++ b/samples/multi-platform-multi-module/location-js/build.gradle.kts @@ -0,0 +1,30 @@ +plugins { + kotlin("js") + id("com.squareup.wire") +} + +repositories { + mavenCentral() +} + +kotlin { + js(IR) { + binaries.executable() + browser { + commonWebpackConfig { + cssSupport { + enabled.set(true) + } + } + } + nodejs { + } + } +} + +wire { + protoLibrary = true + + kotlin { + } +} diff --git a/samples/multi-platform-multi-module/location-js/src/main/proto/squareup/location/continent.proto b/samples/multi-platform-multi-module/location-js/src/main/proto/squareup/location/continent.proto new file mode 100644 index 0000000000..9de47d2bb2 --- /dev/null +++ b/samples/multi-platform-multi-module/location-js/src/main/proto/squareup/location/continent.proto @@ -0,0 +1,14 @@ +syntax = "proto2"; + +package squareup.location; + +option java_package = "com.squareup.location"; + +enum Continent { + AFRICA = 0; + AMERICA = 1; + ANTARCTICA = 2; + ASIA = 3; + AUSTRALIA = 4; + EUROPE = 5; +} diff --git a/samples/multi-platform-multi-module/location-js/src/main/proto/squareup/location/planet.proto b/samples/multi-platform-multi-module/location-js/src/main/proto/squareup/location/planet.proto new file mode 100644 index 0000000000..6b68394cbd --- /dev/null +++ b/samples/multi-platform-multi-module/location-js/src/main/proto/squareup/location/planet.proto @@ -0,0 +1,16 @@ +syntax = "proto2"; + +package squareup.location; + +option java_package = "com.squareup.location"; + +enum Planet { + MERCURY = 0; + VENUS = 1; + EARTH = 2; + MARS = 3; + JUPITER = 4; + SATURN = 5; + URANUS = 6; + NEPTUNE = 7; +} diff --git a/settings.gradle.kts b/settings.gradle.kts index 1740430e13..626aeac993 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -44,7 +44,7 @@ include(":wire-bom") include(":wire-compiler") include(":wire-golden-files") include(":wire-gradle-plugin") -include(":wire-gradle-plugin-playground") +// include(":wire-gradle-plugin-playground") include(":wire-grpc-client") include(":wire-grpc-mockwebserver") include(":wire-grpc-tests") @@ -69,17 +69,28 @@ if (startParameter.projectProperties.get("swift") != "false") { include(":wire-tests-swift:manifest:module_three") include(":wire-tests-proto3-swift") } -include(":samples:android-app-java-sample") -include(":samples:android-app-kotlin-sample") -include(":samples:android-app-kotlin-minsdk-sample") -include(":samples:android-app-variants-sample") -include(":samples:android-lib-java-sample") -include(":samples:android-lib-kotlin-sample") -include(":samples:js") -include(":samples:multi-target") -include(":samples:native") -include(":samples:simple-sample") -include(":samples:wire-codegen-sample") -include(":samples:wire-grpc-sample:client") -include(":samples:wire-grpc-sample:protos") -include(":samples:wire-grpc-sample:server") + +// include(":samples:simple-sample") +// include(":samples:android-app-java-sample") +// include(":samples:android-app-kotlin-sample") +// include(":samples:android-app-variants-sample") +// include(":samples:android-lib-java-sample") +// include(":samples:android-lib-kotlin-sample") +// include(":samples:js") +// include(":samples:multi-platform-multi-module:dinosaurs-native") +// include(":samples:multi-platform-multi-module:geology-native") +// include(":samples:multi-platform-multi-module:location-js") +include(":samples:android-multi-module:dinosaurs") +include(":samples:android-multi-module:geology") +include(":samples:android-multi-module:location") +// include(":samples:native") +// include(":samples:wire-codegen-sample") +// include(":samples:wire-grpc-sample:client") +// include(":samples:wire-grpc-sample:protos") +// include(":samples:wire-grpc-sample:server") +// include(":samples:wire-grpc-sample:server-plain") +// include(":wire-benchmarks") +// include(":wire-golden-files") +// include(":wire-gradle-plugin-playground") +// include(":wire-grpc-tests") +// include(":wire-protoc-compatibility-tests") diff --git a/wire-gradle-plugin/src/main/kotlin/com/squareup/wire/gradle/WireExtension.kt b/wire-gradle-plugin/src/main/kotlin/com/squareup/wire/gradle/WireExtension.kt index 7b75579b1d..23239ceec0 100644 --- a/wire-gradle-plugin/src/main/kotlin/com/squareup/wire/gradle/WireExtension.kt +++ b/wire-gradle-plugin/src/main/kotlin/com/squareup/wire/gradle/WireExtension.kt @@ -15,8 +15,11 @@ */ package com.squareup.wire.gradle +import com.android.build.api.attributes.BuildTypeAttr +import com.android.build.gradle.internal.attributes.VariantAttr import com.squareup.wire.schema.EventListener import java.io.File +import java.io.Serializable import org.gradle.api.Action import org.gradle.api.Project import org.gradle.api.artifacts.MinimalExternalModuleDependency @@ -24,6 +27,7 @@ import org.gradle.api.internal.catalog.DelegatingProjectDependency import org.gradle.api.internal.file.FileOrUriNotationConverter import org.gradle.api.provider.Provider import org.gradle.api.provider.ProviderConvertible +import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType open class WireExtension( private val project: Project, @@ -285,6 +289,12 @@ open class WireExtension( .apply { isCanBeConsumed = false isTransitive = false + attributes { attributesContainer -> + attributesContainer.attribute( + BuildTypeAttr.ATTRIBUTE, + project.objects.named(BuildTypeAttr::class.java, "debug") + ) + } } internal val sourceDirectoriesAndLocalJars = mutableListOf() 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 cb5d546814..a231c46612 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 @@ -17,6 +17,8 @@ package com.squareup.wire.gradle +import java.lang.reflect.Array as JavaArray +import com.android.build.api.attributes.BuildTypeAttr import com.squareup.wire.VERSION import com.squareup.wire.gradle.internal.libraryProtoOutputPath import com.squareup.wire.gradle.internal.targetDefaultOutputPath @@ -26,7 +28,6 @@ import com.squareup.wire.schema.ProtoTarget import com.squareup.wire.schema.Target import com.squareup.wire.schema.newEventListenerFactory import java.io.File -import java.lang.reflect.Array as JavaArray import java.util.concurrent.atomic.AtomicBoolean import org.gradle.api.Plugin import org.gradle.api.Project @@ -37,6 +38,7 @@ import org.gradle.api.tasks.SourceSetContainer import org.gradle.api.tasks.compile.JavaCompile import org.jetbrains.kotlin.gradle.dsl.KotlinJsProjectExtension import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension +import org.jetbrains.kotlin.gradle.dsl.KotlinProjectExtension import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType import org.jetbrains.kotlin.gradle.plugin.sources.DefaultKotlinSourceSet import org.jetbrains.kotlin.gradle.tasks.AbstractKotlinCompile @@ -68,7 +70,11 @@ class WirePlugin : Plugin { // TODO(Benoit) If another project, on which this one depends, exposes multiple variants, // Wire won't be able to pick one. We force the resolution to JVM. On the other hand, this // breaks inter-module dependencies for non-jvm modules. We need to fix it. - attributesContainer.attribute(KotlinPlatformType.attribute, KotlinPlatformType.jvm) + attributesContainer.attribute(KotlinPlatformType.attribute, KotlinPlatformType.androidJvm) + attributesContainer.attribute( + BuildTypeAttr.ATTRIBUTE, + project.objects.named(BuildTypeAttr::class.java, "debug"), + ) } } @@ -120,7 +126,8 @@ class WirePlugin : Plugin { val protoSourceConfiguration = project.configurations.getByName("protoSource") val protoPathConfiguration = project.configurations.getByName("protoPath") - val projectDependenciesJvmConfiguration = project.configurations.getByName("protoProjectDependenciesJvm") + val projectDependenciesJvmConfiguration = + project.configurations.getByName("protoProjectDependenciesJvm") val outputs = extension.outputs check(outputs.isNotEmpty()) { @@ -258,7 +265,8 @@ class WirePlugin : Plugin { task.projectDirProperty.set(project.layout.projectDirectory) task.buildDirProperty.set(project.layout.buildDirectory) - val factories = extension.eventListenerFactories + extension.eventListenerFactoryClasses().map(::newEventListenerFactory) + val factories = extension.eventListenerFactories + extension.eventListenerFactoryClasses() + .map(::newEventListenerFactory) task.eventListenerFactories.set(factories) } @@ -271,17 +279,27 @@ class WirePlugin : Plugin { val protoOutputDirectory = task.map { it.protoLibraryOutput } if (extension.protoLibrary) { - 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 - // sets might be created 'afterEvaluate'. Does that mean we should do this work in - // `afterEvaluate` as well? See: https://kotlinlang.org/docs/multiplatform-dsl-reference.html#source-sets - if (sourceSets.findByName("main") != null) { - sourceSets.getByName("main") { main: SourceSet -> - main.resources.srcDir(protoOutputDirectory) + val sourceContainerNames = project.extensions.extensionsSchema.map { it.name } + sourceContainerNames.forEach { sourceContainerName -> + val extension = project.extensions.getByName(sourceContainerName) + when (extension) { + is SourceSetContainer -> { + extension.findByName("main")?.let { main: SourceSet -> + main.resources.srcDir(protoOutputDirectory) + } + } + + is KotlinProjectExtension -> { + extension.sourceSets.findByName("main")?.resources?.srcDir(protoOutputDirectory) + } + + else -> { + project.logger.warn( + "${project.displayName} doesn't have a 'main' source sets. The .proto files will not automatically be added to the artifact.", + ) + } } - } else { - project.logger.warn("${project.displayName} doesn't have a 'main' source sets. The .proto files will not automatically be added to the artifact.") + (project.extensions.getByName("kotlin") as? KotlinProjectExtension)?.sourceSets } }