gradle: migrate to build-logic

This commit is contained in:
Harsh Shandilya 2022-04-05 19:10:34 +05:30
parent 4cef244d71
commit 3097eaf82f
No known key found for this signature in database
GPG key ID: 366D7BBAD1031E80
26 changed files with 501 additions and 182 deletions

1
build-logic/.gitignore vendored Normal file
View file

@ -0,0 +1 @@
/build

View file

@ -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<JavaCompile>().configureEach {
sourceCompatibility = JavaVersion.VERSION_11.toString()
targetCompatibility = JavaVersion.VERSION_11.toString()
}
tasks.withType<KotlinCompile>().configureEach {
kotlinOptions { jvmTarget = JavaVersion.VERSION_11.toString() }
}
}
dependencies { implementation(libs.build.agp) }

View file

@ -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<String>
@get:Internal abstract val builtArtifactsLoader: Property<BuiltArtifactsLoader>
@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,
)
}
}
}

View file

@ -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<String>
@get:Input abstract val versionName: Property<String>
@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,
)
}
}

View file

@ -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()
}

View file

@ -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<TestedExtension> {
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
}
}

View file

@ -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") } }

View file

@ -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<CollectApksTask>("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<CollectBundleTask>("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"))
}
}
}

View file

@ -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<BaseAppModuleExtension> {
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) }
}
}
}

View file

@ -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<JavaCompile>().configureEach {
sourceCompatibility = JavaVersion.VERSION_11.toString()
targetCompatibility = JavaVersion.VERSION_11.toString()
}
tasks.withType<KotlinCompile>().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)
}

View file

@ -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")
}

View file

@ -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<JavaCompile>().configureEach {
sourceCompatibility = JavaVersion.VERSION_11.toString()
targetCompatibility = JavaVersion.VERSION_11.toString()
}
tasks.withType<KotlinCompile>().configureEach {
kotlinOptions {
allWarningsAsErrors = true
jvmTarget = JavaVersion.VERSION_11.toString()
freeCompilerArgs = freeCompilerArgs + additionalCompilerArgs
languageVersion = "1.5"
}
}
tasks.withType<Test>().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")
}

View file

@ -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" }
}
}

View file

@ -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") }

View file

@ -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()
}
}

View file

@ -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<DependencyUpdatesTask>().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"
}

View file

@ -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")