diff --git a/app/build.gradle b/app/build.gradle index bfc8366d4..156d67f20 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -14,22 +14,18 @@ * limitations under the License. */ plugins { - id 'com.android.application' - id 'kotlin-android' + id 'nowinandroid.android.application' + id 'nowinandroid.android.application.compose' + id 'nowinandroid.android.application.jacoco' id 'kotlin-kapt' id 'jacoco' id 'dagger.hilt.android.plugin' + id 'nowinandroid.spotless' } -def jacocoTestReport = tasks.create("jacocoTestReport") - android { - compileSdk buildConfig.compileSdk - defaultConfig { applicationId "com.google.samples.apps.nowinandroid" - minSdk buildConfig.minSdk - targetSdk buildConfig.targetSdk versionCode 1 versionName "0.0.1" // X.Y.Z; X = Major, Y = minor, Z = Patch level @@ -52,21 +48,6 @@ android { proguardFiles 'benchmark-rules.pro' } } - compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 - coreLibraryDesugaringEnabled true - } - kotlinOptions { - jvmTarget = '1.8' - useIR = true - } - buildFeatures { - compose true - } - composeOptions { - kotlinCompilerExtensionVersion libs.versions.androidxCompose.get() - } packagingOptions { resources { excludes += '/META-INF/{AL2.0,LGPL2.1}' @@ -77,42 +58,6 @@ android { includeAndroidResources = true } } - androidComponents { - def coverageExclusions = [ - // Android - "**/R.class", - "**/R\$*.class", - "**/BuildConfig.*", - "**/Manifest*.*" - ] - - onVariants( - selector().all(), - { variant -> - def testTaskName = "test${variant.name.capitalize()}UnitTest" - - def reportTask = tasks.register("jacoco${testTaskName.capitalize()}Report", JacocoReport) { - dependsOn(testTaskName) - - reports { - xml.required.set(true) - html.required.set(true) - } - - classDirectories.setFrom( - fileTree("$buildDir/tmp/kotlin-classes/${variant.name}") { - exclude(coverageExclusions) - } - ) - - sourceDirectories.setFrom(files("$projectDir/src/main/java", "$projectDir/src/main/kotlin")) - executionData.setFrom(file("$buildDir/jacoco/${testTaskName}.exec")) - } - - jacocoTestReport.dependsOn(reportTask) - } - ) - } } dependencies { @@ -129,8 +74,6 @@ dependencies { androidTestImplementation project(':core-domain-test') androidTestImplementation project(':core-network') - coreLibraryDesugaring libs.android.desugarJdkLibs - implementation libs.androidx.activity.compose implementation libs.androidx.appcompat implementation libs.androidx.core.ktx @@ -157,20 +100,3 @@ dependencies { } } } - -jacoco { - toolVersion libs.versions.jacoco.get() -} - -tasks.withType(Test) { - jacoco { - // Required for JaCoCo + Robolectric - // https://github.com/robolectric/robolectric/issues/2230 - // TODO: Consider removing if not we don't add Robolectric - setIncludeNoLocationClasses(true) - - // Required for JDK 11+ with the above - // https://github.com/gradle/gradle/issues/5184#issuecomment-391982009 - excludes = ["jdk.internal.*"] - } -} diff --git a/benchmark/build.gradle b/benchmark/build.gradle index 5bba24492..b4acb5d89 100644 --- a/benchmark/build.gradle +++ b/benchmark/build.gradle @@ -1,24 +1,29 @@ +/* + * 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. + */ + plugins { - id 'com.android.test' - id 'org.jetbrains.kotlin.android' + id "nowinandroid.android.test" + id 'nowinandroid.spotless' } android { namespace 'com.google.samples.apps.nowinandroid.benchmark' - compileSdk buildConfig.compileSdk - - compileOptions { - sourceCompatibility = JavaVersion.VERSION_1_8 - targetCompatibility = JavaVersion.VERSION_1_8 - } - - kotlinOptions { - jvmTarget = "1.8" - } defaultConfig { minSdk 23 - targetSdk 31 testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } diff --git a/build-logic/README.md b/build-logic/README.md new file mode 100644 index 000000000..90ccccc74 --- /dev/null +++ b/build-logic/README.md @@ -0,0 +1,40 @@ +# Convention Plugins + +The `build-logic` folder defines project-specific convention plugins, used to keep a single +source of truth for common module configurations. + +This approach is heavily based on +[https://developer.squareup.com/blog/herding-elephants/](https://developer.squareup.com/blog/herding-elephants/) +and +[https://github.com/jjohannes/idiomatic-gradle](https://github.com/jjohannes/idiomatic-gradle). + +By setting up convention plugins in `build-logic`, we can avoid duplicated build script setup, +messy `subproject` configurations, without the pitfalls of the `buildSrc` directory. + +`build-logic` is an included build, as configured in the root +[`settings.gradle`](../settings.gradle). + +Inside `build-logic` is a `convention` module, which defines a set of plugins that all normal +modules can use to configure themselves. + +`build-logic` also includes a set of `Kotlin` files used to share logic between plugins themselves, +which is most useful for configuring Android components (libraries vs applications) with shared +code. + +These plugins are *additive* and *composable*, and try to only accomplish a single responsibility. +Modules can then pick and choose the configurations they need. +If there is one-off logic for a module without shared code, it's preferable to define that directly +in the module's `build.gradle`, as opposed to creating a convention plugin with module-specific +setup. + +Current list of convention plugins: + +- [`nowinandroid.spotless`](convention/src/main/kotlin/nowinandroid.spotless.gradle.kts): + Configures spotless. +- [`nowinandroid.android.application`](convention/src/main/kotlin/nowinandroid.android.application.gradle.kts), + [`nowinandroid.android.library`](convention/src/main/kotlin/nowinandroid.android.library.gradle.kts), + [`nowinandroid.android.test`](convention/src/main/kotlin/nowinandroid.android.test.gradle.kts): + Configures common Android and Kotlin options. +- [`nowinandroid.android.application.compose`](convention/src/main/kotlin/nowinandroid.android.application.compose.gradle.kts), + [`nowinandroid.android.library.compose`](convention/src/main/kotlin/nowinandroid.android.library.gradle.kts): + Configures Jetpack Compose options diff --git a/build-logic/convention/build.gradle.kts b/build-logic/convention/build.gradle.kts new file mode 100644 index 000000000..ab9e700ec --- /dev/null +++ b/build-logic/convention/build.gradle.kts @@ -0,0 +1,32 @@ +/* + * 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. + */ + +plugins { + `kotlin-dsl` +} + +group = "com.google.samples.apps.nowinandroid.buildlogic" + +java { + sourceCompatibility = JavaVersion.VERSION_1_8 + targetCompatibility = JavaVersion.VERSION_1_8 +} + +dependencies { + implementation(libs.android.gradlePlugin) + implementation(libs.kotlin.gradlePlugin) + implementation(libs.spotless.gradlePlugin) +} diff --git a/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/AndroidCompose.kt b/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/AndroidCompose.kt new file mode 100644 index 000000000..e94c839b8 --- /dev/null +++ b/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/AndroidCompose.kt @@ -0,0 +1,41 @@ +/* + * 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.dsl.CommonExtension +import org.gradle.api.Project +import org.gradle.api.artifacts.VersionCatalogsExtension +import org.gradle.kotlin.dsl.getByType + +/** + * Configure Compose-specific options + */ +fun Project.configureAndroidCompose( + commonExtension: CommonExtension<*, *, *, *>, +) { + val libs = extensions.getByType().named("libs") + + commonExtension.apply { + buildFeatures { + compose = true + } + + composeOptions { + kotlinCompilerExtensionVersion = libs.findVersion("androidxCompose").get().toString() + } + } +} diff --git a/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/Jacoco.kt b/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/Jacoco.kt new file mode 100644 index 000000000..61e645ab5 --- /dev/null +++ b/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/Jacoco.kt @@ -0,0 +1,70 @@ +package com.google.samples.apps.nowinandroid + +import com.android.build.api.variant.AndroidComponentsExtension +import org.gradle.api.Project +import org.gradle.api.artifacts.VersionCatalogsExtension +import org.gradle.api.tasks.testing.Test +import org.gradle.kotlin.dsl.configure +import org.gradle.kotlin.dsl.getByType +import org.gradle.kotlin.dsl.register +import org.gradle.kotlin.dsl.withType +import org.gradle.testing.jacoco.plugins.JacocoPluginExtension +import org.gradle.testing.jacoco.plugins.JacocoTaskExtension +import org.gradle.testing.jacoco.tasks.JacocoReport + +private val coverageExclusions = listOf( + // Android + "**/R.class", + "**/R\$*.class", + "**/BuildConfig.*", + "**/Manifest*.*" +) + +fun Project.configureJacoco( + androidComponentsExtension: AndroidComponentsExtension<*, *, *>, +) { + val libs = extensions.getByType().named("libs") + + configure { + toolVersion = libs.findVersion("jacoco").get().toString() + } + + val jacocoTestReport = tasks.create("jacocoTestReport") + + androidComponentsExtension.onVariants { variant -> + val testTaskName = "test${variant.name.capitalize()}UnitTest" + + val reportTask = tasks.register("jacoco${testTaskName.capitalize()}Report", JacocoReport::class) { + dependsOn(testTaskName) + + reports { + xml.required.set(true) + html.required.set(true) + } + + classDirectories.setFrom( + fileTree("$buildDir/tmp/kotlin-classes/${variant.name}") { + exclude(coverageExclusions) + } + ) + + sourceDirectories.setFrom(files("$projectDir/src/main/java", "$projectDir/src/main/kotlin")) + executionData.setFrom(file("$buildDir/jacoco/$testTaskName.exec")) + } + + jacocoTestReport.dependsOn(reportTask) + } + + tasks.withType().configureEach { + configure { + // Required for JaCoCo + Robolectric + // https://github.com/robolectric/robolectric/issues/2230 + // TODO: Consider removing if not we don't add Robolectric + isIncludeNoLocationClasses = true + + // Required for JDK 11 with the above + // https://github.com/gradle/gradle/issues/5184#issuecomment-391982009 + excludes = listOf("jdk.internal.*") + } + } +} diff --git a/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/KotlinAndroid.kt b/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/KotlinAndroid.kt new file mode 100644 index 000000000..3a0138cc8 --- /dev/null +++ b/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/KotlinAndroid.kt @@ -0,0 +1,75 @@ +/* + * 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.dsl.CommonExtension +import org.gradle.api.JavaVersion +import org.gradle.api.Project +import org.gradle.api.artifacts.VersionCatalogsExtension +import org.gradle.api.plugins.ExtensionAware +import org.gradle.kotlin.dsl.dependencies +import org.gradle.kotlin.dsl.getByType +import org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptions + +/** + * Configure base Kotlin with Android options + */ +fun Project.configureKotlinAndroid( + commonExtension: CommonExtension<*, *, *, *>, +) { + commonExtension.apply { + compileSdk = 31 + + defaultConfig { + minSdk = 21 + } + + compileOptions { + sourceCompatibility = JavaVersion.VERSION_1_8 + targetCompatibility = JavaVersion.VERSION_1_8 + isCoreLibraryDesugaringEnabled = true + } + + kotlinOptions { + // Treat all Kotlin warnings as errors (disabled by default) + allWarningsAsErrors = properties["warningsAsErrors"] as? Boolean ?: false + + freeCompilerArgs = freeCompilerArgs + listOf( + "-Xopt-in=kotlin.RequiresOptIn", + // Enable experimental coroutines APIs, including Flow + "-Xopt-in=kotlinx.coroutines.ExperimentalCoroutinesApi", + "-Xopt-in=kotlinx.coroutines.FlowPreview", + "-Xopt-in=kotlin.Experimental", + // Enable experimental kotlinx serialization APIs + "-Xopt-in=kotlinx.serialization.ExperimentalSerializationApi" + ) + + // Set JVM target to 1.8 + jvmTarget = JavaVersion.VERSION_1_8.toString() + } + } + + val libs = extensions.getByType().named("libs") + + dependencies { + add("coreLibraryDesugaring", libs.findLibrary("android.desugarJdkLibs").get()) + } +} + +private fun CommonExtension<*, *, *, *>.kotlinOptions(block: KotlinJvmOptions.() -> Unit) { + (this as ExtensionAware).extensions.configure("kotlinOptions", block) +} diff --git a/build-logic/convention/src/main/kotlin/nowinandroid.android.application.compose.gradle.kts b/build-logic/convention/src/main/kotlin/nowinandroid.android.application.compose.gradle.kts new file mode 100644 index 000000000..b53d49c69 --- /dev/null +++ b/build-logic/convention/src/main/kotlin/nowinandroid.android.application.compose.gradle.kts @@ -0,0 +1,25 @@ +/* + * 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.google.samples.apps.nowinandroid.configureAndroidCompose + +plugins { + id("com.android.application") +} + +android { + configureAndroidCompose(this) +} diff --git a/build-logic/convention/src/main/kotlin/nowinandroid.android.application.gradle.kts b/build-logic/convention/src/main/kotlin/nowinandroid.android.application.gradle.kts new file mode 100644 index 000000000..cb09052ca --- /dev/null +++ b/build-logic/convention/src/main/kotlin/nowinandroid.android.application.gradle.kts @@ -0,0 +1,30 @@ +/* + * 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.google.samples.apps.nowinandroid.configureKotlinAndroid + +plugins { + id("com.android.application") + kotlin("android") +} + +android { + configureKotlinAndroid(this) + + defaultConfig { + targetSdk = 31 + } +} diff --git a/build-logic/convention/src/main/kotlin/nowinandroid.android.application.jacoco.gradle.kts b/build-logic/convention/src/main/kotlin/nowinandroid.android.application.jacoco.gradle.kts new file mode 100644 index 000000000..d96d5d040 --- /dev/null +++ b/build-logic/convention/src/main/kotlin/nowinandroid.android.application.jacoco.gradle.kts @@ -0,0 +1,28 @@ +/* + * 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.google.samples.apps.nowinandroid.configureJacoco + +plugins { + id("com.android.application") + jacoco +} + +android { + androidComponents { + configureJacoco(this) + } +} diff --git a/build-logic/convention/src/main/kotlin/nowinandroid.android.library.compose.gradle.kts b/build-logic/convention/src/main/kotlin/nowinandroid.android.library.compose.gradle.kts new file mode 100644 index 000000000..a43b2af87 --- /dev/null +++ b/build-logic/convention/src/main/kotlin/nowinandroid.android.library.compose.gradle.kts @@ -0,0 +1,25 @@ +/* + * 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.google.samples.apps.nowinandroid.configureAndroidCompose + +plugins { + id("com.android.library") +} + +android { + configureAndroidCompose(this) +} diff --git a/build-logic/convention/src/main/kotlin/nowinandroid.android.library.gradle.kts b/build-logic/convention/src/main/kotlin/nowinandroid.android.library.gradle.kts new file mode 100644 index 000000000..c0c4d4048 --- /dev/null +++ b/build-logic/convention/src/main/kotlin/nowinandroid.android.library.gradle.kts @@ -0,0 +1,30 @@ +/* + * 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.google.samples.apps.nowinandroid.configureKotlinAndroid + +plugins { + id("com.android.library") + kotlin("android") +} + +android { + configureKotlinAndroid(this) + + defaultConfig { + targetSdk = 31 + } +} diff --git a/build-logic/convention/src/main/kotlin/nowinandroid.android.library.jacoco.gradle.kts b/build-logic/convention/src/main/kotlin/nowinandroid.android.library.jacoco.gradle.kts new file mode 100644 index 000000000..2f9a999b8 --- /dev/null +++ b/build-logic/convention/src/main/kotlin/nowinandroid.android.library.jacoco.gradle.kts @@ -0,0 +1,28 @@ +/* + * 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.google.samples.apps.nowinandroid.configureJacoco + +plugins { + id("com.android.library") + jacoco +} + +android { + androidComponents { + configureJacoco(this) + } +} diff --git a/build-logic/convention/src/main/kotlin/nowinandroid.android.test.gradle.kts b/build-logic/convention/src/main/kotlin/nowinandroid.android.test.gradle.kts new file mode 100644 index 000000000..c273a652c --- /dev/null +++ b/build-logic/convention/src/main/kotlin/nowinandroid.android.test.gradle.kts @@ -0,0 +1,30 @@ +/* + * 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.google.samples.apps.nowinandroid.configureKotlinAndroid + +plugins { + id("com.android.test") + kotlin("android") +} + +android { + configureKotlinAndroid(this) + + defaultConfig { + targetSdk = 31 + } +} diff --git a/build-logic/convention/src/main/kotlin/nowinandroid.spotless.gradle.kts b/build-logic/convention/src/main/kotlin/nowinandroid.spotless.gradle.kts new file mode 100644 index 000000000..e3df80d7f --- /dev/null +++ b/build-logic/convention/src/main/kotlin/nowinandroid.spotless.gradle.kts @@ -0,0 +1,31 @@ +/* + * 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. + */ + +plugins { + id("com.diffplug.spotless") +} + +val libs = extensions.getByType().named("libs") + +spotless { + kotlin { + target("**/*.kt") + targetExclude("$buildDir/**/*.kt") + targetExclude("bin/**/*.kt") + ktlint(libs.findVersion("ktlint").get().toString()).userData(mapOf("android" to "true")) + licenseHeaderFile(rootProject.file("spotless/copyright.kt")) + } +} diff --git a/build-logic/settings.gradle.kts b/build-logic/settings.gradle.kts new file mode 100644 index 000000000..b5a0552a2 --- /dev/null +++ b/build-logic/settings.gradle.kts @@ -0,0 +1,31 @@ +/* + * 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. + */ + +enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS") + +dependencyResolutionManagement { + repositories { + google() + mavenCentral() + } + versionCatalogs { + create("libs") { + from(files("../gradle/libs.versions.toml")) + } + } +} + +include(":convention") diff --git a/build.gradle b/build.gradle index e3679a438..d0d8f45bf 100644 --- a/build.gradle +++ b/build.gradle @@ -14,20 +14,10 @@ * limitations under the License. */ -// Top-level build file where you can add configuration options common to all sub-projects/modules. - buildscript { - - ext.buildConfig = [ - 'compileSdk': 31, - 'minSdk' : 21, - 'targetSdk' : 31, - ] - repositories { google() mavenCentral() - maven { url 'https://androidx.dev/snapshots/builds/8273139/artifacts/repository' } } dependencies { @@ -37,42 +27,3 @@ buildscript { classpath(libs.hilt.gradlePlugin) } } - -plugins { - alias(libs.plugins.spotless) -} - -subprojects { - - apply plugin: 'com.diffplug.spotless' - spotless { - kotlin { - target '**/*.kt' - targetExclude("$buildDir/**/*.kt") - targetExclude('bin/**/*.kt') - targetExclude("$rootDir/core-network/src/main/java/com/google/samples/apps/nowinandroid/core/network/fake/FakeData.kt") - ktlint(libs.versions.ktlint.get()).userData([android: "true"]) - licenseHeaderFile rootProject.file('spotless/copyright.kt') - } - } - - tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).configureEach { - kotlinOptions { - // Treat all Kotlin warnings as errors (disabled by default) - allWarningsAsErrors = project.hasProperty("warningsAsErrors") ? project.warningsAsErrors : false - - freeCompilerArgs += '-Xopt-in=kotlin.RequiresOptIn' - - // Enable experimental coroutines APIs, including Flow - freeCompilerArgs += '-Xopt-in=kotlinx.coroutines.ExperimentalCoroutinesApi' - freeCompilerArgs += '-Xopt-in=kotlinx.coroutines.FlowPreview' - freeCompilerArgs += '-Xopt-in=kotlin.Experimental' - - // Enable experimental kotlinx serialization APIs - freeCompilerArgs += '-Xopt-in=kotlinx.serialization.ExperimentalSerializationApi' - - // Set JVM target to 1.8 - jvmTarget = "1.8" - } - } -} diff --git a/core-common/build.gradle b/core-common/build.gradle index f82419d66..01fb65a7c 100644 --- a/core-common/build.gradle +++ b/core-common/build.gradle @@ -14,25 +14,10 @@ * limitations under the License. */ plugins { - id 'com.android.library' - id 'kotlin-android' + id "nowinandroid.android.library" + id "nowinandroid.android.library.jacoco" id 'kotlin-kapt' -} - -android { - compileSdk buildConfig.compileSdk - - defaultConfig { - minSdk buildConfig.minSdk - targetSdk buildConfig.targetSdk - } - compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 - } - kotlinOptions { - jvmTarget = '1.8' - } + id 'nowinandroid.spotless' } dependencies { diff --git a/core-database/build.gradle b/core-database/build.gradle index 9847803ba..80c89e610 100644 --- a/core-database/build.gradle +++ b/core-database/build.gradle @@ -14,20 +14,16 @@ * limitations under the License. */ plugins { - id 'com.android.library' - id 'kotlin-android' + id 'nowinandroid.android.library' + id "nowinandroid.android.library.jacoco" id 'kotlin-kapt' id 'dagger.hilt.android.plugin' alias(libs.plugins.ksp) + id 'nowinandroid.spotless' } android { - compileSdk buildConfig.compileSdk - defaultConfig { - minSdk buildConfig.minSdk - targetSdk buildConfig.targetSdk - // The schemas directory contains a schema file for each version of the Room database. // This is required to enable Room auto migrations. // See https://developer.android.com/reference/kotlin/androidx/room/AutoMigration. @@ -37,13 +33,6 @@ android { testInstrumentationRunner "com.google.samples.apps.nowinandroid.core.testing.NiaTestRunner" } - compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 - } - kotlinOptions { - jvmTarget = '1.8' - } } dependencies { diff --git a/core-datastore-test/build.gradle b/core-datastore-test/build.gradle index 686b4a322..41dd13088 100644 --- a/core-datastore-test/build.gradle +++ b/core-datastore-test/build.gradle @@ -14,28 +14,10 @@ * limitations under the License. */ plugins { - id 'com.android.library' - id 'kotlin-android' + id "nowinandroid.android.library" id 'kotlin-kapt' id 'dagger.hilt.android.plugin' -} - -android { - compileSdk buildConfig.compileSdk - - defaultConfig { - minSdk buildConfig.minSdk - targetSdk buildConfig.targetSdk - } - - compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 - } - - kotlinOptions { - jvmTarget = '1.8' - } + id 'nowinandroid.spotless' } dependencies { diff --git a/core-datastore/build.gradle b/core-datastore/build.gradle index 32e172326..4e0c4b8e6 100644 --- a/core-datastore/build.gradle +++ b/core-datastore/build.gradle @@ -14,27 +14,12 @@ * limitations under the License. */ plugins { - id 'com.android.library' - id 'kotlin-android' + id "nowinandroid.android.library" + id "nowinandroid.android.library.jacoco" id 'kotlin-kapt' id 'dagger.hilt.android.plugin' alias(libs.plugins.protobuf) -} - -android { - compileSdk buildConfig.compileSdk - - defaultConfig { - minSdk buildConfig.minSdk - targetSdk buildConfig.targetSdk - } - compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 - } - kotlinOptions { - jvmTarget = '1.8' - } + id 'nowinandroid.spotless' } // Setup protobuf configuration, generating lite Java and Kotlin classes diff --git a/core-domain-test/build.gradle b/core-domain-test/build.gradle index 21d8bd359..f7bca4cbc 100644 --- a/core-domain-test/build.gradle +++ b/core-domain-test/build.gradle @@ -14,28 +14,10 @@ * limitations under the License. */ plugins { - id 'com.android.library' - id 'kotlin-android' + id "nowinandroid.android.library" id 'kotlin-kapt' id 'dagger.hilt.android.plugin' -} - -android { - compileSdk buildConfig.compileSdk - - defaultConfig { - minSdk buildConfig.minSdk - targetSdk buildConfig.targetSdk - } - - compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 - } - - kotlinOptions { - jvmTarget = '1.8' - } + id 'nowinandroid.spotless' } dependencies { diff --git a/core-domain/build.gradle b/core-domain/build.gradle index fca6d8424..fa766806f 100644 --- a/core-domain/build.gradle +++ b/core-domain/build.gradle @@ -14,27 +14,12 @@ * limitations under the License. */ plugins { - id 'com.android.library' - id 'kotlin-android' + id "nowinandroid.android.library" + id "nowinandroid.android.library.jacoco" id 'kotlin-kapt' id 'kotlinx-serialization' id 'dagger.hilt.android.plugin' -} - -android { - compileSdk buildConfig.compileSdk - - defaultConfig { - minSdk buildConfig.minSdk - targetSdk buildConfig.targetSdk - } - compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 - } - kotlinOptions { - jvmTarget = '1.8' - } + id 'nowinandroid.spotless' } dependencies { diff --git a/core-model/build.gradle b/core-model/build.gradle index e2f84391c..bfda73e2c 100644 --- a/core-model/build.gradle +++ b/core-model/build.gradle @@ -14,26 +14,11 @@ * limitations under the License. */ plugins { - id 'com.android.library' - id 'kotlin-android' + id "nowinandroid.android.library" + id "nowinandroid.android.library.jacoco" id 'kotlinx-serialization' alias(libs.plugins.ksp) -} - -android { - compileSdk buildConfig.compileSdk - - defaultConfig { - minSdk buildConfig.minSdk - targetSdk buildConfig.targetSdk - } - compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 - } - kotlinOptions { - jvmTarget = '1.8' - } + id 'nowinandroid.spotless' } dependencies { diff --git a/core-network/build.gradle b/core-network/build.gradle index c715a6879..5afdb7fe4 100644 --- a/core-network/build.gradle +++ b/core-network/build.gradle @@ -14,27 +14,12 @@ * limitations under the License. */ plugins { - id 'com.android.library' - id 'kotlin-android' + id "nowinandroid.android.library" + id "nowinandroid.android.library.jacoco" id 'kotlin-kapt' id 'kotlinx-serialization' id 'dagger.hilt.android.plugin' -} - -android { - compileSdk buildConfig.compileSdk - - defaultConfig { - minSdk buildConfig.minSdk - targetSdk buildConfig.targetSdk - } - compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 - } - kotlinOptions { - jvmTarget = '1.8' - } + id 'nowinandroid.spotless' } dependencies { diff --git a/core-network/src/main/java/com/google/samples/apps/nowinandroid/core/network/fake/FakeData.kt b/core-network/src/main/java/com/google/samples/apps/nowinandroid/core/network/fake/FakeDataSource.kt similarity index 99% rename from core-network/src/main/java/com/google/samples/apps/nowinandroid/core/network/fake/FakeData.kt rename to core-network/src/main/java/com/google/samples/apps/nowinandroid/core/network/fake/FakeDataSource.kt index 23c0ea0aa..eee7b83ba 100644 --- a/core-network/src/main/java/com/google/samples/apps/nowinandroid/core/network/fake/FakeData.kt +++ b/core-network/src/main/java/com/google/samples/apps/nowinandroid/core/network/fake/FakeDataSource.kt @@ -24,6 +24,8 @@ import kotlinx.datetime.TimeZone import kotlinx.datetime.toInstant import org.intellij.lang.annotations.Language +/* ktlint-disable max-line-length */ + object FakeDataSource { val sampleTopic = NetworkTopic( id = 1, @@ -218,7 +220,7 @@ object FakeDataSource { "imageUrl": "" } ] -""".trimIndent() + """.trimIndent() @Language("JSON") val data = """ @@ -3158,3 +3160,5 @@ object FakeDataSource { ] """.trimIndent() } + +/* ktlint-enable max-line-length */ diff --git a/core-testing/build.gradle b/core-testing/build.gradle index 3190597db..bae26696b 100644 --- a/core-testing/build.gradle +++ b/core-testing/build.gradle @@ -14,25 +14,9 @@ * limitations under the License. */ plugins { - id 'com.android.library' - id 'kotlin-android' + id "nowinandroid.android.library" id 'kotlin-kapt' -} - -android { - compileSdk buildConfig.compileSdk - - defaultConfig { - minSdk buildConfig.minSdk - targetSdk buildConfig.targetSdk - } - compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 - } - kotlinOptions { - jvmTarget = '1.8' - } + id 'nowinandroid.spotless' } dependencies { diff --git a/core-ui/build.gradle b/core-ui/build.gradle index 1dc0f71c9..25afebecc 100644 --- a/core-ui/build.gradle +++ b/core-ui/build.gradle @@ -14,38 +14,15 @@ * limitations under the License. */ plugins { - id 'com.android.library' - id 'kotlin-android' -} - -android { - compileSdk buildConfig.compileSdk - - defaultConfig { - minSdk buildConfig.minSdk - targetSdk buildConfig.targetSdk - } - compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 - coreLibraryDesugaringEnabled true - } - kotlinOptions { - jvmTarget = '1.8' - } - buildFeatures { - compose true - } - composeOptions { - kotlinCompilerExtensionVersion libs.versions.androidxCompose.get() - } + id "nowinandroid.android.library" + id "nowinandroid.android.library.compose" + id "nowinandroid.android.library.jacoco" + id 'nowinandroid.spotless' } dependencies { implementation project(':core-model') - coreLibraryDesugaring libs.android.desugarJdkLibs - implementation libs.androidx.core.ktx implementation libs.coil.kt implementation libs.coil.kt.compose diff --git a/feature-following/build.gradle b/feature-following/build.gradle index fde1a4bc9..4df475c6d 100644 --- a/feature-following/build.gradle +++ b/feature-following/build.gradle @@ -14,34 +14,18 @@ * limitations under the License. */ plugins { - id 'com.android.library' - id 'kotlin-android' + id "nowinandroid.android.library" + id "nowinandroid.android.library.compose" + id "nowinandroid.android.library.jacoco" id 'kotlin-kapt' id 'dagger.hilt.android.plugin' + id 'nowinandroid.spotless' } android { - compileSdk buildConfig.compileSdk - defaultConfig { - minSdk buildConfig.minSdk - targetSdk buildConfig.targetSdk - testInstrumentationRunner "com.google.samples.apps.nowinandroid.core.testing.NiaTestRunner" } - compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 - } - kotlinOptions { - jvmTarget = '1.8' - } - buildFeatures { - compose true - } - composeOptions { - kotlinCompilerExtensionVersion libs.versions.androidxCompose.get() - } } dependencies { diff --git a/feature-foryou/build.gradle b/feature-foryou/build.gradle index 2d5c2d9db..01741e1c4 100644 --- a/feature-foryou/build.gradle +++ b/feature-foryou/build.gradle @@ -14,34 +14,18 @@ * limitations under the License. */ plugins { - id 'com.android.library' - id 'kotlin-android' + id "nowinandroid.android.library" + id "nowinandroid.android.library.compose" + id "nowinandroid.android.library.jacoco" id 'kotlin-kapt' id 'dagger.hilt.android.plugin' + id 'nowinandroid.spotless' } android { - compileSdk buildConfig.compileSdk - defaultConfig { - minSdk buildConfig.minSdk - targetSdk buildConfig.targetSdk - testInstrumentationRunner "com.google.samples.apps.nowinandroid.core.testing.NiaTestRunner" } - compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 - } - kotlinOptions { - jvmTarget = '1.8' - } - buildFeatures { - compose true - } - composeOptions { - kotlinCompilerExtensionVersion libs.versions.androidxCompose.get() - } } dependencies { diff --git a/feature-topic/build.gradle b/feature-topic/build.gradle index 0c3feac5e..87cc84855 100644 --- a/feature-topic/build.gradle +++ b/feature-topic/build.gradle @@ -14,34 +14,18 @@ * limitations under the License. */ plugins { - id 'com.android.library' - id 'kotlin-android' + id "nowinandroid.android.library" + id "nowinandroid.android.library.compose" + id "nowinandroid.android.library.jacoco" id 'kotlin-kapt' id 'dagger.hilt.android.plugin' + id 'nowinandroid.spotless' } android { - compileSdk buildConfig.compileSdk - defaultConfig { - minSdk buildConfig.minSdk - targetSdk buildConfig.targetSdk - testInstrumentationRunner "com.google.samples.apps.nowinandroid.core.testing.NiaTestRunner" } - compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 - } - kotlinOptions { - jvmTarget = '1.8' - } - buildFeatures { - compose true - } - composeOptions { - kotlinCompilerExtensionVersion libs.versions.androidxCompose.get() - } } dependencies { diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 1d598cbfd..9876a8cec 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -107,8 +107,8 @@ retrofit-kotlin-serialization = { group = "com.jakewharton.retrofit", name = "re room-runtime = { group = "androidx.room", name = "room-runtime", version.ref = "room" } room-ktx = { group = "androidx.room", name = "room-ktx", version.ref = "room" } room-compiler = { group = "androidx.room", name = "room-compiler", version.ref = "room" } +spotless-gradlePlugin = { group = "com.diffplug.spotless", name = "spotless-plugin-gradle", version.ref = "spotless" } [plugins] -spotless = { id = "com.diffplug.spotless", version.ref = "spotless" } protobuf = { id = "com.google.protobuf", version.ref = "protobufPlugin" } ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" } diff --git a/settings.gradle b/settings.gradle index c7d7c0101..a46adc4f1 100644 --- a/settings.gradle +++ b/settings.gradle @@ -14,6 +14,15 @@ * limitations under the License. */ +pluginManagement { + includeBuild("build-logic") + repositories { + google() + mavenCentral() + gradlePluginPortal() + } +} + dependencyResolutionManagement { repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) repositories { diff --git a/sync/build.gradle b/sync/build.gradle index f9ac28dab..f29346e6d 100644 --- a/sync/build.gradle +++ b/sync/build.gradle @@ -14,26 +14,11 @@ * limitations under the License. */ plugins { - id 'com.android.library' - id 'kotlin-android' + id "nowinandroid.android.library" + id "nowinandroid.android.library.jacoco" id 'kotlin-kapt' id 'dagger.hilt.android.plugin' -} - -android { - compileSdk buildConfig.compileSdk - - defaultConfig { - minSdk buildConfig.minSdk - targetSdk buildConfig.targetSdk - } - compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 - } - kotlinOptions { - jvmTarget = '1.8' - } + id 'nowinandroid.spotless' } dependencies {