parent
22545bfb32
commit
ca73f5598f
@ -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
|
@ -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)
|
||||
}
|
@ -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<VersionCatalogsExtension>().named("libs")
|
||||
|
||||
commonExtension.apply {
|
||||
buildFeatures {
|
||||
compose = true
|
||||
}
|
||||
|
||||
composeOptions {
|
||||
kotlinCompilerExtensionVersion = libs.findVersion("androidxCompose").get().toString()
|
||||
}
|
||||
}
|
||||
}
|
@ -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<VersionCatalogsExtension>().named("libs")
|
||||
|
||||
configure<JacocoPluginExtension> {
|
||||
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<Test>().configureEach {
|
||||
configure<JacocoTaskExtension> {
|
||||
// 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.*")
|
||||
}
|
||||
}
|
||||
}
|
@ -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<VersionCatalogsExtension>().named("libs")
|
||||
|
||||
dependencies {
|
||||
add("coreLibraryDesugaring", libs.findLibrary("android.desugarJdkLibs").get())
|
||||
}
|
||||
}
|
||||
|
||||
private fun CommonExtension<*, *, *, *>.kotlinOptions(block: KotlinJvmOptions.() -> Unit) {
|
||||
(this as ExtensionAware).extensions.configure("kotlinOptions", block)
|
||||
}
|
@ -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)
|
||||
}
|
@ -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
|
||||
}
|
||||
}
|
@ -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)
|
||||
}
|
||||
}
|
@ -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)
|
||||
}
|
@ -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
|
||||
}
|
||||
}
|
@ -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)
|
||||
}
|
||||
}
|
@ -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
|
||||
}
|
||||
}
|
@ -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<VersionCatalogsExtension>().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"))
|
||||
}
|
||||
}
|
@ -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")
|
Loading…
Reference in new issue