From 17afcf4302e380f19ce9c5b7cb943afa0828465f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wojtek=20Kalici=C5=84ski?= Date: Wed, 14 Sep 2022 13:48:10 +0200 Subject: [PATCH 1/5] Fix FTL test APKs resolution Change-Id: I390cdf45df6d8fce5bf388a4fd495205ed407a0c --- .../AndroidApplicationConventionPlugin.kt | 5 ++ .../kotlin/AndroidLibraryConventionPlugin.kt | 9 +- .../apps/nowinandroid/PrintTestApks.kt | 90 +++++++++++++++++++ kokoro/build.sh | 13 ++- 4 files changed, 106 insertions(+), 11 deletions(-) create mode 100644 build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/PrintTestApks.kt mode change 100644 => 100755 kokoro/build.sh diff --git a/build-logic/convention/src/main/kotlin/AndroidApplicationConventionPlugin.kt b/build-logic/convention/src/main/kotlin/AndroidApplicationConventionPlugin.kt index 698bf7a79..824bf5dcf 100644 --- a/build-logic/convention/src/main/kotlin/AndroidApplicationConventionPlugin.kt +++ b/build-logic/convention/src/main/kotlin/AndroidApplicationConventionPlugin.kt @@ -14,8 +14,10 @@ * limitations under the License. */ +import com.android.build.api.variant.ApplicationAndroidComponentsExtension import com.android.build.gradle.internal.dsl.BaseAppModuleExtension import com.google.samples.apps.nowinandroid.configureKotlinAndroid +import com.google.samples.apps.nowinandroid.configurePrintApksTask import org.gradle.api.Plugin import org.gradle.api.Project import org.gradle.kotlin.dsl.configure @@ -32,6 +34,9 @@ class AndroidApplicationConventionPlugin : Plugin { configureKotlinAndroid(this) defaultConfig.targetSdk = 32 } + extensions.configure { + configurePrintApksTask(this) + } } } diff --git a/build-logic/convention/src/main/kotlin/AndroidLibraryConventionPlugin.kt b/build-logic/convention/src/main/kotlin/AndroidLibraryConventionPlugin.kt index 6b2861fde..4c000737e 100644 --- a/build-logic/convention/src/main/kotlin/AndroidLibraryConventionPlugin.kt +++ b/build-logic/convention/src/main/kotlin/AndroidLibraryConventionPlugin.kt @@ -14,9 +14,11 @@ * limitations under the License. */ +import com.android.build.api.variant.LibraryAndroidComponentsExtension import com.android.build.gradle.LibraryExtension import com.google.samples.apps.nowinandroid.configureFlavors import com.google.samples.apps.nowinandroid.configureKotlinAndroid +import com.google.samples.apps.nowinandroid.configurePrintApksTask import org.gradle.api.Plugin import org.gradle.api.Project import org.gradle.api.artifacts.VersionCatalogsExtension @@ -37,7 +39,9 @@ class AndroidLibraryConventionPlugin : Plugin { defaultConfig.targetSdk = 32 configureFlavors(this) } - + extensions.configure { + configurePrintApksTask(this) + } val libs = extensions.getByType().named("libs") dependencies { configurations.configureEach { @@ -50,5 +54,4 @@ class AndroidLibraryConventionPlugin : Plugin { } } } - -} +} \ No newline at end of file diff --git a/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/PrintTestApks.kt b/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/PrintTestApks.kt new file mode 100644 index 000000000..20e209aeb --- /dev/null +++ b/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/PrintTestApks.kt @@ -0,0 +1,90 @@ +/* + * Copyright 2022 The Android Open Source Project + * + * 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.google.samples.apps.nowinandroid + +import com.android.build.api.artifact.SingleArtifact +import com.android.build.api.variant.AndroidComponentsExtension +import com.android.build.api.variant.BuiltArtifactsLoader +import com.android.build.api.variant.HasAndroidTest +import org.gradle.api.DefaultTask +import org.gradle.api.Project +import org.gradle.api.file.Directory +import org.gradle.api.file.DirectoryProperty +import org.gradle.api.provider.ListProperty +import org.gradle.api.provider.Property +import org.gradle.api.provider.Provider +import org.gradle.api.tasks.Input +import org.gradle.api.tasks.InputDirectory +import org.gradle.api.tasks.InputFile +import org.gradle.api.tasks.InputFiles +import org.gradle.api.tasks.Internal +import org.gradle.api.tasks.TaskAction +import java.io.File + +internal fun Project.configurePrintApksTask(extension: AndroidComponentsExtension<*, *, *>) { + extension.onVariants { variant -> + if (variant is HasAndroidTest) { + val loader = variant.artifacts.getBuiltArtifactsLoader() + val artifact = variant.androidTest?.artifacts?.get(SingleArtifact.APK) + val testSources = variant.androidTest?.sources?.java?.all + if (artifact != null && testSources != null) { + tasks.register( + "${variant.name}PrintTestApk", + PrintApkLocationTask::class.java + ) { + apkFolder.set(artifact) + builtArtifactsLoader.set(loader) + variantName.set(variant.name) + sources.set(testSources) + } + } + } + } +} + +internal abstract class PrintApkLocationTask : DefaultTask() { + @get:InputDirectory + abstract val apkFolder: DirectoryProperty + + @get:InputFiles + abstract val sources: ListProperty + + @get:Internal + abstract val builtArtifactsLoader: Property + + @get:Input + abstract val variantName: Property + + @TaskAction + fun taskAction() { + val hasFiles = sources.orNull?.any { directory -> + directory.asFileTree.files.any { it.isFile } + } ?: throw RuntimeException("Cannot check androidTest sources") + + // Don't print APK location if there are no androidTest source files + if (!hasFiles) { + return + } + + val builtArtifacts = builtArtifactsLoader.get().load(apkFolder.get()) + ?: throw RuntimeException("Cannot load APKs") + if (builtArtifacts.elements.size != 1) + throw RuntimeException("Expected one APK !") + val apk = File(builtArtifacts.elements.single().outputFile).toPath() + println(apk) + } +} \ No newline at end of file diff --git a/kokoro/build.sh b/kokoro/build.sh old mode 100644 new mode 100755 index 1d21ee299..c283382d7 --- a/kokoro/build.sh +++ b/kokoro/build.sh @@ -58,12 +58,12 @@ run_firebase_test_lab() { set +e # To not exit on an error to retry flaky tests local counter=0 local result=1 - local module=$1 + local testApk=$1 while [ $result != 0 -a $counter -lt $MAX_RETRY ]; do gcloud firebase test android run \ --type instrumentation \ --app "app/build/outputs/apk/demo/debug/app-demo-debug.apk" \ - --test "$module/build/outputs/apk/androidTest/demo/debug/$module-demo-debug-androidTest.apk" \ + --test "$testApk" \ --device-ids $deviceIds \ --os-version-ids $osVersionIds \ --locales en \ @@ -76,17 +76,14 @@ run_firebase_test_lab() { # All modules with androidTest to run tests on. -# This command will create a list like ["app", "sync"] based on which subdirectories -# (assumed to be modules) have an androidTest source directory. -# The sed regex pulls out the module name from the matched directory -modules=($(find . -regex ".*/src/androidTest" | sed -E 's|\./([^/]*)/.*|\1|g')) +testApks=($(./gradlew -q demoDebugPrintTestApk)) # Run all modules in parallel with Firebase Test Lab, and fail if any fail pids="" result=0 -for module in ${modules[@]}; do - run_firebase_test_lab $module & +for testApk in ${testApks[@]}; do + run_firebase_test_lab $testApk & pids="$pids $!" done From d0cff2b11c5b09d6d218b8f6ebfa0d7938e27393 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wojtek=20Kalici=C5=84ski?= Date: Wed, 10 Aug 2022 14:52:33 +0200 Subject: [PATCH 2/5] Build cleanup * Move Hilt setup to convention plugin * Disable Hilt on modules where it's not needed * Enable non-transitive R classes * Fix `configuration` blocks called in wrong scope * Move imperative Flavors code from build.gradle * Disable unnecessary build features globally * Disable configure-on-demand as it's not encouraged * Don't use internal AGP packages in plugins Change-Id: I1bee3e3fd0103054637b979a350f9fd2312ae8ba --- app/build.gradle.kts | 36 ++++----------- .../apps/nowinandroid/ui/NavigationTest.kt | 13 +++--- benchmark/build.gradle.kts | 4 ++ build-logic/convention/build.gradle.kts | 4 ++ ...droidApplicationComposeConventionPlugin.kt | 4 +- .../AndroidApplicationConventionPlugin.kt | 6 ++- .../kotlin/AndroidFeatureConventionPlugin.kt | 8 +--- .../kotlin/AndroidHiltConventionPlugin.kt | 44 +++++++++++++++++++ .../kotlin/AndroidLibraryConventionPlugin.kt | 13 +++--- .../samples/apps/nowinandroid/Flavor.kt | 8 ++++ .../apps/nowinandroid/PrintTestApks.kt | 2 - core/common/build.gradle.kts | 5 +-- core/data-test/build.gradle.kts | 7 +-- core/data/build.gradle.kts | 6 +-- core/database/build.gradle.kts | 6 +-- core/datastore-test/build.gradle.kts | 7 +-- core/datastore/build.gradle.kts | 7 +-- core/navigation/build.gradle.kts | 7 +-- core/network/build.gradle.kts | 13 +++--- core/testing/build.gradle.kts | 5 +-- core/ui/build.gradle.kts | 2 +- .../nowinandroid/core/ui/NewsResourceCard.kt | 3 +- feature/author/build.gradle.kts | 2 - .../feature/author/AuthorScreen.kt | 4 +- feature/bookmarks/build.gradle.kts | 2 - feature/foryou/build.gradle.kts | 2 - feature/interests/build.gradle.kts | 2 - feature/topic/build.gradle.kts | 4 +- .../nowinandroid/feature/topic/TopicScreen.kt | 4 +- gradle.properties | 28 ++++++++++-- gradle/libs.versions.toml | 2 +- sync/build.gradle.kts | 8 +--- .../sync/initializers/SyncWorkHelpers.kt | 4 +- 33 files changed, 145 insertions(+), 127 deletions(-) create mode 100644 build-logic/convention/src/main/kotlin/AndroidHiltConventionPlugin.kt diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 690cd172f..e53f2f013 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -20,9 +20,8 @@ plugins { id("nowinandroid.android.application") id("nowinandroid.android.application.compose") id("nowinandroid.android.application.jacoco") - kotlin("kapt") + id("nowinandroid.android.hilt") id("jacoco") - id("dagger.hilt.android.plugin") id("nowinandroid.spotless") id("nowinandroid.firebase-perf") } @@ -67,19 +66,6 @@ android { } } - // @see Flavor for more details on the app product flavors. - flavorDimensions += FlavorDimension.contentType.name - productFlavors { - Flavor.values().forEach { - create(it.name) { - dimension = it.dimension.name - if (it.applicationIdSuffix != null) { - applicationIdSuffix = it.applicationIdSuffix - } - } - } - } - packagingOptions { resources { excludes.add("/META-INF/{AL2.0,LGPL2.1}") @@ -124,17 +110,13 @@ dependencies { implementation(libs.coil.kt) implementation(libs.coil.kt.svg) +} - implementation(libs.hilt.android) - kapt(libs.hilt.compiler) - kaptAndroidTest(libs.hilt.compiler) - - // androidx.test is forcing JUnit, 4.12. This forces it to use 4.13 - configurations.configureEach { - resolutionStrategy { - force(libs.junit4) - // Temporary workaround for https://issuetracker.google.com/174733673 - force("org.objenesis:objenesis:2.6") - } +// androidx.test is forcing JUnit, 4.12. This forces it to use 4.13 +configurations.configureEach { + resolutionStrategy { + force(libs.junit4) + // Temporary workaround for https://issuetracker.google.com/174733673 + force("org.objenesis:objenesis:2.6") } -} +} \ No newline at end of file diff --git a/app/src/androidTest/java/com/google/samples/apps/nowinandroid/ui/NavigationTest.kt b/app/src/androidTest/java/com/google/samples/apps/nowinandroid/ui/NavigationTest.kt index 90d5d92dc..184d48507 100644 --- a/app/src/androidTest/java/com/google/samples/apps/nowinandroid/ui/NavigationTest.kt +++ b/app/src/androidTest/java/com/google/samples/apps/nowinandroid/ui/NavigationTest.kt @@ -25,7 +25,8 @@ import androidx.compose.ui.test.performClick import androidx.test.espresso.Espresso import androidx.test.espresso.NoActivityResumedException import com.google.samples.apps.nowinandroid.MainActivity -import com.google.samples.apps.nowinandroid.R +import com.google.samples.apps.nowinandroid.feature.foryou.R as FeatureForyouR +import com.google.samples.apps.nowinandroid.feature.interests.R as FeatureInterestsR import dagger.hilt.android.testing.BindValue import dagger.hilt.android.testing.HiltAndroidRule import dagger.hilt.android.testing.HiltAndroidTest @@ -70,11 +71,11 @@ class NavigationTest { @Before fun setup() { composeTestRule.activity.apply { - done = getString(R.string.done) - navigateUp = getString(R.string.navigate_up) - forYouLoading = getString(R.string.for_you_loading) - forYou = getString(R.string.for_you) - interests = getString(R.string.interests) + done = getString(FeatureForyouR.string.done) + navigateUp = getString(FeatureForyouR.string.navigate_up) + forYouLoading = getString(FeatureForyouR.string.for_you_loading) + forYou = getString(FeatureForyouR.string.for_you) + interests = getString(FeatureInterestsR.string.interests) sampleTopic = "Headlines" } } diff --git a/benchmark/build.gradle.kts b/benchmark/build.gradle.kts index fab2055e7..a00e1dfe2 100644 --- a/benchmark/build.gradle.kts +++ b/benchmark/build.gradle.kts @@ -30,6 +30,10 @@ android { testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" } + buildFeatures { + buildConfig = true + } + buildTypes { // This benchmark buildType is used for benchmarking, and should function like your // release build (for example, with minification on). It's signed with a debug key diff --git a/build-logic/convention/build.gradle.kts b/build-logic/convention/build.gradle.kts index 52dfeafb5..adcd7af61 100644 --- a/build-logic/convention/build.gradle.kts +++ b/build-logic/convention/build.gradle.kts @@ -65,6 +65,10 @@ gradlePlugin { id = "nowinandroid.android.test" implementationClass = "AndroidTestConventionPlugin" } + register("androidHilt") { + id = "nowinandroid.android.hilt" + implementationClass = "AndroidHiltConventionPlugin" + } register("spotless") { id = "nowinandroid.spotless" implementationClass = "SpotlessConventionPlugin" diff --git a/build-logic/convention/src/main/kotlin/AndroidApplicationComposeConventionPlugin.kt b/build-logic/convention/src/main/kotlin/AndroidApplicationComposeConventionPlugin.kt index ea40d8c25..cf90b17af 100644 --- a/build-logic/convention/src/main/kotlin/AndroidApplicationComposeConventionPlugin.kt +++ b/build-logic/convention/src/main/kotlin/AndroidApplicationComposeConventionPlugin.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -import com.android.build.gradle.internal.dsl.BaseAppModuleExtension +import com.android.build.api.dsl.ApplicationExtension import com.google.samples.apps.nowinandroid.configureAndroidCompose import org.gradle.api.Plugin import org.gradle.api.Project @@ -24,7 +24,7 @@ class AndroidApplicationComposeConventionPlugin : Plugin { override fun apply(target: Project) { with(target) { pluginManager.apply("com.android.application") - val extension = extensions.getByType() + val extension = extensions.getByType() configureAndroidCompose(extension) } } diff --git a/build-logic/convention/src/main/kotlin/AndroidApplicationConventionPlugin.kt b/build-logic/convention/src/main/kotlin/AndroidApplicationConventionPlugin.kt index 4369a7380..612eb6ad4 100644 --- a/build-logic/convention/src/main/kotlin/AndroidApplicationConventionPlugin.kt +++ b/build-logic/convention/src/main/kotlin/AndroidApplicationConventionPlugin.kt @@ -15,7 +15,8 @@ */ import com.android.build.api.variant.ApplicationAndroidComponentsExtension -import com.android.build.gradle.internal.dsl.BaseAppModuleExtension +import com.android.build.api.dsl.ApplicationExtension +import com.google.samples.apps.nowinandroid.configureFlavors import com.google.samples.apps.nowinandroid.configureKotlinAndroid import com.google.samples.apps.nowinandroid.configurePrintApksTask import org.gradle.api.Plugin @@ -30,9 +31,10 @@ class AndroidApplicationConventionPlugin : Plugin { apply("org.jetbrains.kotlin.android") } - extensions.configure { + extensions.configure { configureKotlinAndroid(this) defaultConfig.targetSdk = 33 + configureFlavors(this) } extensions.configure { configurePrintApksTask(this) diff --git a/build-logic/convention/src/main/kotlin/AndroidFeatureConventionPlugin.kt b/build-logic/convention/src/main/kotlin/AndroidFeatureConventionPlugin.kt index 934a38af1..ec0b0b223 100644 --- a/build-logic/convention/src/main/kotlin/AndroidFeatureConventionPlugin.kt +++ b/build-logic/convention/src/main/kotlin/AndroidFeatureConventionPlugin.kt @@ -26,9 +26,8 @@ class AndroidFeatureConventionPlugin : Plugin { override fun apply(target: Project) { with(target) { pluginManager.apply { - apply("com.android.library") - apply("org.jetbrains.kotlin.android") - apply("org.jetbrains.kotlin.kapt") + apply("nowinandroid.android.library") + apply("nowinandroid.android.hilt") } extensions.configure { defaultConfig { @@ -59,9 +58,6 @@ class AndroidFeatureConventionPlugin : Plugin { add("implementation", libs.findLibrary("kotlinx.coroutines.android").get()) - add("implementation", libs.findLibrary("hilt.android").get()) - add("kapt", libs.findLibrary("hilt.compiler").get()) - // TODO : Remove this dependency once we upgrade to Android Studio Dolphin b/228889042 // These dependencies are currently necessary to render Compose previews add( diff --git a/build-logic/convention/src/main/kotlin/AndroidHiltConventionPlugin.kt b/build-logic/convention/src/main/kotlin/AndroidHiltConventionPlugin.kt new file mode 100644 index 000000000..0ae7e60e0 --- /dev/null +++ b/build-logic/convention/src/main/kotlin/AndroidHiltConventionPlugin.kt @@ -0,0 +1,44 @@ +/* + * Copyright 2022 The Android Open Source Project + * + * 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. + */ + +import com.android.build.api.variant.LibraryAndroidComponentsExtension +import com.google.samples.apps.nowinandroid.configureJacoco +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.api.artifacts.VersionCatalogsExtension +import org.gradle.kotlin.dsl.dependencies +import org.gradle.kotlin.dsl.getByType +import org.gradle.kotlin.dsl.kotlin + +class AndroidHiltConventionPlugin : Plugin { + override fun apply(target: Project) { + with(target) { + with(pluginManager) { + apply("org.jetbrains.kotlin.kapt") + apply("dagger.hilt.android.plugin") + } + + val libs = extensions.getByType().named("libs") + dependencies { + "implementation"(libs.findLibrary("hilt.android").get()) + "kapt"(libs.findLibrary("hilt.compiler").get()) + "kaptAndroidTest"(libs.findLibrary("hilt.compiler").get()) + } + + } + } + +} \ No newline at end of file diff --git a/build-logic/convention/src/main/kotlin/AndroidLibraryConventionPlugin.kt b/build-logic/convention/src/main/kotlin/AndroidLibraryConventionPlugin.kt index 8cc061cca..4bcd039f3 100644 --- a/build-logic/convention/src/main/kotlin/AndroidLibraryConventionPlugin.kt +++ b/build-logic/convention/src/main/kotlin/AndroidLibraryConventionPlugin.kt @@ -14,6 +14,7 @@ * limitations under the License. */ +import com.android.build.api.variant.AndroidComponentsExtension import com.android.build.api.variant.LibraryAndroidComponentsExtension import com.android.build.gradle.LibraryExtension import com.google.samples.apps.nowinandroid.configureFlavors @@ -43,13 +44,11 @@ class AndroidLibraryConventionPlugin : Plugin { configurePrintApksTask(this) } val libs = extensions.getByType().named("libs") - dependencies { - configurations.configureEach { - resolutionStrategy { - force(libs.findLibrary("junit4").get()) - // Temporary workaround for https://issuetracker.google.com/174733673 - force("org.objenesis:objenesis:2.6") - } + configurations.configureEach { + resolutionStrategy { + force(libs.findLibrary("junit4").get()) + // Temporary workaround for https://issuetracker.google.com/174733673 + force("org.objenesis:objenesis:2.6") } } } diff --git a/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/Flavor.kt b/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/Flavor.kt index cfcfe6956..f3a12db4f 100644 --- a/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/Flavor.kt +++ b/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/Flavor.kt @@ -1,5 +1,8 @@ package com.google.samples.apps.nowinandroid +import com.android.build.api.dsl.ApplicationExtension +import com.android.build.api.dsl.ApplicationProductFlavor +import com.android.build.api.dsl.ApplicationVariantDimension import com.android.build.api.dsl.CommonExtension import org.gradle.api.Project @@ -24,6 +27,11 @@ fun Project.configureFlavors( Flavor.values().forEach{ create(it.name) { dimension = it.dimension.name + if (this@apply is ApplicationExtension && this is ApplicationProductFlavor) { + if (it.applicationIdSuffix != null) { + this.applicationIdSuffix = it.applicationIdSuffix + } + } } } } diff --git a/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/PrintTestApks.kt b/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/PrintTestApks.kt index 20e209aeb..1a9b3c7ed 100644 --- a/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/PrintTestApks.kt +++ b/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/PrintTestApks.kt @@ -26,10 +26,8 @@ import org.gradle.api.file.Directory import org.gradle.api.file.DirectoryProperty import org.gradle.api.provider.ListProperty import org.gradle.api.provider.Property -import org.gradle.api.provider.Provider import org.gradle.api.tasks.Input import org.gradle.api.tasks.InputDirectory -import org.gradle.api.tasks.InputFile import org.gradle.api.tasks.InputFiles import org.gradle.api.tasks.Internal import org.gradle.api.tasks.TaskAction diff --git a/core/common/build.gradle.kts b/core/common/build.gradle.kts index 0957177c2..94d6e4379 100644 --- a/core/common/build.gradle.kts +++ b/core/common/build.gradle.kts @@ -16,14 +16,11 @@ plugins { id("nowinandroid.android.library") id("nowinandroid.android.library.jacoco") - kotlin("kapt") + id("nowinandroid.android.hilt") id("nowinandroid.spotless") } dependencies { implementation(libs.kotlinx.coroutines.android) - implementation(libs.hilt.android) - kapt(libs.hilt.compiler) - testImplementation(project(":core:testing")) } \ No newline at end of file diff --git a/core/data-test/build.gradle.kts b/core/data-test/build.gradle.kts index a55fc05bd..93a24d913 100644 --- a/core/data-test/build.gradle.kts +++ b/core/data-test/build.gradle.kts @@ -15,16 +15,11 @@ */ plugins { id("nowinandroid.android.library") - kotlin("kapt") - id("dagger.hilt.android.plugin") + id("nowinandroid.android.hilt") id("nowinandroid.spotless") } dependencies { api(project(":core:data")) implementation(project(":core:testing")) - - implementation(libs.hilt.android) - kapt(libs.hilt.compiler) - kaptAndroidTest(libs.hilt.compiler) } diff --git a/core/data/build.gradle.kts b/core/data/build.gradle.kts index b1fa8ef04..7df2f360f 100644 --- a/core/data/build.gradle.kts +++ b/core/data/build.gradle.kts @@ -16,9 +16,8 @@ plugins { id("nowinandroid.android.library") id("nowinandroid.android.library.jacoco") - kotlin("kapt") + id("nowinandroid.android.hilt") id("kotlinx-serialization") - id("dagger.hilt.android.plugin") id("nowinandroid.spotless") } @@ -35,7 +34,4 @@ dependencies { implementation(libs.kotlinx.datetime) implementation(libs.kotlinx.coroutines.android) implementation(libs.kotlinx.serialization.json) - - implementation(libs.hilt.android) - kapt(libs.hilt.compiler) } diff --git a/core/database/build.gradle.kts b/core/database/build.gradle.kts index 0554bee55..72c816946 100644 --- a/core/database/build.gradle.kts +++ b/core/database/build.gradle.kts @@ -18,8 +18,7 @@ plugins { id("nowinandroid.android.library") id("nowinandroid.android.library.jacoco") - kotlin("kapt") - id("dagger.hilt.android.plugin") + id("nowinandroid.android.hilt") alias(libs.plugins.ksp) id("nowinandroid.spotless") } @@ -47,8 +46,5 @@ dependencies { implementation(libs.kotlinx.coroutines.android) implementation(libs.kotlinx.datetime) - implementation(libs.hilt.android) - kapt(libs.hilt.compiler) - androidTestImplementation(project(":core:testing")) } \ No newline at end of file diff --git a/core/datastore-test/build.gradle.kts b/core/datastore-test/build.gradle.kts index f16d5c617..aeb7c336b 100644 --- a/core/datastore-test/build.gradle.kts +++ b/core/datastore-test/build.gradle.kts @@ -15,8 +15,7 @@ */ plugins { id("nowinandroid.android.library") - kotlin("kapt") - id("dagger.hilt.android.plugin") + id("nowinandroid.android.hilt") id("nowinandroid.spotless") } @@ -25,8 +24,4 @@ dependencies { implementation(project(":core:testing")) api(libs.androidx.dataStore.core) - - implementation(libs.hilt.android) - kapt(libs.hilt.compiler) - kaptAndroidTest(libs.hilt.compiler) } diff --git a/core/datastore/build.gradle.kts b/core/datastore/build.gradle.kts index 623f52549..f7252622b 100644 --- a/core/datastore/build.gradle.kts +++ b/core/datastore/build.gradle.kts @@ -24,8 +24,7 @@ import com.google.protobuf.gradle.protoc plugins { id("nowinandroid.android.library") id("nowinandroid.android.library.jacoco") - kotlin("kapt") - id("dagger.hilt.android.plugin") + id("nowinandroid.android.hilt") alias(libs.plugins.protobuf) id("nowinandroid.spotless") } @@ -65,10 +64,6 @@ dependencies { implementation(libs.androidx.dataStore.core) implementation(libs.protobuf.kotlin.lite) - - implementation(libs.hilt.android) - kapt(libs.hilt.compiler) - kaptAndroidTest(libs.hilt.compiler) } // TODO b/239411851, Remove kapt workaround configuration diff --git a/core/navigation/build.gradle.kts b/core/navigation/build.gradle.kts index d9449babc..883d9087a 100644 --- a/core/navigation/build.gradle.kts +++ b/core/navigation/build.gradle.kts @@ -18,16 +18,11 @@ plugins { id("nowinandroid.android.library") id("nowinandroid.android.library.jacoco") - kotlin("kapt") - id("dagger.hilt.android.plugin") - alias(libs.plugins.ksp) + id("nowinandroid.android.hilt") id("nowinandroid.spotless") } dependencies { api(libs.androidx.hilt.navigation.compose) api(libs.androidx.navigation.compose) - - implementation(libs.hilt.android) - kapt(libs.hilt.compiler) } \ No newline at end of file diff --git a/core/network/build.gradle.kts b/core/network/build.gradle.kts index 3c2303185..26256d85c 100644 --- a/core/network/build.gradle.kts +++ b/core/network/build.gradle.kts @@ -13,16 +13,22 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + plugins { id("nowinandroid.android.library") id("nowinandroid.android.library.jacoco") - kotlin("kapt") + id("nowinandroid.android.hilt") id("kotlinx-serialization") - id("dagger.hilt.android.plugin") id("nowinandroid.spotless") id("com.google.android.libraries.mapsplatform.secrets-gradle-plugin") } +android { + buildFeatures { + buildConfig = true + } +} + secrets { defaultPropertiesFileName = "secrets.defaults.properties" } @@ -40,7 +46,4 @@ dependencies { implementation(libs.okhttp.logging) implementation(libs.retrofit.core) implementation(libs.retrofit.kotlin.serialization) - - implementation(libs.hilt.android) - kapt(libs.hilt.compiler) } diff --git a/core/testing/build.gradle.kts b/core/testing/build.gradle.kts index e71d82ef8..9734762b4 100644 --- a/core/testing/build.gradle.kts +++ b/core/testing/build.gradle.kts @@ -15,7 +15,7 @@ */ plugins { id("nowinandroid.android.library") - kotlin("kapt") + id("nowinandroid.android.hilt") id("nowinandroid.spotless") } @@ -24,9 +24,6 @@ dependencies { implementation(project(":core:data")) implementation(project(":core:model")) - implementation(libs.hilt.android) - kapt(libs.hilt.compiler) - api(libs.junit4) api(libs.androidx.test.core) api(libs.kotlinx.coroutines.test) diff --git a/core/ui/build.gradle.kts b/core/ui/build.gradle.kts index 47dd778ca..b83a3b6e1 100644 --- a/core/ui/build.gradle.kts +++ b/core/ui/build.gradle.kts @@ -47,4 +47,4 @@ dependencies { api(libs.androidx.compose.runtime.livedata) api(libs.androidx.metrics) api(libs.androidx.tracing.ktx) -} \ No newline at end of file +} diff --git a/core/ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCard.kt b/core/ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCard.kt index 0b765bbc1..125d8c3c6 100644 --- a/core/ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCard.kt +++ b/core/ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCard.kt @@ -57,6 +57,7 @@ import androidx.compose.ui.semantics.semantics import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import coil.compose.AsyncImage +import com.google.samples.apps.nowinandroid.core.designsystem.R as DesignsystemR import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaToggleButton import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaTopicTag import com.google.samples.apps.nowinandroid.core.designsystem.icon.NiaIcons @@ -135,7 +136,7 @@ fun NewsResourceHeaderImage( ) { AsyncImage( placeholder = if (LocalInspectionMode.current) { - painterResource(R.drawable.ic_placeholder_default) + painterResource(DesignsystemR.drawable.ic_placeholder_default) } else { // TODO b/228077205, show specific loading image visual null diff --git a/feature/author/build.gradle.kts b/feature/author/build.gradle.kts index 9316decc6..7febbf4d3 100644 --- a/feature/author/build.gradle.kts +++ b/feature/author/build.gradle.kts @@ -14,11 +14,9 @@ * limitations under the License. */ plugins { - id("nowinandroid.android.library") id("nowinandroid.android.feature") id("nowinandroid.android.library.compose") id("nowinandroid.android.library.jacoco") - id("dagger.hilt.android.plugin") id("nowinandroid.spotless") } diff --git a/feature/author/src/main/java/com/google/samples/apps/nowinandroid/feature/author/AuthorScreen.kt b/feature/author/src/main/java/com/google/samples/apps/nowinandroid/feature/author/AuthorScreen.kt index b1f45c9eb..755d584cf 100644 --- a/feature/author/src/main/java/com/google/samples/apps/nowinandroid/feature/author/AuthorScreen.kt +++ b/feature/author/src/main/java/com/google/samples/apps/nowinandroid/feature/author/AuthorScreen.kt @@ -209,7 +209,9 @@ private fun AuthorToolbar( IconButton(onClick = { onBackClick() }) { Icon( imageVector = Filled.ArrowBack, - contentDescription = stringResource(id = R.string.back) + contentDescription = stringResource( + id = com.google.samples.apps.nowinandroid.core.ui.R.string.back + ) ) } val selected = uiState.isFollowed diff --git a/feature/bookmarks/build.gradle.kts b/feature/bookmarks/build.gradle.kts index 568ac3c54..897a5e8b8 100644 --- a/feature/bookmarks/build.gradle.kts +++ b/feature/bookmarks/build.gradle.kts @@ -14,11 +14,9 @@ * limitations under the License. */ plugins { - id("nowinandroid.android.library") id("nowinandroid.android.feature") id("nowinandroid.android.library.compose") id("nowinandroid.android.library.jacoco") - id("dagger.hilt.android.plugin") id("nowinandroid.spotless") } diff --git a/feature/foryou/build.gradle.kts b/feature/foryou/build.gradle.kts index e9fb9d0b0..31ff8eacb 100644 --- a/feature/foryou/build.gradle.kts +++ b/feature/foryou/build.gradle.kts @@ -14,11 +14,9 @@ * limitations under the License. */ plugins { - id("nowinandroid.android.library") id("nowinandroid.android.feature") id("nowinandroid.android.library.compose") id("nowinandroid.android.library.jacoco") - id("dagger.hilt.android.plugin") id("nowinandroid.spotless") } diff --git a/feature/interests/build.gradle.kts b/feature/interests/build.gradle.kts index 15d07ceb7..4eebe78da 100644 --- a/feature/interests/build.gradle.kts +++ b/feature/interests/build.gradle.kts @@ -14,10 +14,8 @@ * limitations under the License. */ plugins { - id("nowinandroid.android.library") id("nowinandroid.android.feature") id("nowinandroid.android.library.compose") id("nowinandroid.android.library.jacoco") - id("dagger.hilt.android.plugin") id("nowinandroid.spotless") } diff --git a/feature/topic/build.gradle.kts b/feature/topic/build.gradle.kts index 9316decc6..1221ffb15 100644 --- a/feature/topic/build.gradle.kts +++ b/feature/topic/build.gradle.kts @@ -14,14 +14,12 @@ * limitations under the License. */ plugins { - id("nowinandroid.android.library") id("nowinandroid.android.feature") id("nowinandroid.android.library.compose") id("nowinandroid.android.library.jacoco") - id("dagger.hilt.android.plugin") id("nowinandroid.spotless") } dependencies { implementation(libs.kotlinx.datetime) -} +} \ No newline at end of file diff --git a/feature/topic/src/main/java/com/google/samples/apps/nowinandroid/feature/topic/TopicScreen.kt b/feature/topic/src/main/java/com/google/samples/apps/nowinandroid/feature/topic/TopicScreen.kt index 08cd7a8ad..981b2b9a2 100644 --- a/feature/topic/src/main/java/com/google/samples/apps/nowinandroid/feature/topic/TopicScreen.kt +++ b/feature/topic/src/main/java/com/google/samples/apps/nowinandroid/feature/topic/TopicScreen.kt @@ -210,7 +210,9 @@ private fun TopicToolbar( IconButton(onClick = { onBackClick() }) { Icon( imageVector = Filled.ArrowBack, - contentDescription = stringResource(id = R.string.back) + contentDescription = stringResource( + id = com.google.samples.apps.nowinandroid.core.ui.R.string.back + ) ) } val selected = uiState.isFollowed diff --git a/gradle.properties b/gradle.properties index ed7ead318..5643db706 100644 --- a/gradle.properties +++ b/gradle.properties @@ -4,17 +4,26 @@ # any settings specified in this file. # For more details on how to configure your build environment visit # http://www.gradle.org/docs/current/userguide/build_environment.html + # Specifies the JVM arguments used for the daemon process. # The setting is particularly useful for tweaking memory settings. -org.gradle.configureondemand=true -org.gradle.caching=true -org.gradle.parallel=true # Ensure important default jvmargs aren't overwritten. See https://github.com/gradle/gradle/issues/19750 org.gradle.jvmargs=-Xmx6g -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 -XX:+UseParallelGC -XX:MaxMetaspaceSize=1g + # When configured, Gradle will run in incubating parallel mode. # This option should only be used with decoupled projects. More details, visit # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects -# org.gradle.parallel=true +org.gradle.parallel=true + +# Not encouraged by Gradle and can produce weird results. Wait for isolated projects instead. +org.gradle.configureondemand=false + +# Enable caching between builds. +org.gradle.caching=true + +# TODO: enable this when moving to AGP 7.3 +#org.gradle.unsafe.configuration-cache=true + # AndroidX package structure to make it clearer which packages are bundled with the # Android operating system, and which are packaged with your app"s APK # https://developer.android.com/topic/libraries/support-library/androidx-rn @@ -23,3 +32,14 @@ android.useAndroidX=true kotlin.code.style=official # Allow kapt to use incremental processing kapt.incremental.apt=true + +# Non-transitive R classes is recommended and is faster/smaller +android.nonTransitiveRClass=true + +# Disable build features that are enabled by default, +# https://developer.android.com/studio/releases/gradle-plugin#buildFeatures +android.defaults.buildfeatures.buildconfig=false +android.defaults.buildfeatures.aidl=false +android.defaults.buildfeatures.renderscript=false +android.defaults.buildfeatures.resvalues=false +android.defaults.buildfeatures.shaders=false diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 0c09ab117..85d49ce67 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,7 +1,7 @@ [versions] accompanist = "0.24.8-beta" androidDesugarJdkLibs = "1.1.5" -androidGradlePlugin = "7.2.2" +androidGradlePlugin = "7.2.2" # TODO: when changing this to 7.3 resolve TODO in gradle.properties androidxActivity = "1.5.1" androidxAppCompat = "1.5.1" androidxCompose = "1.3.0-beta02" diff --git a/sync/build.gradle.kts b/sync/build.gradle.kts index 8e24d955e..6f5cb6379 100644 --- a/sync/build.gradle.kts +++ b/sync/build.gradle.kts @@ -16,8 +16,7 @@ plugins { id("nowinandroid.android.library") id("nowinandroid.android.library.jacoco") - kotlin("kapt") - id("dagger.hilt.android.plugin") + id("nowinandroid.android.hilt") id("nowinandroid.spotless") } @@ -43,12 +42,7 @@ dependencies { testImplementation(project(":core:testing")) androidTestImplementation(project(":core:testing")) - implementation(libs.hilt.android) - kapt(libs.hilt.compiler) kapt(libs.hilt.ext.compiler) androidTestImplementation(libs.androidx.work.testing) - - kaptAndroidTest(libs.hilt.compiler) - kaptAndroidTest(libs.hilt.ext.compiler) } diff --git a/sync/src/main/java/com/google/samples/apps/nowinandroid/sync/initializers/SyncWorkHelpers.kt b/sync/src/main/java/com/google/samples/apps/nowinandroid/sync/initializers/SyncWorkHelpers.kt index 6a58ebe19..bfaef1808 100644 --- a/sync/src/main/java/com/google/samples/apps/nowinandroid/sync/initializers/SyncWorkHelpers.kt +++ b/sync/src/main/java/com/google/samples/apps/nowinandroid/sync/initializers/SyncWorkHelpers.kt @@ -69,7 +69,9 @@ private fun Context.syncWorkNotification(): Notification { this, SyncNotificationChannelID ) - .setSmallIcon(R.drawable.ic_nia_notification) + .setSmallIcon( + com.google.samples.apps.nowinandroid.core.common.R.drawable.ic_nia_notification + ) .setContentTitle(getString(R.string.sync_notification_title)) .setPriority(NotificationCompat.PRIORITY_DEFAULT) .build() From 4683918cc7da6593edea6dca1ea662eea76d3b7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wojtek=20Kalici=C5=84ski?= Date: Tue, 13 Sep 2022 17:57:31 +0200 Subject: [PATCH 3/5] Move spotless to init script Also adds automatic git hooks installation Change-Id: I18debbee43af27db7b95a4202f824fa87e186713 --- .../pull_request_template.md | 2 +- .github/workflows/Build.yaml | 2 +- app-nia-catalog/build.gradle.kts | 1 - app/build.gradle.kts | 1 - benchmark/build.gradle.kts | 1 - build-logic/README.md | 2 - build-logic/convention/build.gradle.kts | 5 -- .../main/kotlin/SpotlessConventionPlugin.kt | 53 ------------------ build.gradle.kts | 1 - core/common/build.gradle.kts | 1 - core/data-test/build.gradle.kts | 1 - core/data/build.gradle.kts | 1 - core/database/build.gradle.kts | 1 - core/datastore-test/build.gradle.kts | 1 - core/datastore/build.gradle.kts | 1 - core/designsystem/build.gradle.kts | 1 - core/model/build.gradle.kts | 1 - core/navigation/build.gradle.kts | 1 - core/network/build.gradle.kts | 1 - core/testing/build.gradle.kts | 1 - core/ui/build.gradle.kts | 1 - feature/author/build.gradle.kts | 1 - feature/bookmarks/build.gradle.kts | 1 - feature/foryou/build.gradle.kts | 1 - feature/interests/build.gradle.kts | 1 - feature/topic/build.gradle.kts | 1 - gradle/init.gradle.kts | 56 +++++++++++++++++++ gradle/libs.versions.toml | 6 +- .../lint/designsystem/DesignSystemDetector.kt | 4 +- settings.gradle.kts | 14 +++++ sync/build.gradle.kts | 1 - tools/pre-push | 2 +- 32 files changed, 76 insertions(+), 92 deletions(-) delete mode 100644 build-logic/convention/src/main/kotlin/SpotlessConventionPlugin.kt create mode 100644 gradle/init.gradle.kts diff --git a/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md b/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md index da9b19682..c38247d23 100644 --- a/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md +++ b/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md @@ -6,7 +6,7 @@ label: 'triage me' Thank you for opening a Pull Request! Before submitting your PR, there are a few things you can do to make sure it goes smoothly: - [ ] Make sure to open a GitHub issue as a bug/feature request before writing your code! That way we can discuss the change, evaluate designs, and agree on the general idea -- [ ] Ensure the tests and linter pass (`./gradlew spotlessApply` to automatically apply formatting) +- [ ] Ensure the tests and linter pass (`./gradlew --init-script gradle/init.gradle.kts spotlessApply` to automatically apply formatting) - [ ] Appropriate docs were updated (if necessary) Is this your first Pull Request? diff --git a/.github/workflows/Build.yaml b/.github/workflows/Build.yaml index de2666fa1..595a0dc6e 100644 --- a/.github/workflows/Build.yaml +++ b/.github/workflows/Build.yaml @@ -34,7 +34,7 @@ jobs: uses: gradle/gradle-build-action@v2 - name: Check spotless - run: ./gradlew spotlessCheck --stacktrace + run: ./gradlew spotlessCheck --init-script gradle/init.gradle.kts --stacktrace - name: Check lint run: ./gradlew lintDebug --stacktrace diff --git a/app-nia-catalog/build.gradle.kts b/app-nia-catalog/build.gradle.kts index 88b105542..33ce4dc24 100644 --- a/app-nia-catalog/build.gradle.kts +++ b/app-nia-catalog/build.gradle.kts @@ -16,7 +16,6 @@ plugins { id("nowinandroid.android.application") id("nowinandroid.android.application.compose") - id("nowinandroid.spotless") } android { diff --git a/app/build.gradle.kts b/app/build.gradle.kts index e53f2f013..2f25807ba 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -22,7 +22,6 @@ plugins { id("nowinandroid.android.application.jacoco") id("nowinandroid.android.hilt") id("jacoco") - id("nowinandroid.spotless") id("nowinandroid.firebase-perf") } diff --git a/benchmark/build.gradle.kts b/benchmark/build.gradle.kts index a00e1dfe2..e39e716f2 100644 --- a/benchmark/build.gradle.kts +++ b/benchmark/build.gradle.kts @@ -19,7 +19,6 @@ import com.google.samples.apps.nowinandroid.configureFlavors plugins { id("nowinandroid.android.test") - id("nowinandroid.spotless") } android { diff --git a/build-logic/README.md b/build-logic/README.md index 093e5d857..0458b4fb1 100644 --- a/build-logic/README.md +++ b/build-logic/README.md @@ -29,8 +29,6 @@ setup. Current list of convention plugins: -- [`nowinandroid.spotless`](convention/src/main/kotlin/SpotlessConventionPlugin.kt): - Configures spotless. - [`nowinandroid.android.application`](convention/src/main/kotlin/AndroidApplicationConventionPlugin.kt), [`nowinandroid.android.library`](convention/src/main/kotlin/AndroidLibraryConventionPlugin.kt), [`nowinandroid.android.test`](convention/src/main/kotlin/AndroidTestConventionPlugin.kt): diff --git a/build-logic/convention/build.gradle.kts b/build-logic/convention/build.gradle.kts index adcd7af61..453085807 100644 --- a/build-logic/convention/build.gradle.kts +++ b/build-logic/convention/build.gradle.kts @@ -28,7 +28,6 @@ java { dependencies { compileOnly(libs.android.gradlePlugin) compileOnly(libs.kotlin.gradlePlugin) - compileOnly(libs.spotless.gradlePlugin) } gradlePlugin { @@ -69,10 +68,6 @@ gradlePlugin { id = "nowinandroid.android.hilt" implementationClass = "AndroidHiltConventionPlugin" } - register("spotless") { - id = "nowinandroid.spotless" - implementationClass = "SpotlessConventionPlugin" - } register("firebase-perf") { id = "nowinandroid.firebase-perf" implementationClass = "FirebasePerfConventionPlugin" diff --git a/build-logic/convention/src/main/kotlin/SpotlessConventionPlugin.kt b/build-logic/convention/src/main/kotlin/SpotlessConventionPlugin.kt deleted file mode 100644 index eaf907ce2..000000000 --- a/build-logic/convention/src/main/kotlin/SpotlessConventionPlugin.kt +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2022 The Android Open Source Project - * - * 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. - */ - -import com.diffplug.gradle.spotless.SpotlessExtension -import org.gradle.api.Plugin -import org.gradle.api.Project -import org.gradle.api.artifacts.VersionCatalogsExtension -import org.gradle.kotlin.dsl.configure -import org.gradle.kotlin.dsl.getByType - -class SpotlessConventionPlugin : Plugin { - override fun apply(target: Project) { - with(target) { - pluginManager.apply("com.diffplug.spotless") - val libs = extensions.getByType().named("libs") - - extensions.configure { - kotlin { - target("**/*.kt") - targetExclude("**/build/**/*.kt") - ktlint(libs.findVersion("ktlint").get().toString()).userData(mapOf("android" to "true")) - licenseHeaderFile(rootProject.file("spotless/copyright.kt")) - } - format("kts") { - target("**/*.kts") - targetExclude("**/build/**/*.kts") - // Look for the first line that doesn't have a block comment (assumed to be the license) - licenseHeaderFile(rootProject.file("spotless/copyright.kts"), "(^(?![\\/ ]\\*).*$)") - } - format("xml") { - target("**/*.xml") - targetExclude("**/build/**/*.xml") - // Look for the first XML tag that isn't a comment (