diff --git a/.idea/copyright/The_Android_Open_Source_Project.xml b/.idea/copyright/The_Android_Open_Source_Project.xml new file mode 100644 index 000000000..74acd98d8 --- /dev/null +++ b/.idea/copyright/The_Android_Open_Source_Project.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/copyright/profiles_settings.xml b/.idea/copyright/profiles_settings.xml new file mode 100644 index 000000000..c2494651f --- /dev/null +++ b/.idea/copyright/profiles_settings.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/build-logic/README.md b/build-logic/README.md index 45fd95f91..093e5d857 100644 --- a/build-logic/README.md +++ b/build-logic/README.md @@ -29,12 +29,12 @@ setup. Current list of convention plugins: -- [`nowinandroid.spotless`](convention/src/main/kotlin/nowinandroid.spotless.gradle.kts): +- [`nowinandroid.spotless`](convention/src/main/kotlin/SpotlessConventionPlugin.kt): 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): +- [`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): 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): +- [`nowinandroid.android.application.compose`](convention/src/main/kotlin/AndroidApplicationComposeConventionPlugin.kt), + [`nowinandroid.android.library.compose`](convention/src/main/kotlin/AndroidLibraryComposeConventionPlugin.kt): Configures Jetpack Compose options diff --git a/build-logic/convention/build.gradle.kts b/build-logic/convention/build.gradle.kts index ab9e700ec..9a5baaa41 100644 --- a/build-logic/convention/build.gradle.kts +++ b/build-logic/convention/build.gradle.kts @@ -30,3 +30,44 @@ dependencies { implementation(libs.kotlin.gradlePlugin) implementation(libs.spotless.gradlePlugin) } + +gradlePlugin { + plugins { + register("androidApplicationCompose") { + id = "nowinandroid.android.application.compose" + implementationClass = "AndroidApplicationComposeConventionPlugin" + } + register("androidApplication") { + id = "nowinandroid.android.application" + implementationClass = "AndroidApplicationConventionPlugin" + } + register("androidApplicationJacoco") { + id = "nowinandroid.android.application.jacoco" + implementationClass = "AndroidApplicationJacocoConventionPlugin" + } + register("androidLibraryCompose") { + id = "nowinandroid.android.library.compose" + implementationClass = "AndroidLibraryComposeConventionPlugin" + } + register("androidLibrary") { + id = "nowinandroid.android.library" + implementationClass = "AndroidLibraryConventionPlugin" + } + register("androidFeature") { + id = "nowinandroid.android.feature" + implementationClass = "AndroidFeatureConventionPlugin" + } + register("androidLibraryJacoco") { + id = "nowinandroid.android.library.jacoco" + implementationClass = "AndroidLibraryJacocoConventionPlugin" + } + register("androidTest") { + id = "nowinandroid.android.test" + implementationClass = "AndroidTestConventionPlugin" + } + 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 new file mode 100644 index 000000000..ea40d8c25 --- /dev/null +++ b/build-logic/convention/src/main/kotlin/AndroidApplicationComposeConventionPlugin.kt @@ -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. + */ + +import com.android.build.gradle.internal.dsl.BaseAppModuleExtension +import com.google.samples.apps.nowinandroid.configureAndroidCompose +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.kotlin.dsl.getByType + +class AndroidApplicationComposeConventionPlugin : Plugin { + override fun apply(target: Project) { + with(target) { + pluginManager.apply("com.android.application") + val extension = extensions.getByType() + configureAndroidCompose(extension) + } + } + +} \ No newline at end of file diff --git a/build-logic/convention/src/main/kotlin/AndroidApplicationConventionPlugin.kt b/build-logic/convention/src/main/kotlin/AndroidApplicationConventionPlugin.kt new file mode 100644 index 000000000..698bf7a79 --- /dev/null +++ b/build-logic/convention/src/main/kotlin/AndroidApplicationConventionPlugin.kt @@ -0,0 +1,38 @@ +/* + * 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.gradle.internal.dsl.BaseAppModuleExtension +import com.google.samples.apps.nowinandroid.configureKotlinAndroid +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.kotlin.dsl.configure + +class AndroidApplicationConventionPlugin : Plugin { + override fun apply(target: Project) { + with(target) { + with(pluginManager) { + apply("com.android.application") + apply("org.jetbrains.kotlin.android") + } + + extensions.configure { + configureKotlinAndroid(this) + defaultConfig.targetSdk = 32 + } + } + } + +} \ No newline at end of file diff --git a/build-logic/convention/src/main/kotlin/AndroidApplicationJacocoConventionPlugin.kt b/build-logic/convention/src/main/kotlin/AndroidApplicationJacocoConventionPlugin.kt new file mode 100644 index 000000000..4c3acc520 --- /dev/null +++ b/build-logic/convention/src/main/kotlin/AndroidApplicationJacocoConventionPlugin.kt @@ -0,0 +1,35 @@ +/* + * 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.ApplicationAndroidComponentsExtension +import com.google.samples.apps.nowinandroid.configureJacoco +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.kotlin.dsl.getByType + +class AndroidApplicationJacocoConventionPlugin : Plugin { + override fun apply(target: Project) { + with(target) { + with(pluginManager) { + apply("org.gradle.jacoco") + apply("com.android.application") + } + val extension = extensions.getByType() + configureJacoco(extension) + } + } + +} \ No newline at end of file diff --git a/build-logic/convention/src/main/kotlin/AndroidFeatureConventionPlugin.kt b/build-logic/convention/src/main/kotlin/AndroidFeatureConventionPlugin.kt new file mode 100644 index 000000000..9545bfb12 --- /dev/null +++ b/build-logic/convention/src/main/kotlin/AndroidFeatureConventionPlugin.kt @@ -0,0 +1,72 @@ +/* + * 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.gradle.LibraryExtension +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.dependencies +import org.gradle.kotlin.dsl.getByType + +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") + } + extensions.configure { + defaultConfig { + testInstrumentationRunner = + "com.google.samples.apps.nowinandroid.core.testing.NiaTestRunner" + } + } + + val libs = extensions.getByType().named("libs") + + dependencies { + add("implementation", project(":core-model")) + add("implementation", project(":core-ui")) + add("implementation", project(":core-data")) + add("implementation", project(":core-common")) + add("implementation", project(":core-navigation")) + + add("testImplementation", project(":core-testing")) + add("androidTestImplementation", project(":core-testing")) + + add("implementation", libs.findLibrary("coil.kt").get()) + add("implementation", libs.findLibrary("coil.kt.compose").get()) + + add("implementation", libs.findLibrary("androidx.hilt.navigation.compose").get()) + add("implementation", libs.findLibrary("androidx.lifecycle.viewModelCompose").get()) + + 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( + "debugImplementation", + libs.findLibrary("androidx.customview.poolingcontainer").get() + ) + } + } + } +} \ No newline at end of file diff --git a/build-logic/convention/src/main/kotlin/AndroidLibraryComposeConventionPlugin.kt b/build-logic/convention/src/main/kotlin/AndroidLibraryComposeConventionPlugin.kt new file mode 100644 index 000000000..ee6192e05 --- /dev/null +++ b/build-logic/convention/src/main/kotlin/AndroidLibraryComposeConventionPlugin.kt @@ -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. + */ + +import com.android.build.gradle.LibraryExtension +import com.google.samples.apps.nowinandroid.configureAndroidCompose +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.kotlin.dsl.getByType + +class AndroidLibraryComposeConventionPlugin : Plugin { + override fun apply(target: Project) { + with(target) { + pluginManager.apply("com.android.library") + val extension = extensions.getByType() + configureAndroidCompose(extension) + } + } + +} \ 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 new file mode 100644 index 000000000..f9247b6f7 --- /dev/null +++ b/build-logic/convention/src/main/kotlin/AndroidLibraryConventionPlugin.kt @@ -0,0 +1,52 @@ +/* + * 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.gradle.LibraryExtension +import com.google.samples.apps.nowinandroid.configureKotlinAndroid +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.dependencies +import org.gradle.kotlin.dsl.getByType + +class AndroidLibraryConventionPlugin : Plugin { + override fun apply(target: Project) { + with(target) { + with(pluginManager) { + apply("com.android.library") + apply("org.jetbrains.kotlin.android") + } + + extensions.configure { + configureKotlinAndroid(this) + defaultConfig.targetSdk = 32 + } + + 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") + } + } + } + } + } + +} \ No newline at end of file diff --git a/build-logic/convention/src/main/kotlin/AndroidLibraryJacocoConventionPlugin.kt b/build-logic/convention/src/main/kotlin/AndroidLibraryJacocoConventionPlugin.kt new file mode 100644 index 000000000..86ca091c3 --- /dev/null +++ b/build-logic/convention/src/main/kotlin/AndroidLibraryJacocoConventionPlugin.kt @@ -0,0 +1,35 @@ +/* + * 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.kotlin.dsl.getByType + +class AndroidLibraryJacocoConventionPlugin : Plugin { + override fun apply(target: Project) { + with(target) { + with(pluginManager) { + apply("org.gradle.jacoco") + apply("com.android.library") + } + val extension = extensions.getByType() + configureJacoco(extension) + } + } + +} \ No newline at end of file diff --git a/build-logic/convention/src/main/kotlin/AndroidTestConventionPlugin.kt b/build-logic/convention/src/main/kotlin/AndroidTestConventionPlugin.kt new file mode 100644 index 000000000..8d446505c --- /dev/null +++ b/build-logic/convention/src/main/kotlin/AndroidTestConventionPlugin.kt @@ -0,0 +1,38 @@ +/* + * 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.gradle.TestExtension +import com.google.samples.apps.nowinandroid.configureKotlinAndroid +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.kotlin.dsl.configure + +class AndroidTestConventionPlugin : Plugin { + override fun apply(target: Project) { + with(target) { + with(pluginManager) { + apply("com.android.test") + apply("org.jetbrains.kotlin.android") + } + + extensions.configure { + configureKotlinAndroid(this) + defaultConfig.targetSdk = 31 + } + } + } + +} \ No newline at end of file diff --git a/build-logic/convention/src/main/kotlin/SpotlessConventionPlugin.kt b/build-logic/convention/src/main/kotlin/SpotlessConventionPlugin.kt new file mode 100644 index 000000000..eaf907ce2 --- /dev/null +++ b/build-logic/convention/src/main/kotlin/SpotlessConventionPlugin.kt @@ -0,0 +1,53 @@ +/* + * 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 (