From 3097eaf82fe1b2348a7f91fcf14997ba190e72c9 Mon Sep 17 00:00:00 2001 From: Harsh Shandilya Date: Tue, 5 Apr 2022 19:10:34 +0530 Subject: [PATCH] gradle: migrate to build-logic --- android/build.gradle.kts | 101 ++---------------- api/build.gradle.kts | 5 +- build-logic/.gitignore | 1 + build-logic/android-plugins/build.gradle.kts | 24 +++++ .../main/kotlin/artifacts/CollectApksTask.kt | 44 ++++++++ .../kotlin/artifacts/CollectBundleTask.kt | 33 ++++++ ...jarvis.claw.android-application.gradle.kts | 41 +++++++ ...v.msfjarvis.claw.android-common.gradle.kts | 40 +++++++ ....msfjarvis.claw.android-library.gradle.kts | 11 ++ ...msfjarvis.claw.rename-artifacts.gradle.kts | 22 ++++ .../src/main/kotlin/signing/AppSigning.kt | 37 +++++++ build-logic/kotlin-plugins/build.gradle.kts | 31 ++++++ ...v.msfjarvis.claw.kotlin-android.gradle.kts | 9 ++ ...ev.msfjarvis.claw.kotlin-common.gradle.kts | 38 +++++++ .../dev.msfjarvis.claw.kotlin-kapt.gradle.kts | 43 ++++++++ ...v.msfjarvis.claw.kotlin-library.gradle.kts | 6 ++ .../dev.msfjarvis.claw.spotless.gradle.kts | 28 +++++ .../dev.msfjarvis.claw.versions.gradle.kts | 27 +++++ build-logic/settings.gradle.kts | 22 ++++ build.gradle.kts | 46 ++------ common/build.gradle.kts | 10 +- database/build.gradle.kts | 23 +--- desktop/build.gradle.kts | 3 +- gradle/libs.versions.toml | 18 ++-- model/build.gradle.kts | 19 ++-- settings.gradle.kts | 1 + 26 files changed, 501 insertions(+), 182 deletions(-) create mode 100644 build-logic/.gitignore create mode 100644 build-logic/android-plugins/build.gradle.kts create mode 100644 build-logic/android-plugins/src/main/kotlin/artifacts/CollectApksTask.kt create mode 100644 build-logic/android-plugins/src/main/kotlin/artifacts/CollectBundleTask.kt create mode 100644 build-logic/android-plugins/src/main/kotlin/dev.msfjarvis.claw.android-application.gradle.kts create mode 100644 build-logic/android-plugins/src/main/kotlin/dev.msfjarvis.claw.android-common.gradle.kts create mode 100644 build-logic/android-plugins/src/main/kotlin/dev.msfjarvis.claw.android-library.gradle.kts create mode 100644 build-logic/android-plugins/src/main/kotlin/dev.msfjarvis.claw.rename-artifacts.gradle.kts create mode 100644 build-logic/android-plugins/src/main/kotlin/signing/AppSigning.kt create mode 100644 build-logic/kotlin-plugins/build.gradle.kts create mode 100644 build-logic/kotlin-plugins/src/main/kotlin/dev.msfjarvis.claw.kotlin-android.gradle.kts create mode 100644 build-logic/kotlin-plugins/src/main/kotlin/dev.msfjarvis.claw.kotlin-common.gradle.kts create mode 100644 build-logic/kotlin-plugins/src/main/kotlin/dev.msfjarvis.claw.kotlin-kapt.gradle.kts create mode 100644 build-logic/kotlin-plugins/src/main/kotlin/dev.msfjarvis.claw.kotlin-library.gradle.kts create mode 100644 build-logic/kotlin-plugins/src/main/kotlin/dev.msfjarvis.claw.spotless.gradle.kts create mode 100644 build-logic/kotlin-plugins/src/main/kotlin/dev.msfjarvis.claw.versions.gradle.kts create mode 100644 build-logic/settings.gradle.kts diff --git a/android/build.gradle.kts b/android/build.gradle.kts index 815d4ee2..9321a515 100644 --- a/android/build.gradle.kts +++ b/android/build.gradle.kts @@ -1,51 +1,20 @@ @file:OptIn(org.jetbrains.compose.ExperimentalComposeLibrary::class) @file:Suppress("DSL_SCOPE_VIOLATION", "UnstableApiUsage") -import com.android.build.api.artifact.SingleArtifact -import com.android.build.api.variant.BuiltArtifactsLoader -import java.nio.file.Files -import java.nio.file.Paths -import java.nio.file.StandardCopyOption -import java.util.Properties -import org.gradle.api.DefaultTask -import org.gradle.api.file.DirectoryProperty -import org.gradle.api.provider.Property -import org.gradle.api.tasks.CacheableTask -import org.gradle.api.tasks.InputFiles -import org.gradle.api.tasks.Internal -import org.gradle.api.tasks.PathSensitive -import org.gradle.api.tasks.PathSensitivity -import org.gradle.api.tasks.TaskAction - plugins { - alias(libs.plugins.android.application) - alias(libs.plugins.kotlin.android) - alias(libs.plugins.kotlin.kapt) + id("dev.msfjarvis.claw.android-application") + id("dev.msfjarvis.claw.rename-artifacts") + id("dev.msfjarvis.claw.kotlin-android") + id("dev.msfjarvis.claw.kotlin-kapt") alias(libs.plugins.compose) alias(libs.plugins.hilt) } -@CacheableTask -abstract class CollectApksTask : DefaultTask() { - - @get:InputFiles @get:PathSensitive(PathSensitivity.NONE) abstract val apkFolder: DirectoryProperty - @get:Input abstract val variantName: Property - @get:Internal abstract val builtArtifactsLoader: Property - @get:OutputDirectory abstract val outputDirectory: DirectoryProperty - - @TaskAction - fun taskAction() { - val outputDir = outputDirectory.asFile.get() - outputDir.mkdirs() - val builtArtifacts = - builtArtifactsLoader.get().load(apkFolder.get()) ?: throw RuntimeException("Cannot load APKs") - builtArtifacts.elements.forEach { artifact -> - Files.copy( - Paths.get(artifact.outputFile), - outputDir.resolve("Claw-${variantName.get()}-${artifact.versionName}.apk").toPath(), - StandardCopyOption.REPLACE_EXISTING, - ) - } +android { + defaultConfig { + applicationId = "dev.msfjarvis.claw.android" + versionCode = 1 + versionName = "1.0" } } @@ -71,55 +40,3 @@ dependencies { implementation(libs.kotlinx.serialization.json) implementation(libs.retrofit.kotlinxSerializationConverter) { isTransitive = false } } - -android { - compileSdk = 31 - defaultConfig { - applicationId = "dev.msfjarvis.claw.android" - minSdk = 23 - targetSdk = 31 - versionCode = 1 - versionName = "1.0" - } - val keystoreConfigFile = rootProject.layout.projectDirectory.file("keystore.properties") - if (keystoreConfigFile.asFile.exists()) { - val contents = providers.fileContents(keystoreConfigFile).asText - val keystoreProperties = Properties() - keystoreProperties.load(contents.get().byteInputStream()) - signingConfigs { - register("release") { - keyAlias = keystoreProperties["keyAlias"] as String - keyPassword = keystoreProperties["keyPassword"] as String - storeFile = rootProject.file(keystoreProperties["storeFile"] as String) - storePassword = keystoreProperties["storePassword"] as String - } - } - buildTypes.all { signingConfig = signingConfigs.getByName("release") } - } - buildFeatures { buildConfig = true } - buildTypes { - named("release") { - isMinifyEnabled = false - setProguardFiles(listOf("proguard-android-optimize.txt", "proguard-rules.pro")) - } - } - compileOptions { - sourceCompatibility = JavaVersion.VERSION_11 - targetCompatibility = JavaVersion.VERSION_11 - } - dependenciesInfo { - includeInBundle = false - includeInApk = false - } -} - -androidComponents { - onVariants { variant -> - project.tasks.register("collect${variant.name.capitalize()}Apks") { - variantName.set(variant.name) - apkFolder.set(variant.artifacts.get(SingleArtifact.APK)) - builtArtifactsLoader.set(variant.artifacts.getBuiltArtifactsLoader()) - outputDirectory.set(project.layout.projectDirectory.dir("outputs")) - } - } -} diff --git a/api/build.gradle.kts b/api/build.gradle.kts index 0b0d7c49..844201e1 100644 --- a/api/build.gradle.kts +++ b/api/build.gradle.kts @@ -1,6 +1,9 @@ @file:Suppress("DSL_SCOPE_VIOLATION", "UnstableApiUsage") -plugins { alias(libs.plugins.kotlin.jvm) } +plugins { + kotlin("jvm") + id("dev.msfjarvis.claw.kotlin-library") +} dependencies { api(projects.model) diff --git a/build-logic/.gitignore b/build-logic/.gitignore new file mode 100644 index 00000000..42afabfd --- /dev/null +++ b/build-logic/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/build-logic/android-plugins/build.gradle.kts b/build-logic/android-plugins/build.gradle.kts new file mode 100644 index 00000000..22f54e17 --- /dev/null +++ b/build-logic/android-plugins/build.gradle.kts @@ -0,0 +1,24 @@ +/* + * Copyright © 2014-2021 The Android Password Store Authors. All Rights Reserved. + * SPDX-License-Identifier: GPL-3.0-only + */ + +import org.gradle.api.JavaVersion +import org.gradle.api.tasks.compile.JavaCompile +import org.gradle.kotlin.dsl.withType +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile + +plugins { `kotlin-dsl` } + +afterEvaluate { + tasks.withType().configureEach { + sourceCompatibility = JavaVersion.VERSION_11.toString() + targetCompatibility = JavaVersion.VERSION_11.toString() + } + + tasks.withType().configureEach { + kotlinOptions { jvmTarget = JavaVersion.VERSION_11.toString() } + } +} + +dependencies { implementation(libs.build.agp) } diff --git a/build-logic/android-plugins/src/main/kotlin/artifacts/CollectApksTask.kt b/build-logic/android-plugins/src/main/kotlin/artifacts/CollectApksTask.kt new file mode 100644 index 00000000..a3da21e4 --- /dev/null +++ b/build-logic/android-plugins/src/main/kotlin/artifacts/CollectApksTask.kt @@ -0,0 +1,44 @@ +package artifacts + +import com.android.build.api.variant.BuiltArtifactsLoader +import java.nio.file.Files +import java.nio.file.Paths +import java.nio.file.StandardCopyOption +import org.gradle.api.DefaultTask +import org.gradle.api.file.DirectoryProperty +import org.gradle.api.provider.Property +import org.gradle.api.tasks.CacheableTask +import org.gradle.api.tasks.Input +import org.gradle.api.tasks.InputFiles +import org.gradle.api.tasks.Internal +import org.gradle.api.tasks.OutputDirectory +import org.gradle.api.tasks.PathSensitive +import org.gradle.api.tasks.PathSensitivity +import org.gradle.api.tasks.TaskAction + +/** Task to collect APKs in a given [outputDirectory]. */ +@CacheableTask +abstract class CollectApksTask : DefaultTask() { + @get:InputFiles @get:PathSensitive(PathSensitivity.NONE) abstract val apkFolder: DirectoryProperty + + @get:Input abstract val variantName: Property + + @get:Internal abstract val builtArtifactsLoader: Property + + @get:OutputDirectory abstract val outputDirectory: DirectoryProperty + + @TaskAction + fun run() { + val outputDir = outputDirectory.asFile.get() + outputDir.mkdirs() + val builtArtifacts = + builtArtifactsLoader.get().load(apkFolder.get()) ?: throw RuntimeException("Cannot load APKs") + builtArtifacts.elements.forEach { artifact -> + Files.copy( + Paths.get(artifact.outputFile), + outputDir.resolve("Claw-${variantName.get()}-${artifact.versionName}.apk").toPath(), + StandardCopyOption.REPLACE_EXISTING, + ) + } + } +} diff --git a/build-logic/android-plugins/src/main/kotlin/artifacts/CollectBundleTask.kt b/build-logic/android-plugins/src/main/kotlin/artifacts/CollectBundleTask.kt new file mode 100644 index 00000000..8789e94e --- /dev/null +++ b/build-logic/android-plugins/src/main/kotlin/artifacts/CollectBundleTask.kt @@ -0,0 +1,33 @@ +package artifacts + +import java.nio.file.Files +import java.nio.file.StandardCopyOption +import org.gradle.api.DefaultTask +import org.gradle.api.file.DirectoryProperty +import org.gradle.api.file.RegularFileProperty +import org.gradle.api.provider.Property +import org.gradle.api.tasks.Input +import org.gradle.api.tasks.InputFile +import org.gradle.api.tasks.OutputDirectory +import org.gradle.api.tasks.TaskAction + +abstract class CollectBundleTask : DefaultTask() { + @get:InputFile abstract val bundleFile: RegularFileProperty + + @get:Input abstract val variantName: Property + + @get:Input abstract val versionName: Property + + @get:OutputDirectory abstract val outputDirectory: DirectoryProperty + + @TaskAction + fun taskAction() { + val outputDir = outputDirectory.asFile.get() + outputDir.mkdirs() + Files.copy( + bundleFile.get().asFile.toPath(), + outputDir.resolve("Claw-${variantName.get()}-${versionName.get()}.aab").toPath(), + StandardCopyOption.REPLACE_EXISTING, + ) + } +} diff --git a/build-logic/android-plugins/src/main/kotlin/dev.msfjarvis.claw.android-application.gradle.kts b/build-logic/android-plugins/src/main/kotlin/dev.msfjarvis.claw.android-application.gradle.kts new file mode 100644 index 00000000..0fab3627 --- /dev/null +++ b/build-logic/android-plugins/src/main/kotlin/dev.msfjarvis.claw.android-application.gradle.kts @@ -0,0 +1,41 @@ +/* + * Copyright © 2014-2021 The Android Password Store Authors. All Rights Reserved. + * SPDX-License-Identifier: GPL-3.0-only + */ +@file:Suppress("UnstableApiUsage") + +import signing.configureBuildSigning + +plugins { + id("com.android.application") + id("dev.msfjarvis.claw.android-common") +} + +android { + adbOptions.installOptions("--user 0") + + dependenciesInfo { + includeInBundle = false + includeInApk = false + } + + buildFeatures { buildConfig = true } + + buildTypes { + named("release") { + setProguardFiles( + listOf( + "proguard-android-optimize.txt", + "proguard-rules.pro", + "proguard-rules-missing-classes.pro", + ) + ) + } + named("debug") { + applicationIdSuffix = ".debug" + versionNameSuffix = "-debug" + isMinifyEnabled = false + } + } + project.configureBuildSigning() +} diff --git a/build-logic/android-plugins/src/main/kotlin/dev.msfjarvis.claw.android-common.gradle.kts b/build-logic/android-plugins/src/main/kotlin/dev.msfjarvis.claw.android-common.gradle.kts new file mode 100644 index 00000000..e431cb0a --- /dev/null +++ b/build-logic/android-plugins/src/main/kotlin/dev.msfjarvis.claw.android-common.gradle.kts @@ -0,0 +1,40 @@ +/* + * Copyright © 2014-2021 The Android Password Store Authors. All Rights Reserved. + * SPDX-License-Identifier: GPL-3.0-only + */ +@file:Suppress("UnstableApiUsage") + +import com.android.build.gradle.TestedExtension + +extensions.configure { + setCompileSdkVersion(31) + defaultConfig { + minSdk = 23 + targetSdk = 31 + } + + sourceSets { + named("main") { java.srcDirs("src/main/kotlin") } + named("test") { java.srcDirs("src/test/kotlin") } + named("androidTest") { java.srcDirs("src/androidTest/kotlin") } + } + + packagingOptions { + resources.excludes.add("**/*.version") + resources.excludes.add("**/*.txt") + resources.excludes.add("**/*.kotlin_module") + resources.excludes.add("**/plugin.properties") + resources.excludes.add("**/META-INF/AL2.0") + resources.excludes.add("**/META-INF/LGPL2.1") + } + + compileOptions { + sourceCompatibility = JavaVersion.VERSION_11 + targetCompatibility = JavaVersion.VERSION_11 + } + + testOptions { + animationsDisabled = true + unitTests.isReturnDefaultValues = true + } +} diff --git a/build-logic/android-plugins/src/main/kotlin/dev.msfjarvis.claw.android-library.gradle.kts b/build-logic/android-plugins/src/main/kotlin/dev.msfjarvis.claw.android-library.gradle.kts new file mode 100644 index 00000000..4181f556 --- /dev/null +++ b/build-logic/android-plugins/src/main/kotlin/dev.msfjarvis.claw.android-library.gradle.kts @@ -0,0 +1,11 @@ +/* + * Copyright © 2014-2021 The Android Password Store Authors. All Rights Reserved. + * SPDX-License-Identifier: GPL-3.0-only + */ + +plugins { + id("com.android.library") + id("dev.msfjarvis.claw.android-common") +} + +android { defaultConfig { consumerProguardFiles("consumer-rules.pro") } } diff --git a/build-logic/android-plugins/src/main/kotlin/dev.msfjarvis.claw.rename-artifacts.gradle.kts b/build-logic/android-plugins/src/main/kotlin/dev.msfjarvis.claw.rename-artifacts.gradle.kts new file mode 100644 index 00000000..9c74c360 --- /dev/null +++ b/build-logic/android-plugins/src/main/kotlin/dev.msfjarvis.claw.rename-artifacts.gradle.kts @@ -0,0 +1,22 @@ +import artifacts.CollectApksTask +import artifacts.CollectBundleTask +import com.android.build.api.artifact.SingleArtifact + +plugins { id("com.android.application") } + +androidComponents { + onVariants { variant -> + project.tasks.register("collect${variant.name.capitalize()}Apks") { + variantName.set(variant.name) + apkFolder.set(variant.artifacts.get(SingleArtifact.APK)) + builtArtifactsLoader.set(variant.artifacts.getBuiltArtifactsLoader()) + outputDirectory.set(project.layout.projectDirectory.dir("outputs")) + } + project.tasks.register("collect${variant.name.capitalize()}Bundle") { + variantName.set(variant.name) + versionName.set(android.defaultConfig.versionName) + bundleFile.set(variant.artifacts.get(SingleArtifact.BUNDLE)) + outputDirectory.set(project.layout.projectDirectory.dir("outputs")) + } + } +} diff --git a/build-logic/android-plugins/src/main/kotlin/signing/AppSigning.kt b/build-logic/android-plugins/src/main/kotlin/signing/AppSigning.kt new file mode 100644 index 00000000..115f0f56 --- /dev/null +++ b/build-logic/android-plugins/src/main/kotlin/signing/AppSigning.kt @@ -0,0 +1,37 @@ +/* + * Copyright © 2014-2021 The Android Password Store Authors. All Rights Reserved. + * SPDX-License-Identifier: GPL-3.0-only + */ + +package signing + +import com.android.build.gradle.internal.dsl.BaseAppModuleExtension +import java.util.Properties +import org.gradle.api.Project +import org.gradle.kotlin.dsl.configure +import org.gradle.kotlin.dsl.provideDelegate + +private const val KEYSTORE_CONFIG_PATH = "keystore.properties" + +/** Configure signing for all build types. */ +@Suppress("UnstableApiUsage") +internal fun Project.configureBuildSigning() { + val keystoreConfigFile = rootProject.layout.projectDirectory.file(KEYSTORE_CONFIG_PATH) + if (keystoreConfigFile.asFile.exists()) { + extensions.configure { + val contents = providers.fileContents(keystoreConfigFile).asText + val keystoreProperties = Properties() + keystoreProperties.load(contents.get().byteInputStream()) + signingConfigs { + register("release") { + keyAlias = keystoreProperties["keyAlias"] as String + keyPassword = keystoreProperties["keyPassword"] as String + storeFile = rootProject.file(keystoreProperties["storeFile"] as String) + storePassword = keystoreProperties["storePassword"] as String + } + } + val signingConfig = signingConfigs.getByName("release") + buildTypes.all { setSigningConfig(signingConfig) } + } + } +} diff --git a/build-logic/kotlin-plugins/build.gradle.kts b/build-logic/kotlin-plugins/build.gradle.kts new file mode 100644 index 00000000..79de4742 --- /dev/null +++ b/build-logic/kotlin-plugins/build.gradle.kts @@ -0,0 +1,31 @@ +/* + * Copyright © 2014-2021 The Android Password Store Authors. All Rights Reserved. + * SPDX-License-Identifier: GPL-3.0-only + */ + +import org.gradle.api.JavaVersion +import org.gradle.api.tasks.compile.JavaCompile +import org.gradle.kotlin.dsl.withType +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile + +plugins { `kotlin-dsl` } + +afterEvaluate { + tasks.withType().configureEach { + sourceCompatibility = JavaVersion.VERSION_11.toString() + targetCompatibility = JavaVersion.VERSION_11.toString() + } + + tasks.withType().configureEach { + kotlinOptions { jvmTarget = JavaVersion.VERSION_11.toString() } + } +} + +dependencies { + implementation(libs.build.agp) + implementation(libs.build.kotlin.gradle) + implementation(libs.build.kotlin.serialization) + implementation(libs.build.spotless) + implementation(libs.build.vcu) + implementation(libs.build.versions) +} diff --git a/build-logic/kotlin-plugins/src/main/kotlin/dev.msfjarvis.claw.kotlin-android.gradle.kts b/build-logic/kotlin-plugins/src/main/kotlin/dev.msfjarvis.claw.kotlin-android.gradle.kts new file mode 100644 index 00000000..1f578be4 --- /dev/null +++ b/build-logic/kotlin-plugins/src/main/kotlin/dev.msfjarvis.claw.kotlin-android.gradle.kts @@ -0,0 +1,9 @@ +/* + * Copyright © 2014-2021 The Android Password Store Authors. All Rights Reserved. + * SPDX-License-Identifier: GPL-3.0-only + */ + +plugins { + kotlin("android") + id("dev.msfjarvis.claw.kotlin-common") +} diff --git a/build-logic/kotlin-plugins/src/main/kotlin/dev.msfjarvis.claw.kotlin-common.gradle.kts b/build-logic/kotlin-plugins/src/main/kotlin/dev.msfjarvis.claw.kotlin-common.gradle.kts new file mode 100644 index 00000000..e61b03a8 --- /dev/null +++ b/build-logic/kotlin-plugins/src/main/kotlin/dev.msfjarvis.claw.kotlin-common.gradle.kts @@ -0,0 +1,38 @@ +/* + * Copyright © 2014-2021 The Android Password Store Authors. All Rights Reserved. + * SPDX-License-Identifier: GPL-3.0-only + */ + +import org.gradle.api.JavaVersion +import org.gradle.api.tasks.compile.JavaCompile +import org.gradle.api.tasks.testing.Test +import org.gradle.api.tasks.testing.logging.TestLogEvent +import org.gradle.kotlin.dsl.withType +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile + +val additionalCompilerArgs = + listOf( + "-Xopt-in=kotlin.RequiresOptIn", + "-P", + "plugin:androidx.compose.compiler.plugins.kotlin:suppressKotlinVersionCompatibilityCheck=true", + ) + +tasks.withType().configureEach { + sourceCompatibility = JavaVersion.VERSION_11.toString() + targetCompatibility = JavaVersion.VERSION_11.toString() +} + +tasks.withType().configureEach { + kotlinOptions { + allWarningsAsErrors = true + jvmTarget = JavaVersion.VERSION_11.toString() + freeCompilerArgs = freeCompilerArgs + additionalCompilerArgs + languageVersion = "1.5" + } +} + +tasks.withType().configureEach { + maxParallelForks = Runtime.getRuntime().availableProcessors() * 2 + testLogging { events(TestLogEvent.PASSED, TestLogEvent.SKIPPED, TestLogEvent.FAILED) } + doNotTrackState("We want tests to always run even if Gradle thinks otherwise") +} diff --git a/build-logic/kotlin-plugins/src/main/kotlin/dev.msfjarvis.claw.kotlin-kapt.gradle.kts b/build-logic/kotlin-plugins/src/main/kotlin/dev.msfjarvis.claw.kotlin-kapt.gradle.kts new file mode 100644 index 00000000..14542655 --- /dev/null +++ b/build-logic/kotlin-plugins/src/main/kotlin/dev.msfjarvis.claw.kotlin-kapt.gradle.kts @@ -0,0 +1,43 @@ +/* + * Copyright © 2014-2021 The Android Password Store Authors. All Rights Reserved. + * SPDX-License-Identifier: GPL-3.0-only + */ + +import org.gradle.api.Project + +plugins { + kotlin("android") + kotlin("kapt") +} + +afterEvaluate { + kapt { + javacOptions { + if (hasDaggerCompilerDependency()) { + // https://dagger.dev/dev-guide/compiler-options#fastinit-mode + option("-Adagger.fastInit=enabled") + // Enable the better, experimental error messages + // https://github.com/google/dagger/commit/0d2505a727b54f47b8677f42dd4fc5c1924e37f5 + option("-Adagger.experimentalDaggerErrorMessages=enabled") + // Share test components for when we start leveraging Hilt for tests + // https://github.com/google/dagger/releases/tag/dagger-2.34 + option("-Adagger.hilt.shareTestComponents=true") + // KAPT nests errors causing real issues to be suppressed in CI logs + option("-Xmaxerrs", 500) + // Enables per-module validation for faster error detection + // https://github.com/google/dagger/commit/325b516ac6a53d3fc973d247b5231fafda9870a2 + option("-Adagger.moduleBindingValidation=ERROR") + } + } + } +} +// disable kapt tasks for unit tests +tasks.matching { it.name.startsWith("kapt") && it.name.endsWith("UnitTestKotlin") }.configureEach { + enabled = false +} + +fun Project.hasDaggerCompilerDependency(): Boolean { + return configurations.any { + it.dependencies.any { dependency -> dependency.name == "hilt-compiler" } + } +} diff --git a/build-logic/kotlin-plugins/src/main/kotlin/dev.msfjarvis.claw.kotlin-library.gradle.kts b/build-logic/kotlin-plugins/src/main/kotlin/dev.msfjarvis.claw.kotlin-library.gradle.kts new file mode 100644 index 00000000..10f7ae44 --- /dev/null +++ b/build-logic/kotlin-plugins/src/main/kotlin/dev.msfjarvis.claw.kotlin-library.gradle.kts @@ -0,0 +1,6 @@ +/* + * Copyright © 2014-2021 The Android Password Store Authors. All Rights Reserved. + * SPDX-License-Identifier: GPL-3.0-only + */ + +plugins { id("dev.msfjarvis.claw.kotlin-common") } diff --git a/build-logic/kotlin-plugins/src/main/kotlin/dev.msfjarvis.claw.spotless.gradle.kts b/build-logic/kotlin-plugins/src/main/kotlin/dev.msfjarvis.claw.spotless.gradle.kts new file mode 100644 index 00000000..2ec3891a --- /dev/null +++ b/build-logic/kotlin-plugins/src/main/kotlin/dev.msfjarvis.claw.spotless.gradle.kts @@ -0,0 +1,28 @@ +/* + * Copyright © 2014-2021 The Android Password Store Authors. All Rights Reserved. + * SPDX-License-Identifier: GPL-3.0-only + */ + +plugins { id("com.diffplug.spotless") } + +val KTFMT_VERSION = "0.35" + +spotless { + kotlin { + ktfmt(KTFMT_VERSION).googleStyle() + target("**/*.kt") + targetExclude("**/build/") + } + kotlinGradle { + ktfmt(KTFMT_VERSION).googleStyle() + target("**/*.kts") + targetExclude("**/build/") + } + format("xml") { + target("**/*.xml") + targetExclude("**/build/", ".idea/") + trimTrailingWhitespace() + indentWithSpaces() + endWithNewline() + } +} diff --git a/build-logic/kotlin-plugins/src/main/kotlin/dev.msfjarvis.claw.versions.gradle.kts b/build-logic/kotlin-plugins/src/main/kotlin/dev.msfjarvis.claw.versions.gradle.kts new file mode 100644 index 00000000..1d9eb0ee --- /dev/null +++ b/build-logic/kotlin-plugins/src/main/kotlin/dev.msfjarvis.claw.versions.gradle.kts @@ -0,0 +1,27 @@ +import com.github.benmanes.gradle.versions.updates.DependencyUpdatesTask + +plugins { + id("com.github.ben-manes.versions") + id("nl.littlerobots.version-catalog-update") +} + +fun isNonStable(version: String): Boolean { + val stableKeyword = listOf("RELEASE", "FINAL", "GA").any { version.toUpperCase().contains(it) } + val regex = "^[0-9,.v-]+(-r)?$".toRegex() + val isStable = stableKeyword || regex.matches(version) + return isStable.not() +} + +tasks.withType().configureEach { + rejectVersionIf { + when (candidate.group) { + "com.android.application", "com.android.library" -> true + else -> isNonStable(candidate.version) && !isNonStable(currentVersion) + } + } + checkForGradleUpdate = false + checkBuildEnvironmentConstraints = true + outputFormatter = "json" + outputDir = "build/dependencyUpdates" + reportfileName = "report" +} diff --git a/build-logic/settings.gradle.kts b/build-logic/settings.gradle.kts new file mode 100644 index 00000000..e23f9448 --- /dev/null +++ b/build-logic/settings.gradle.kts @@ -0,0 +1,22 @@ +/* + * Copyright © 2014-2021 The Android Password Store Authors. All Rights Reserved. + * SPDX-License-Identifier: GPL-3.0-only + */ +@file:Suppress("UnstableApiUsage") + +rootProject.name = "build-logic" + +dependencyResolutionManagement { + repositories { + google() + mavenCentral() + gradlePluginPortal() { + content { includeModule("com.github.ben-manes", "gradle-versions-plugin") } + } + } + versionCatalogs { create("libs") { from(files("../gradle/libs.versions.toml")) } } +} + +include("android-plugins") + +include("kotlin-plugins") diff --git a/build.gradle.kts b/build.gradle.kts index ac80b12d..5d2398df 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,7 +1,5 @@ @file:Suppress("DSL_SCOPE_VIOLATION", "UnstableApiUsage") -import com.github.benmanes.gradle.versions.updates.DependencyUpdatesTask - buildscript { repositories { maven { @@ -9,44 +7,14 @@ buildscript { content { includeModule("com.android.tools", "r8") } } } - dependencies { classpath(libs.r8) } + dependencies { + classpath(libs.r8) + classpath(libs.javapoet) + } } plugins { - alias(libs.plugins.spotless) - alias(libs.plugins.versions) - alias(libs.plugins.vcu) -} - -fun isNonStable(version: String): Boolean { - val stableKeyword = listOf("RELEASE", "FINAL", "GA").any { version.toUpperCase().contains(it) } - val regex = "^[0-9,.v-]+(-r)?$".toRegex() - val isStable = stableKeyword || regex.matches(version) - return isStable.not() -} - -tasks.withType().configureEach { - rejectVersionIf { - when (candidate.group) { - "com.android.application", "com.android.library" -> true - else -> isNonStable(candidate.version) && !isNonStable(currentVersion) - } - } - checkForGradleUpdate = false - checkBuildEnvironmentConstraints = true - outputFormatter = "json" - outputDir = "build/dependencyUpdates" - reportfileName = "report" -} - -spotless { - kotlin { - target("**/*.kt") - targetExclude("**/build/**") - ktfmt("0.35").googleStyle() - } - kotlinGradle { - target("**/*.gradle.kts") - ktfmt("0.35").googleStyle() - } + id("dev.msfjarvis.claw.spotless") + id("dev.msfjarvis.claw.versions") + id("dev.msfjarvis.claw.kotlin-common") } diff --git a/common/build.gradle.kts b/common/build.gradle.kts index 097e623a..863b0b94 100644 --- a/common/build.gradle.kts +++ b/common/build.gradle.kts @@ -4,9 +4,10 @@ import org.jetbrains.compose.compose plugins { - alias(libs.plugins.kotlin.multiplatform) - alias(libs.plugins.android.library) + kotlin("multiplatform") alias(libs.plugins.compose) + id("dev.msfjarvis.claw.kotlin-common") + id("dev.msfjarvis.claw.android-library") } kotlin { @@ -38,13 +39,8 @@ kotlin { android { buildFeatures { androidResources = true } - compileSdk = 31 sourceSets["main"].apply { manifest.srcFile("src/androidMain/AndroidManifest.xml") res.srcDirs("src/commonMain/resources") } - defaultConfig { - minSdk = 23 - targetSdk = 31 - } } diff --git a/database/build.gradle.kts b/database/build.gradle.kts index ef75e431..6173b9be 100644 --- a/database/build.gradle.kts +++ b/database/build.gradle.kts @@ -1,20 +1,15 @@ @file:Suppress("DSL_SCOPE_VIOLATION", "UnstableApiUsage") plugins { - alias(libs.plugins.kotlin.multiplatform) - alias(libs.plugins.android.library) + kotlin("multiplatform") alias(libs.plugins.sqldelight) + id("dev.msfjarvis.claw.kotlin-common") + id("dev.msfjarvis.claw.android-library") } kotlin { android() - jvm("desktop") { - compilations.all { - kotlinOptions.jvmTarget = "11" - kotlinOptions.freeCompilerArgs = - kotlinOptions.freeCompilerArgs + listOf("-Xopt-in=kotlin.RequiresOptIn") - } - } + jvm("desktop") sourceSets["androidMain"].apply { dependencies { implementation(libs.sqldelight.androidDriver) } dependsOn(sourceSets["androidAndroidTestRelease"]) @@ -28,15 +23,7 @@ kotlin { } } -android { - compileSdk = 31 - sourceSets["main"].manifest.srcFile("src/androidMain/AndroidManifest.xml") - defaultConfig { - minSdk = 23 - targetSdk = 31 - consumerProguardFiles("consumer-rules.pro") - } -} +android { sourceSets["main"].manifest.srcFile("src/androidMain/AndroidManifest.xml") } sqldelight { database("LobstersDatabase") { diff --git a/desktop/build.gradle.kts b/desktop/build.gradle.kts index f6bdf558..2e3d757d 100644 --- a/desktop/build.gradle.kts +++ b/desktop/build.gradle.kts @@ -4,8 +4,9 @@ import org.jetbrains.compose.compose import org.jetbrains.compose.desktop.application.dsl.TargetFormat plugins { - alias(libs.plugins.kotlin.multiplatform) + kotlin("multiplatform") alias(libs.plugins.compose) + id("dev.msfjarvis.claw.kotlin-common") } group = "dev.msfjarvis.claw" diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 7d70b0bc..53a70ad9 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,6 +1,5 @@ [versions] accompanist = "0.24.5-alpha" -agp = "7.0.4" aurora = "1.1.0" coroutines = "1.6.1" hilt = "2.41" @@ -23,6 +22,12 @@ androidx-paging-compose = "androidx.paging:paging-compose:1.0.0-alpha14" aurora-component = { module = "org.pushing-pixels:aurora-component", version.ref = "aurora" } aurora-theming = { module = "org.pushing-pixels:aurora-theming", version.ref = "aurora" } aurora-window = { module = "org.pushing-pixels:aurora-window", version.ref = "aurora" } +build-agp = "com.android.tools.build:gradle:7.0.4" +build-kotlin-gradle = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin", version.ref = "kotlin" } +build-kotlin-serialization = { module = "org.jetbrains.kotlin:kotlin-serialization", version.ref = "kotlin" } +build-spotless = "com.diffplug.spotless:spotless-plugin-gradle:6.4.1" +build-vcu = "nl.littlerobots.version-catalog-update:nl.littlerobots.version-catalog-update.gradle.plugin:0.3.1" +build-versions = "com.github.ben-manes:gradle-versions-plugin:0.42.0" coil-compose = "io.coil-kt:coil-compose:2.0.0-rc02" compose-richtext-markdown = { module = "com.halilibo.compose-richtext:richtext-commonmark", version.ref = "richtext" } compose-richtext-material = { module = "com.halilibo.compose-richtext:richtext-ui-material", version.ref = "richtext" } @@ -30,6 +35,7 @@ compose-richtext-ui = { module = "com.halilibo.compose-richtext:richtext-ui", ve copydown = "io.github.furstenheim:copy_down:1.0" dagger-hilt-android = { module = "com.google.dagger:hilt-android", version.ref = "hilt" } dagger-hilt-compiler = { module = "com.google.dagger:hilt-compiler", version.ref = "hilt" } +javapoet = "com.squareup:javapoet:1.13.0" kamel-image = "com.alialbaali.kamel:kamel-image:0.3.0" kotlin-coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "coroutines" } kotlinx-serialization-core = { module = "org.jetbrains.kotlinx:kotlinx-serialization-core", version.ref = "serialization" } @@ -44,16 +50,6 @@ sqldelight-jvmDriver = { module = "com.squareup.sqldelight:sqlite-driver", versi testing-mockWebServer = "com.squareup.okhttp3:mockwebserver3-junit4:5.0.0-alpha.6" [plugins] -android-application = { id = "com.android.application", version.ref = "agp" } -android-library = { id = "com.android.library", version.ref = "agp" } compose = "org.jetbrains.compose:1.1.1" hilt = { id = "com.google.dagger.hilt.android", version.ref = "hilt" } -kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" } -kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" } -kotlin-kapt = { id = "org.jetbrains.kotlin.kapt", version.ref = "kotlin" } -kotlin-multiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" } -kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" } -spotless = "com.diffplug.spotless:6.4.1" sqldelight = "com.squareup.sqldelight:1.5.3" -vcu = "nl.littlerobots.version-catalog-update:0.3.1" -versions = "com.github.ben-manes.versions:0.42.0" diff --git a/model/build.gradle.kts b/model/build.gradle.kts index 417dbb6d..200a7eac 100644 --- a/model/build.gradle.kts +++ b/model/build.gradle.kts @@ -1,25 +1,18 @@ @file:Suppress("DSL_SCOPE_VIOLATION", "UnstableApiUsage") plugins { - alias(libs.plugins.kotlin.multiplatform) - alias(libs.plugins.kotlin.serialization) - alias(libs.plugins.android.library) + kotlin("multiplatform") + kotlin("plugin.serialization") + id("dev.msfjarvis.claw.kotlin-common") + id("dev.msfjarvis.claw.android-library") } kotlin { android() - jvm { compilations.all { kotlinOptions.jvmTarget = "11" } } + jvm() sourceSets["commonMain"].apply { dependencies { implementation(libs.kotlinx.serialization.core) } } } -android { - compileSdk = 31 - sourceSets["main"].manifest.srcFile("src/androidMain/AndroidManifest.xml") - defaultConfig { - minSdk = 23 - targetSdk = 31 - consumerProguardFiles("consumer-rules.pro") - } -} +android { sourceSets["main"].manifest.srcFile("src/androidMain/AndroidManifest.xml") } diff --git a/settings.gradle.kts b/settings.gradle.kts index 6031164c..c3c55d2d 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -2,6 +2,7 @@ pluginManagement { repositories { + includeBuild("build-logic") gradlePluginPortal() mavenCentral() maven("https://maven.pkg.jetbrains.space/public/p/compose/dev") {