diff --git a/.github/workflows/android.yml b/.github/workflows/android.yml index 8a635beff..f89439480 100644 --- a/.github/workflows/android.yml +++ b/.github/workflows/android.yml @@ -16,11 +16,12 @@ jobs: java-version: 17 - name: Setup Gradle uses: gradle/gradle-build-action@v2 + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: 22 - name: Check Snippets run: python scripts/checksnippets.py - # TODO(thatfiredev): remove this once github.com/firebase/quickstart-android/issues/1672 is fixed - - name: Remove Firebase Data Connect from CI - run: python scripts/ci_remove_fdc.py - name: Copy mock google_services.json run: ./copy_mock_google_services_json.sh - name: Build with Gradle (Pull Request) diff --git a/dataconnect/app/build.gradle.kts b/dataconnect/app/build.gradle.kts index 2abc8043f..a5cc12e77 100644 --- a/dataconnect/app/build.gradle.kts +++ b/dataconnect/app/build.gradle.kts @@ -4,6 +4,7 @@ plugins { alias(libs.plugins.kotlin.serialization) alias(libs.plugins.google.services) alias(libs.plugins.compose.compiler) + id("com.google.firebase.example.dataconnect.gradle") } android { @@ -50,13 +51,9 @@ android { excludes += "/META-INF/{AL2.0,LGPL2.1}" } } - sourceSets.getByName("main") { - java.srcDirs("build/generated/sources") - } } dependencies { - implementation(libs.androidx.core.ktx) implementation(libs.androidx.lifecycle.runtime.ktx) implementation(libs.androidx.lifecycle.viewmodel.compose) @@ -83,3 +80,13 @@ dependencies { debugImplementation(libs.androidx.ui.tooling) debugImplementation(libs.androidx.ui.test.manifest) } + +dataconnect { + // The version of https://www.npmjs.com/package/firebase-tools to use to perform the + // Data Connect code generation. + firebaseToolsVersion = "13.23.0" + + // The directory that contains dataconnect.yaml to use as input when performing + // the Data Connect code generation. + dataConnectConfigDir = file("../dataconnect") +} diff --git a/dataconnect/buildSrc/build.gradle.kts b/dataconnect/buildSrc/build.gradle.kts new file mode 100644 index 000000000..36b9fb605 --- /dev/null +++ b/dataconnect/buildSrc/build.gradle.kts @@ -0,0 +1,45 @@ +/* + * Copyright 2024 Google LLC + * + * 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 + * + * http://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. + */ + +plugins { + // See https://docs.gradle.org/current/userguide/kotlin_dsl.html#sec:kotlin-dsl_plugin + `kotlin-dsl` + alias(libs.plugins.spotless) +} + +java { toolchain { languageVersion.set(JavaLanguageVersion.of(17)) } } + +dependencies { + implementation(libs.android.gradlePlugin.api) + implementation(libs.snakeyaml) +} + +gradlePlugin { + plugins { + create("dataconnect") { + id = "com.google.firebase.example.dataconnect.gradle" + implementationClass = "com.google.firebase.example.dataconnect.gradle.DataConnectGradlePlugin" + } + } +} + +spotless { + kotlin { ktfmt(libs.versions.ktfmt.get()).googleStyle() } + kotlinGradle { + target("*.gradle.kts") + ktfmt(libs.versions.ktfmt.get()).googleStyle() + } +} diff --git a/dataconnect/buildSrc/settings.gradle.kts b/dataconnect/buildSrc/settings.gradle.kts new file mode 100644 index 000000000..89a5d455e --- /dev/null +++ b/dataconnect/buildSrc/settings.gradle.kts @@ -0,0 +1,15 @@ +pluginManagement { + repositories { + gradlePluginPortal() + google() + mavenCentral() + } +} + +dependencyResolutionManagement { + repositories { + google() + mavenCentral() + } + versionCatalogs { create("libs") { from(files("../../gradle/libs.versions.toml")) } } +} diff --git a/dataconnect/buildSrc/src/main/kotlin/com/google/firebase/example/dataconnect/gradle/CodegenTask.kt b/dataconnect/buildSrc/src/main/kotlin/com/google/firebase/example/dataconnect/gradle/CodegenTask.kt new file mode 100644 index 000000000..90dedc587 --- /dev/null +++ b/dataconnect/buildSrc/src/main/kotlin/com/google/firebase/example/dataconnect/gradle/CodegenTask.kt @@ -0,0 +1,75 @@ +/* + * Copyright 2024 Google LLC + * + * 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 + * + * http://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.google.firebase.example.dataconnect.gradle + +import java.io.File +import org.gradle.api.DefaultTask +import org.gradle.api.file.DirectoryProperty +import org.gradle.api.file.RegularFileProperty +import org.gradle.api.tasks.InputDirectory +import org.gradle.api.tasks.InputFile +import org.gradle.api.tasks.Internal +import org.gradle.api.tasks.OutputDirectory +import org.gradle.api.tasks.TaskAction + +abstract class CodegenTask : DefaultTask() { + + @get:InputDirectory abstract val dataConnectConfigDir: DirectoryProperty + + @get:InputFile abstract val firebaseExecutable: RegularFileProperty + + @get:OutputDirectory abstract val outputDirectory: DirectoryProperty + + @get:Internal abstract val tweakedDataConnectConfigDir: DirectoryProperty + + @TaskAction + fun run() { + val dataConnectConfigDir = dataConnectConfigDir.get().asFile + val firebaseExecutable = firebaseExecutable.get().asFile + val outputDirectory = outputDirectory.get().asFile + val tweakedDataConnectConfigDir = tweakedDataConnectConfigDir.get().asFile + + logger.info("dataConnectConfigDir: {}", dataConnectConfigDir) + logger.info("firebaseExecutable: {}", firebaseExecutable) + logger.info("outputDirectory: {}", outputDirectory) + logger.info("tweakedDataConnectConfigDir: {}", tweakedDataConnectConfigDir) + + project.delete(outputDirectory) + project.delete(tweakedDataConnectConfigDir) + project.mkdir(tweakedDataConnectConfigDir) + + project.copy { + from(dataConnectConfigDir) + into(tweakedDataConnectConfigDir) + } + tweakConnectorYamlFiles(tweakedDataConnectConfigDir, outputDirectory.absolutePath) + + runCommand(File(tweakedDataConnectConfigDir, "generate.log.txt")) { + commandLine(firebaseExecutable.absolutePath, "--debug", "dataconnect:sdk:generate") + // Specify a fake project because dataconnect:sdk:generate unnecessarily + // requires one. The actual value does not matter. + args("--project", "zzyzx") + workingDir(tweakedDataConnectConfigDir) + } + } + + internal fun configureFrom(providers: MyVariantProviders) { + dataConnectConfigDir.set(providers.dataConnectConfigDir) + firebaseExecutable.set(providers.firebaseExecutable) + tweakedDataConnectConfigDir.set(providers.buildDirectory.map { it.dir("config") }) + } +} diff --git a/dataconnect/buildSrc/src/main/kotlin/com/google/firebase/example/dataconnect/gradle/Commands.kt b/dataconnect/buildSrc/src/main/kotlin/com/google/firebase/example/dataconnect/gradle/Commands.kt new file mode 100644 index 000000000..0a53b06ae --- /dev/null +++ b/dataconnect/buildSrc/src/main/kotlin/com/google/firebase/example/dataconnect/gradle/Commands.kt @@ -0,0 +1,42 @@ +/* + * Copyright 2024 Google LLC + * + * 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 + * + * http://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.google.firebase.example.dataconnect.gradle + +import java.io.File +import org.gradle.api.Task +import org.gradle.process.ExecSpec + +internal fun Task.runCommand(logFile: File, configure: ExecSpec.() -> Unit) { + val effectiveLogFile = if (logger.isInfoEnabled) null else logFile + val result = + effectiveLogFile?.outputStream().use { logStream -> + project.runCatching { + exec { + isIgnoreExitValue = false + if (logStream !== null) { + standardOutput = logStream + errorOutput = logStream + } + configure(this) + } + } + } + result.onFailure { exception -> + effectiveLogFile?.let { logger.warn("{}", it.readText()) } + throw exception + } +} diff --git a/dataconnect/buildSrc/src/main/kotlin/com/google/firebase/example/dataconnect/gradle/ConnectorYamlTweaking.kt b/dataconnect/buildSrc/src/main/kotlin/com/google/firebase/example/dataconnect/gradle/ConnectorYamlTweaking.kt new file mode 100644 index 000000000..fbd9dcf09 --- /dev/null +++ b/dataconnect/buildSrc/src/main/kotlin/com/google/firebase/example/dataconnect/gradle/ConnectorYamlTweaking.kt @@ -0,0 +1,89 @@ +/* + * Copyright 2024 Google LLC + * + * 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 + * + * http://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.google.firebase.example.dataconnect.gradle + +import java.io.File +import org.gradle.api.GradleException +import org.gradle.api.Task +import org.yaml.snakeyaml.Yaml + +internal fun Task.tweakConnectorYamlFiles(dir: File, newOutputDir: String) { + logger.info("Tweaking connector.yaml files in {}", dir.absolutePath) + dir.walk().forEach { file -> + if (file.isFile && file.name == "connector.yaml") { + tweakConnectorYamlFile(file, newOutputDir) + } else { + logger.debug("skipping file: {}", file.absolutePath) + } + } +} + +internal fun Task.tweakConnectorYamlFile(file: File, newOutputDir: String) { + logger.info("Tweaking connector.yaml file: {}", file.absolutePath) + + fun Map<*, *>.withTweakedKotlinSdk() = + filterKeys { it == "kotlinSdk" } + .mapValues { (_, value) -> + val kotlinSdkMap = + value as? Map<*, *> + ?: throw GradleException( + "Parsing ${file.absolutePath} failed: \"kotlinSdk\" is " + + (if (value === null) "null" else value::class.qualifiedName) + + ", but expected ${Map::class.qualifiedName} " + + "(error code m697s27yxn)" + ) + kotlinSdkMap.mapValues { (key, value) -> + if (key == "outputDir") { + newOutputDir + } else { + value + } + } + } + + fun Map<*, *>.withTweakedGenerateNode() = mapValues { (key, value) -> + if (key != "generate") { + value + } else { + val generateMap = + value as? Map<*, *> + ?: throw GradleException( + "Parsing ${file.absolutePath} failed: \"generate\" is " + + (if (value === null) "null" else value::class.qualifiedName) + + ", but expected ${Map::class.qualifiedName} " + + "(error code 9c2p857gq6)" + ) + generateMap.withTweakedKotlinSdk() + } + } + + val yaml = Yaml() + val rootObject = file.reader(Charsets.UTF_8).use { reader -> yaml.load(reader) } + + val rootMap = + rootObject as? Map<*, *> + ?: throw GradleException( + "Parsing ${file.absolutePath} failed: root is " + + (if (rootObject === null) "null" else rootObject::class.qualifiedName) + + ", but expected ${Map::class.qualifiedName} " + + "(error code 45dw8jx8jd)" + ) + + val newRootMap = rootMap.withTweakedGenerateNode() + + file.writer(Charsets.UTF_8).use { writer -> yaml.dump(newRootMap, writer) } +} diff --git a/dataconnect/buildSrc/src/main/kotlin/com/google/firebase/example/dataconnect/gradle/DataConnectExtension.kt b/dataconnect/buildSrc/src/main/kotlin/com/google/firebase/example/dataconnect/gradle/DataConnectExtension.kt new file mode 100644 index 000000000..7dadff6d7 --- /dev/null +++ b/dataconnect/buildSrc/src/main/kotlin/com/google/firebase/example/dataconnect/gradle/DataConnectExtension.kt @@ -0,0 +1,24 @@ +/* + * Copyright 2024 Google LLC + * + * 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 + * + * http://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.google.firebase.example.dataconnect.gradle + +import java.io.File + +interface DataConnectExtension { + var firebaseToolsVersion: String? + var dataConnectConfigDir: File? +} diff --git a/dataconnect/buildSrc/src/main/kotlin/com/google/firebase/example/dataconnect/gradle/DataConnectGradlePlugin.kt b/dataconnect/buildSrc/src/main/kotlin/com/google/firebase/example/dataconnect/gradle/DataConnectGradlePlugin.kt new file mode 100644 index 000000000..57403344c --- /dev/null +++ b/dataconnect/buildSrc/src/main/kotlin/com/google/firebase/example/dataconnect/gradle/DataConnectGradlePlugin.kt @@ -0,0 +1,63 @@ +/* + * Copyright 2024 Google LLC + * + * 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 + * + * http://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.google.firebase.example.dataconnect.gradle + +import com.android.build.api.variant.ApplicationAndroidComponentsExtension +import com.android.build.api.variant.ApplicationVariant +import java.util.Locale +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.kotlin.dsl.getByType +import org.gradle.kotlin.dsl.newInstance +import org.gradle.kotlin.dsl.register + +@Suppress("unused") +abstract class DataConnectGradlePlugin : Plugin { + + override fun apply(project: Project) { + project.extensions.create("dataconnect", DataConnectExtension::class.java) + val providers = project.objects.newInstance() + + project.tasks.register("setupFirebaseToolsForDataConnect") { + configureFrom(providers) + } + + val androidComponents = project.extensions.getByType() + androidComponents.onVariants { variant -> + val variantProviders = project.objects.newInstance(variant) + registerVariantTasks(project, variant, variantProviders) + } + } + + private fun registerVariantTasks( + project: Project, + variant: ApplicationVariant, + providers: MyVariantProviders, + ) { + val variantNameTitleCase = variant.name.replaceFirstChar { it.titlecase(Locale.US) } + + val generateCodeTask = + project.tasks.register("generate${variantNameTitleCase}DataConnectSources") { + configureFrom(providers) + } + + variant.sources.java!!.addGeneratedSourceDirectory( + generateCodeTask, + CodegenTask::outputDirectory, + ) + } +} diff --git a/dataconnect/buildSrc/src/main/kotlin/com/google/firebase/example/dataconnect/gradle/FirebaseToolsSetupTask.kt b/dataconnect/buildSrc/src/main/kotlin/com/google/firebase/example/dataconnect/gradle/FirebaseToolsSetupTask.kt new file mode 100644 index 000000000..48828f631 --- /dev/null +++ b/dataconnect/buildSrc/src/main/kotlin/com/google/firebase/example/dataconnect/gradle/FirebaseToolsSetupTask.kt @@ -0,0 +1,64 @@ +/* + * Copyright 2024 Google LLC + * + * 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 + * + * http://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.google.firebase.example.dataconnect.gradle + +import java.io.File +import org.gradle.api.DefaultTask +import org.gradle.api.file.DirectoryProperty +import org.gradle.api.file.RegularFile +import org.gradle.api.provider.Property +import org.gradle.api.provider.Provider +import org.gradle.api.tasks.Input +import org.gradle.api.tasks.Internal +import org.gradle.api.tasks.OutputDirectory +import org.gradle.api.tasks.TaskAction + +abstract class FirebaseToolsSetupTask : DefaultTask() { + + @get:Input abstract val version: Property + + @get:OutputDirectory abstract val outputDirectory: DirectoryProperty + + @get:Internal + val firebaseExecutable: Provider + get() = outputDirectory.map { it.file("node_modules/.bin/firebase") } + + @TaskAction + fun run() { + val version: String = version.get() + val outputDirectory: File = outputDirectory.get().asFile + + logger.info("version: {}", version) + logger.info("outputDirectory: {}", outputDirectory.absolutePath) + + project.delete(outputDirectory) + project.mkdir(outputDirectory) + + val packageJsonFile = File(outputDirectory, "package.json") + packageJsonFile.writeText("{}", Charsets.UTF_8) + + runCommand(File(outputDirectory, "install.log.txt")) { + commandLine("npm", "install", "firebase-tools@$version") + workingDir(outputDirectory) + } + } + + internal fun configureFrom(providers: MyProjectProviders) { + version.set(providers.firebaseToolsVersion) + outputDirectory.set(providers.buildDirectory.map { it.dir("firebase-tools") }) + } +} diff --git a/dataconnect/buildSrc/src/main/kotlin/com/google/firebase/example/dataconnect/gradle/Providers.kt b/dataconnect/buildSrc/src/main/kotlin/com/google/firebase/example/dataconnect/gradle/Providers.kt new file mode 100644 index 000000000..dda65d47e --- /dev/null +++ b/dataconnect/buildSrc/src/main/kotlin/com/google/firebase/example/dataconnect/gradle/Providers.kt @@ -0,0 +1,107 @@ +/* + * Copyright 2024 Google LLC + * + * 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 + * + * http://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.google.firebase.example.dataconnect.gradle + +import com.android.build.api.variant.ApplicationVariant +import javax.inject.Inject +import org.gradle.api.GradleException +import org.gradle.api.Project +import org.gradle.api.file.Directory +import org.gradle.api.file.DirectoryProperty +import org.gradle.api.file.RegularFile +import org.gradle.api.model.ObjectFactory +import org.gradle.api.provider.Provider +import org.gradle.api.provider.ProviderFactory +import org.gradle.kotlin.dsl.getByType +import org.gradle.kotlin.dsl.newInstance + +internal open class MyProjectProviders( + projectBuildDirectory: DirectoryProperty, + providerFactory: ProviderFactory, + ext: DataConnectExtension, +) { + + @Suppress("unused") + @Inject + constructor( + project: Project, + ) : this( + projectBuildDirectory = project.layout.buildDirectory, + providerFactory = project.providers, + ext = project.extensions.getByType(), + ) + + val buildDirectory: Provider = projectBuildDirectory.map { it.dir("dataconnect") } + + val firebaseToolsVersion: Provider = + providerFactory.provider { + ext.firebaseToolsVersion + ?: throw GradleException( + "dataconnect.firebaseToolsVersion must be set in your build.gradle or build.gradle.kts " + + "(error code xbmvkc3mtr)" + ) + } +} + +internal open class MyVariantProviders( + variant: ApplicationVariant, + myProjectProviders: MyProjectProviders, + ext: DataConnectExtension, + firebaseToolsSetupTask: FirebaseToolsSetupTask, + objectFactory: ObjectFactory, +) { + + @Suppress("unused") + @Inject + constructor( + variant: ApplicationVariant, + project: Project + ) : this( + variant = variant, + myProjectProviders = project.objects.newInstance(), + ext = project.extensions.getByType(), + firebaseToolsSetupTask = project.firebaseToolsSetupTask, + objectFactory = project.objects, + ) + + val buildDirectory: Provider = + myProjectProviders.buildDirectory.map { it.dir("variants/${variant.name}") } + + val dataConnectConfigDir: Provider = run { + val dir = + ext.dataConnectConfigDir + ?: throw GradleException( + "dataconnect.dataConnectConfigDir must be set in your build.gradle or build.gradle.kts " + + "(error code xbmvkc3mtr)" + ) + objectFactory.directoryProperty().also { property -> property.set(dir) } + } + + val firebaseExecutable: Provider = firebaseToolsSetupTask.firebaseExecutable +} + +private val Project.firebaseToolsSetupTask: FirebaseToolsSetupTask + get() { + val tasks = tasks.filterIsInstance() + if (tasks.size != 1) { + throw GradleException( + "expected exactly 1 FirebaseToolsSetupTask task to be registered, but found " + + "${tasks.size}: [${tasks.map { it.name }.sorted().joinToString(", ")}]" + ) + } + return tasks.single() + } diff --git a/dataconnect/dataconnect/.gitignore b/dataconnect/dataconnect/.gitignore new file mode 100644 index 000000000..ecb842d70 --- /dev/null +++ b/dataconnect/dataconnect/.gitignore @@ -0,0 +1 @@ +.generated/ diff --git a/dataconnect/dataconnect/movie-connector/connector.yaml b/dataconnect/dataconnect/movie-connector/connector.yaml index 2ba51749d..eb00af0c6 100644 --- a/dataconnect/dataconnect/movie-connector/connector.yaml +++ b/dataconnect/dataconnect/movie-connector/connector.yaml @@ -8,6 +8,6 @@ generate: kotlinSdk: # Create a custom package name for your generated SDK package: com.google.firebase.dataconnect.movies - # Specify where to store the generated SDK - # We're using the build/ directory so that generated code doesn't get checked into git - outputDir: ../../app/build/generated/sources/com/google/firebase/dataconnect/movies + # Use an arbitrary directory for generating the code, as the custom task in + # app/build.gradle.kts will generate into the appropriate directory. + outputDir: ../.generated diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 00284342f..6adec269a 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -14,8 +14,10 @@ activityCompose = "1.9.3" composeBom = "2024.11.00" googleServices = "4.4.2" composeNavigation = "2.8.4" +ktfmt = "0.43" [libraries] +android-gradlePlugin-api = { group = "com.android.tools.build", name = "gradle-api", version.ref = "agp" } androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" } androidx-lifecycle-runtime-compose-android = { module = "androidx.lifecycle:lifecycle-runtime-compose-android", version.ref = "lifecycle" } androidx-lifecycle-viewmodel-compose = { module = "androidx.lifecycle:lifecycle-viewmodel-compose", version.ref = "lifecycle" } @@ -37,6 +39,7 @@ androidx-ui-test-junit4 = { group = "androidx.compose.ui", name = "ui-test-junit androidx-material3 = { group = "androidx.compose.material3", name = "material3" } compose-navigation = { group = "androidx.navigation", name = "navigation-compose", version.ref = "composeNavigation"} kotlinx-serialization-core = { module = "org.jetbrains.kotlinx:kotlinx-serialization-core", version.ref = "kotlinxSerializationCore" } +snakeyaml = { module = "org.yaml:snakeyaml", version = "2.3" } [plugins] android-application = { id = "com.android.application", version.ref = "agp" } @@ -44,3 +47,5 @@ jetbrains-kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" } google-services = { id = "com.google.gms.google-services", version.ref = "googleServices" } compose-compiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" } +kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" } +spotless = { id = "com.diffplug.spotless", version = "7.0.0.BETA3" } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index c44c2304c..c229d658d 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.1-all.zip networkTimeout=10000 zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/scripts/ci_remove_fdc.py b/scripts/ci_remove_fdc.py deleted file mode 100644 index c425af615..000000000 --- a/scripts/ci_remove_fdc.py +++ /dev/null @@ -1,8 +0,0 @@ -# TODO(thatfiredev): remove this once github.com/firebase/quickstart-android/issues/1672 is fixed -with open('settings.gradle.kts', 'r') as file: - filedata = file.read() - -filedata = filedata.replace('":dataconnect:app",', '') - -with open('settings.gradle.kts', 'w') as file: - file.write(filedata) diff --git a/settings.gradle.kts b/settings.gradle.kts index af004974b..6962a0179 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,4 +1,7 @@ pluginManagement { + includeBuild("dataconnect/buildSrc") { + name = "dataConnectBuildSrc" + } repositories { google() mavenCentral()