mirror of
https://github.com/msfjarvis/compose-lobsters
synced 2025-08-15 19:17:02 +05:30
refactor(build-logic): make everything top-level
This commit is contained in:
parent
f48ef0206f
commit
1267cf81e3
21 changed files with 48 additions and 88 deletions
|
@ -0,0 +1,102 @@
|
|||
/*
|
||||
* Copyright © 2022 Harsh Shandilya.
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
* https://opensource.org/licenses/MIT.
|
||||
*/
|
||||
@file:Suppress("UnstableApiUsage")
|
||||
|
||||
package dev.msfjarvis.claw.gradle
|
||||
|
||||
import com.android.build.api.dsl.LibraryExtension
|
||||
import com.android.build.api.dsl.Lint
|
||||
import com.android.build.api.variant.ApplicationAndroidComponentsExtension
|
||||
import com.android.build.api.variant.LibraryAndroidComponentsExtension
|
||||
import com.android.build.gradle.BaseExtension
|
||||
import com.android.build.gradle.internal.dsl.BaseAppModuleExtension
|
||||
import org.gradle.android.AndroidCacheFixPlugin
|
||||
import org.gradle.api.JavaVersion
|
||||
import org.gradle.api.Plugin
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.kotlin.dsl.apply
|
||||
import org.gradle.kotlin.dsl.findByType
|
||||
|
||||
private const val SLIM_TESTS_PROPERTY = "slimTests"
|
||||
|
||||
class AndroidCommonPlugin : Plugin<Project> {
|
||||
|
||||
private companion object {
|
||||
const val COMPILE_SDK = 33
|
||||
const val MIN_SDK = 26
|
||||
const val TARGET_SDK = 33
|
||||
}
|
||||
|
||||
override fun apply(project: Project) {
|
||||
project.configureSlimTests()
|
||||
project.pluginManager.apply(AndroidCacheFixPlugin::class)
|
||||
project.extensions.findByType<BaseExtension>()?.run {
|
||||
compileSdkVersion(COMPILE_SDK)
|
||||
defaultConfig {
|
||||
minSdk = MIN_SDK
|
||||
targetSdk = TARGET_SDK
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
project.extensions.findByType<BaseAppModuleExtension>()?.run { lint.configureLint(project) }
|
||||
project.extensions.findByType<LibraryExtension>()?.run { lint.configureLint(project) }
|
||||
}
|
||||
}
|
||||
|
||||
private fun Lint.configureLint(project: Project) {
|
||||
abortOnError = false
|
||||
checkReleaseBuilds = false
|
||||
warningsAsErrors = false
|
||||
disable.add("DialogFragmentCallbacksDetector")
|
||||
baseline = project.file("lint-baseline.xml")
|
||||
}
|
||||
|
||||
/**
|
||||
* When the "slimTests" project property is provided, disable the unit test tasks on `release` build
|
||||
* type and `nonFree` product flavor to avoid running the same tests repeatedly in different build
|
||||
* variants.
|
||||
*
|
||||
* Examples: `./gradlew test -PslimTests` will run unit tests for `nonFreeDebug` and `debug` build
|
||||
* variants in Android App and Library projects, and all tests in JVM projects.
|
||||
*/
|
||||
private fun Project.configureSlimTests() {
|
||||
if (providers.gradleProperty(SLIM_TESTS_PROPERTY).isPresent) {
|
||||
// Disable unit test tasks on the release build type for Android Library projects
|
||||
extensions.findByType<LibraryAndroidComponentsExtension>()?.run {
|
||||
beforeVariants(selector().withBuildType("release")) {
|
||||
it.enableUnitTest = false
|
||||
it.enableAndroidTest = false
|
||||
}
|
||||
}
|
||||
|
||||
// Disable unit test tasks on the release build type for Android Application projects.
|
||||
extensions.findByType<ApplicationAndroidComponentsExtension>()?.run {
|
||||
beforeVariants(selector().withBuildType("release")) {
|
||||
it.enableUnitTest = false
|
||||
it.enableAndroidTest = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* Copyright © 2022 Harsh Shandilya.
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
* https://opensource.org/licenses/MIT.
|
||||
*/
|
||||
@file:Suppress("UnstableApiUsage")
|
||||
|
||||
package dev.msfjarvis.claw.gradle
|
||||
|
||||
import com.android.build.gradle.AppPlugin
|
||||
import com.android.build.gradle.internal.dsl.BaseAppModuleExtension
|
||||
import dev.msfjarvis.claw.gradle.signing.configureBuildSigning
|
||||
import org.gradle.api.Plugin
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.kotlin.dsl.apply
|
||||
import org.gradle.kotlin.dsl.getByType
|
||||
|
||||
@Suppress("Unused")
|
||||
class ApplicationPlugin : Plugin<Project> {
|
||||
|
||||
override fun apply(project: Project) {
|
||||
project.pluginManager.apply(AppPlugin::class)
|
||||
project.pluginManager.apply(AndroidCommonPlugin::class)
|
||||
project.extensions.getByType<BaseAppModuleExtension>().run {
|
||||
adbOptions.installOptions("--user 0")
|
||||
|
||||
dependenciesInfo {
|
||||
includeInBundle = false
|
||||
includeInApk = false
|
||||
}
|
||||
|
||||
buildFeatures {
|
||||
viewBinding = true
|
||||
buildConfig = true
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
named("release") {
|
||||
isMinifyEnabled = true
|
||||
setProguardFiles(
|
||||
listOf(
|
||||
"proguard-android-optimize.pro",
|
||||
"proguard-rules.pro",
|
||||
"proguard-rules-missing-classes.pro",
|
||||
)
|
||||
)
|
||||
}
|
||||
named("debug") {
|
||||
applicationIdSuffix = ".debug"
|
||||
versionNameSuffix = "-debug"
|
||||
isMinifyEnabled = false
|
||||
}
|
||||
}
|
||||
|
||||
project.configureBuildSigning()
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Copyright © 2022 Harsh Shandilya.
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
* https://opensource.org/licenses/MIT.
|
||||
*/
|
||||
package dev.msfjarvis.claw.gradle
|
||||
|
||||
import com.github.benmanes.gradle.versions.VersionsPlugin
|
||||
import com.github.benmanes.gradle.versions.updates.DependencyUpdatesTask
|
||||
import nl.littlerobots.vcu.plugin.VersionCatalogUpdateExtension
|
||||
import nl.littlerobots.vcu.plugin.VersionCatalogUpdatePlugin
|
||||
import org.gradle.api.Plugin
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.kotlin.dsl.apply
|
||||
import org.gradle.kotlin.dsl.getByType
|
||||
import org.gradle.kotlin.dsl.withType
|
||||
|
||||
@Suppress("Unused")
|
||||
class DependencyUpdatesPlugin : Plugin<Project> {
|
||||
override fun apply(project: Project) {
|
||||
project.pluginManager.apply(VersionsPlugin::class)
|
||||
project.pluginManager.apply(VersionCatalogUpdatePlugin::class)
|
||||
project.tasks.withType<DependencyUpdatesTask>().configureEach {
|
||||
rejectVersionIf {
|
||||
when (candidate.group) {
|
||||
"com.squareup.okhttp3",
|
||||
"org.jetbrains.kotlin" -> true
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
checkForGradleUpdate = true
|
||||
}
|
||||
project.extensions.getByType<VersionCatalogUpdateExtension>().run {
|
||||
keep.keepUnusedLibraries.set(true)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* Copyright © 2022 Harsh Shandilya.
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
* https://opensource.org/licenses/MIT.
|
||||
*/
|
||||
package dev.msfjarvis.claw.gradle
|
||||
|
||||
import io.gitlab.arturbosch.detekt.DetektPlugin
|
||||
import io.gitlab.arturbosch.detekt.extensions.DetektExtension
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.kotlin.dsl.configure
|
||||
|
||||
object Detekt {
|
||||
private const val TWITTER_RULES_VERSION = "0.0.26"
|
||||
|
||||
fun apply(project: Project) {
|
||||
project.pluginManager.apply(DetektPlugin::class.java)
|
||||
project.extensions.configure<DetektExtension> {
|
||||
debug = project.providers.gradleProperty("debugDetekt").isPresent
|
||||
parallel = true
|
||||
ignoredBuildTypes = listOf("benchmark", "release")
|
||||
basePath = project.layout.projectDirectory.toString()
|
||||
baseline =
|
||||
project.rootProject.layout.projectDirectory
|
||||
.dir("detekt-baselines")
|
||||
.file("${project.name}.xml")
|
||||
.asFile
|
||||
}
|
||||
project.dependencies.add(
|
||||
"detektPlugins",
|
||||
"com.twitter.compose.rules:detekt:$TWITTER_RULES_VERSION",
|
||||
)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* Copyright © 2022 Harsh Shandilya.
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
* https://opensource.org/licenses/MIT.
|
||||
*/
|
||||
package dev.msfjarvis.claw.gradle
|
||||
|
||||
import org.gradle.api.Plugin
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.kotlin.dsl.apply
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinAndroidPluginWrapper
|
||||
|
||||
@Suppress("Unused")
|
||||
class KotlinAndroidPlugin : Plugin<Project> {
|
||||
|
||||
override fun apply(project: Project) {
|
||||
project.pluginManager.run {
|
||||
apply(KotlinAndroidPluginWrapper::class)
|
||||
apply(KotlinCommonPlugin::class)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* Copyright © 2022 Harsh Shandilya.
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
* https://opensource.org/licenses/MIT.
|
||||
*/
|
||||
package dev.msfjarvis.claw.gradle
|
||||
|
||||
import org.gradle.api.JavaVersion
|
||||
import org.gradle.api.Plugin
|
||||
import org.gradle.api.Project
|
||||
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
|
||||
|
||||
@Suppress("Unused")
|
||||
class KotlinCommonPlugin : Plugin<Project> {
|
||||
|
||||
override fun apply(project: Project) {
|
||||
Detekt.apply(project)
|
||||
project.tasks.run {
|
||||
withType<JavaCompile>().configureEach {
|
||||
sourceCompatibility = JavaVersion.VERSION_11.toString()
|
||||
targetCompatibility = JavaVersion.VERSION_11.toString()
|
||||
}
|
||||
withType<KotlinCompile>().configureEach {
|
||||
kotlinOptions {
|
||||
allWarningsAsErrors =
|
||||
false // project.providers.environmentVariable("GITHUB_WORKFLOW").isPresent
|
||||
jvmTarget = JavaVersion.VERSION_11.toString()
|
||||
freeCompilerArgs = freeCompilerArgs + ADDITIONAL_COMPILER_ARGS
|
||||
languageVersion = "1.7"
|
||||
}
|
||||
}
|
||||
withType<Test>().configureEach {
|
||||
maxParallelForks = Runtime.getRuntime().availableProcessors() * 2
|
||||
testLogging { events(TestLogEvent.PASSED, TestLogEvent.SKIPPED, TestLogEvent.FAILED) }
|
||||
useJUnitPlatform()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private companion object {
|
||||
private val ADDITIONAL_COMPILER_ARGS =
|
||||
listOf(
|
||||
"-opt-in=kotlin.RequiresOptIn",
|
||||
)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* Copyright © 2021-2022 Harsh Shandilya.
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
* https://opensource.org/licenses/MIT.
|
||||
*/
|
||||
package dev.msfjarvis.claw.gradle
|
||||
|
||||
import org.gradle.api.Plugin
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.kotlin.dsl.apply
|
||||
import org.gradle.kotlin.dsl.getByType
|
||||
import org.jetbrains.kotlin.gradle.internal.Kapt3GradleSubplugin
|
||||
import org.jetbrains.kotlin.gradle.plugin.KaptExtension
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinAndroidPluginWrapper
|
||||
|
||||
@Suppress("Unused")
|
||||
class KotlinKaptPlugin : Plugin<Project> {
|
||||
|
||||
override fun apply(project: Project) {
|
||||
project.pluginManager.run {
|
||||
apply(KotlinAndroidPluginWrapper::class)
|
||||
apply(Kapt3GradleSubplugin::class)
|
||||
}
|
||||
project.afterEvaluate {
|
||||
project.extensions.getByType<KaptExtension>().run {
|
||||
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")
|
||||
// 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")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
project.tasks
|
||||
.matching { it.name.startsWith("kapt") && it.name.endsWith("UnitTestKotlin") }
|
||||
.configureEach { enabled = false }
|
||||
}
|
||||
|
||||
private fun Project.hasDaggerCompilerDependency(): Boolean {
|
||||
return configurations.any {
|
||||
it.dependencies.any { dependency -> dependency.name == "dagger-compiler" }
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
* Copyright © 2022 Harsh Shandilya.
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
* https://opensource.org/licenses/MIT.
|
||||
*/
|
||||
package dev.msfjarvis.claw.gradle
|
||||
|
||||
import org.gradle.api.Plugin
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.kotlin.dsl.apply
|
||||
|
||||
@Suppress("Unused")
|
||||
class KotlinLibraryPlugin : Plugin<Project> {
|
||||
|
||||
override fun apply(project: Project) {
|
||||
project.pluginManager.apply(KotlinCommonPlugin::class)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
* Copyright © 2022 Harsh Shandilya.
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
* https://opensource.org/licenses/MIT.
|
||||
*/
|
||||
package dev.msfjarvis.claw.gradle
|
||||
|
||||
import com.android.build.gradle.LibraryPlugin
|
||||
import org.gradle.api.Plugin
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.kotlin.dsl.apply
|
||||
|
||||
@Suppress("Unused")
|
||||
class LibraryPlugin : Plugin<Project> {
|
||||
|
||||
override fun apply(project: Project) {
|
||||
project.pluginManager.apply(LibraryPlugin::class)
|
||||
project.pluginManager.apply(AndroidCommonPlugin::class)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* Copyright © 2022 Harsh Shandilya.
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
* https://opensource.org/licenses/MIT.
|
||||
*/
|
||||
package dev.msfjarvis.claw.gradle
|
||||
|
||||
import com.android.build.api.artifact.SingleArtifact
|
||||
import com.android.build.api.variant.ApplicationAndroidComponentsExtension
|
||||
import com.android.build.api.variant.VariantOutputConfiguration
|
||||
import dev.msfjarvis.claw.gradle.artifacts.CollectApksTask
|
||||
import dev.msfjarvis.claw.gradle.artifacts.CollectBundleTask
|
||||
import java.util.Locale
|
||||
import org.gradle.api.Plugin
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.kotlin.dsl.getByType
|
||||
import org.gradle.kotlin.dsl.register
|
||||
|
||||
@Suppress("Unused")
|
||||
class RenameArtifactsPlugin : Plugin<Project> {
|
||||
|
||||
override fun apply(project: Project) {
|
||||
project.pluginManager.withPlugin("com.android.application") {
|
||||
project.extensions.getByType<ApplicationAndroidComponentsExtension>().run {
|
||||
onVariants { variant ->
|
||||
val taskPrefix = "collect${variant.name.capitalize(Locale.ROOT)}"
|
||||
project.tasks.register<CollectApksTask>("${taskPrefix}Apks") {
|
||||
variantName.set(variant.name)
|
||||
apkFolder.set(variant.artifacts.get(SingleArtifact.APK))
|
||||
mappingFile.set(variant.artifacts.get(SingleArtifact.OBFUSCATION_MAPPING_FILE))
|
||||
builtArtifactsLoader.set(variant.artifacts.getBuiltArtifactsLoader())
|
||||
outputDirectory.set(project.layout.projectDirectory.dir("apk"))
|
||||
}
|
||||
project.tasks.register<CollectBundleTask>("${taskPrefix}Bundle") {
|
||||
val mainOutput =
|
||||
variant.outputs.single {
|
||||
it.outputType == VariantOutputConfiguration.OutputType.SINGLE
|
||||
}
|
||||
variantName.set(variant.name)
|
||||
versionName.set(mainOutput.versionName)
|
||||
mappingFile.set(variant.artifacts.get(SingleArtifact.OBFUSCATION_MAPPING_FILE))
|
||||
bundleFile.set(variant.artifacts.get(SingleArtifact.BUNDLE))
|
||||
outputDirectory.set(project.layout.projectDirectory.dir("bundle"))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* Copyright © 2022 Harsh Shandilya.
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
* https://opensource.org/licenses/MIT.
|
||||
*/
|
||||
package dev.msfjarvis.claw.gradle
|
||||
|
||||
import com.diffplug.gradle.spotless.SpotlessExtension
|
||||
import com.diffplug.gradle.spotless.SpotlessPlugin
|
||||
import org.gradle.api.GradleException
|
||||
import org.gradle.api.Plugin
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.kotlin.dsl.apply
|
||||
import org.gradle.kotlin.dsl.getByType
|
||||
|
||||
@Suppress("Unused")
|
||||
class SpotlessPlugin : Plugin<Project> {
|
||||
|
||||
override fun apply(project: Project) {
|
||||
if (project.rootProject != project) {
|
||||
throw GradleException("Spotless plugin must only be applied to the root project.")
|
||||
}
|
||||
project.pluginManager.apply(SpotlessPlugin::class)
|
||||
project.extensions.getByType<SpotlessExtension>().run {
|
||||
kotlin {
|
||||
ktfmt(KTFMT_VERSION).googleStyle()
|
||||
target("**/*.kt")
|
||||
targetExclude("**/build/", "/spotless/")
|
||||
licenseHeaderFile(project.file("spotless/license.kt"))
|
||||
}
|
||||
kotlinGradle {
|
||||
ktfmt(KTFMT_VERSION).googleStyle()
|
||||
target("**/*.kts")
|
||||
targetExclude("**/build/")
|
||||
licenseHeaderFile(project.file("spotless/license.kt"), "import|plugins|@file")
|
||||
}
|
||||
format("xml") {
|
||||
target("**/*.xml")
|
||||
targetExclude("**/build/", ".idea/")
|
||||
trimTrailingWhitespace()
|
||||
indentWithSpaces()
|
||||
endWithNewline()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private companion object {
|
||||
private const val KTFMT_VERSION = "0.41"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* Copyright © 2022 Harsh Shandilya.
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
* https://opensource.org/licenses/MIT.
|
||||
*/
|
||||
package dev.msfjarvis.claw.gradle.artifacts
|
||||
|
||||
import com.android.build.api.variant.BuiltArtifactsLoader
|
||||
import java.io.File
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.Path
|
||||
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.file.RegularFileProperty
|
||||
import org.gradle.api.provider.Property
|
||||
import org.gradle.api.tasks.CacheableTask
|
||||
import org.gradle.api.tasks.Input
|
||||
import org.gradle.api.tasks.InputFile
|
||||
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:InputFile
|
||||
@get:PathSensitive(PathSensitivity.NONE)
|
||||
abstract val mappingFile: RegularFileProperty
|
||||
|
||||
@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()
|
||||
val outputDirStream =
|
||||
Files.walk(outputDir.toPath()).sorted(Comparator.reverseOrder()).map(Path::toFile)
|
||||
outputDirStream.forEach(File::delete)
|
||||
outputDirStream.close()
|
||||
outputDir.mkdirs()
|
||||
val builtArtifacts =
|
||||
builtArtifactsLoader.get().load(apkFolder.get()) ?: error("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,
|
||||
)
|
||||
}
|
||||
Files.copy(
|
||||
mappingFile.get().asFile.toPath(),
|
||||
outputDir.resolve("mapping.txt").toPath(),
|
||||
StandardCopyOption.REPLACE_EXISTING,
|
||||
)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* Copyright © 2022 Harsh Shandilya.
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
* https://opensource.org/licenses/MIT.
|
||||
*/
|
||||
package dev.msfjarvis.claw.gradle.artifacts
|
||||
|
||||
import java.io.File
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.Path
|
||||
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:InputFile abstract val mappingFile: 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()
|
||||
val outputDirStream =
|
||||
Files.walk(outputDir.toPath()).sorted(Comparator.reverseOrder()).map(Path::toFile)
|
||||
outputDirStream.forEach(File::delete)
|
||||
outputDirStream.close()
|
||||
outputDir.mkdirs()
|
||||
Files.copy(
|
||||
bundleFile.get().asFile.toPath(),
|
||||
outputDir.resolve("Claw-${variantName.get()}-${versionName.get()}.aab").toPath(),
|
||||
StandardCopyOption.REPLACE_EXISTING,
|
||||
)
|
||||
Files.copy(
|
||||
mappingFile.get().asFile.toPath(),
|
||||
outputDir.resolve("mapping.txt").toPath(),
|
||||
StandardCopyOption.REPLACE_EXISTING,
|
||||
)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Copyright © 2022 Harsh Shandilya.
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
* https://opensource.org/licenses/MIT.
|
||||
*/
|
||||
package dev.msfjarvis.claw.gradle.signing
|
||||
|
||||
import com.android.build.gradle.internal.dsl.BaseAppModuleExtension
|
||||
import java.util.Properties
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.kotlin.dsl.configure
|
||||
|
||||
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) }
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
/*
|
||||
* Copyright © 2022 Harsh Shandilya.
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
* https://opensource.org/licenses/MIT.
|
||||
*/
|
||||
package dev.msfjarvis.claw.gradle.versioning
|
||||
|
||||
const val VERSIONING_PROP_FILE = "version.properties"
|
||||
const val VERSIONING_PROP_VERSION_NAME = "versioning-plugin.versionName"
|
||||
const val VERSIONING_PROP_VERSION_CODE = "versioning-plugin.versionCode"
|
||||
const val VERSIONING_PROP_COMMENT =
|
||||
"""#
|
||||
# This file was automatically generated by 'versioning-plugin'. DO NOT EDIT MANUALLY.
|
||||
#"""
|
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
* Copyright © 2022 Harsh Shandilya.
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
* https://opensource.org/licenses/MIT.
|
||||
*/
|
||||
package dev.msfjarvis.claw.gradle.versioning
|
||||
|
||||
import com.android.build.api.variant.ApplicationAndroidComponentsExtension
|
||||
import com.android.build.api.variant.VariantOutputConfiguration
|
||||
import com.android.build.gradle.internal.plugins.AppPlugin
|
||||
import com.vdurmont.semver4j.Semver
|
||||
import java.util.Properties
|
||||
import java.util.concurrent.atomic.AtomicBoolean
|
||||
import org.gradle.api.Plugin
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.kotlin.dsl.getByType
|
||||
import org.gradle.kotlin.dsl.register
|
||||
import org.gradle.kotlin.dsl.withType
|
||||
|
||||
/**
|
||||
* A Gradle [Plugin] that takes a [Project] with the [AppPlugin] applied and dynamically sets the
|
||||
* versionCode and versionName properties based on values read from a [VERSIONING_PROP_FILE] file in
|
||||
* the [Project.getBuildDir] directory. It also adds Gradle tasks to bump the major, minor, and
|
||||
* patch versions along with one to prepare the next snapshot.
|
||||
*/
|
||||
@Suppress("Unused")
|
||||
class VersioningPlugin : Plugin<Project> {
|
||||
|
||||
override fun apply(project: Project) {
|
||||
with(project) {
|
||||
val androidAppPluginApplied = AtomicBoolean(false)
|
||||
val propFile = layout.projectDirectory.file(VERSIONING_PROP_FILE)
|
||||
require(propFile.asFile.exists()) {
|
||||
"A 'version.properties' file must exist in the project subdirectory to use this plugin"
|
||||
}
|
||||
val contents = providers.fileContents(propFile).asText
|
||||
val versionProps = Properties().also { it.load(contents.get().byteInputStream()) }
|
||||
val versionName =
|
||||
requireNotNull(versionProps.getProperty(VERSIONING_PROP_VERSION_NAME)) {
|
||||
"version.properties must contain a '$VERSIONING_PROP_VERSION_NAME' property"
|
||||
}
|
||||
val versionCode =
|
||||
requireNotNull(versionProps.getProperty(VERSIONING_PROP_VERSION_CODE).toInt()) {
|
||||
"version.properties must contain a '$VERSIONING_PROP_VERSION_CODE' property"
|
||||
}
|
||||
project.plugins.withType<AppPlugin> {
|
||||
androidAppPluginApplied.set(true)
|
||||
extensions.getByType<ApplicationAndroidComponentsExtension>().onVariants { variant ->
|
||||
val mainOutput =
|
||||
variant.outputs.single { it.outputType == VariantOutputConfiguration.OutputType.SINGLE }
|
||||
mainOutput.versionName.set(versionName)
|
||||
mainOutput.versionCode.set(versionCode)
|
||||
}
|
||||
}
|
||||
val version = Semver(versionName)
|
||||
tasks.register<VersioningTask>("clearPreRelease") {
|
||||
description = "Remove the pre-release suffix from the version"
|
||||
semverString.set(version.withClearedSuffix().toString())
|
||||
propertyFile.set(propFile)
|
||||
}
|
||||
tasks.register<VersioningTask>("bumpMajor") {
|
||||
description = "Increment the major version"
|
||||
semverString.set(version.withIncMajor().withClearedSuffix().toString())
|
||||
propertyFile.set(propFile)
|
||||
}
|
||||
tasks.register<VersioningTask>("bumpMinor") {
|
||||
description = "Increment the minor version"
|
||||
semverString.set(version.withIncMinor().withClearedSuffix().toString())
|
||||
propertyFile.set(propFile)
|
||||
}
|
||||
tasks.register<VersioningTask>("bumpPatch") {
|
||||
description = "Increment the patch version"
|
||||
semverString.set(version.withIncPatch().withClearedSuffix().toString())
|
||||
propertyFile.set(propFile)
|
||||
}
|
||||
tasks.register<VersioningTask>("bumpSnapshot") {
|
||||
description = "Increment the minor version and add the `SNAPSHOT` suffix"
|
||||
semverString.set(version.withIncMinor().withSuffix("SNAPSHOT").toString())
|
||||
propertyFile.set(propFile)
|
||||
}
|
||||
afterEvaluate {
|
||||
check(androidAppPluginApplied.get()) {
|
||||
"Plugin 'com.android.application' must be applied to ${project.displayName} to use the Versioning Plugin"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* Copyright © 2022 Harsh Shandilya.
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
* https://opensource.org/licenses/MIT.
|
||||
*/
|
||||
package dev.msfjarvis.claw.gradle.versioning
|
||||
|
||||
import com.vdurmont.semver4j.Semver
|
||||
import org.gradle.api.DefaultTask
|
||||
import org.gradle.api.file.RegularFileProperty
|
||||
import org.gradle.api.provider.Property
|
||||
import org.gradle.api.tasks.CacheableTask
|
||||
import org.gradle.api.tasks.Input
|
||||
import org.gradle.api.tasks.OutputFile
|
||||
import org.gradle.api.tasks.TaskAction
|
||||
|
||||
@CacheableTask
|
||||
abstract class VersioningTask : DefaultTask() {
|
||||
@get:Input abstract val semverString: Property<String>
|
||||
|
||||
@get:OutputFile abstract val propertyFile: RegularFileProperty
|
||||
|
||||
/** Generate the Android 'versionCode' property */
|
||||
private fun Semver.androidCode(): Int {
|
||||
return major * 1_00_00 + minor * 1_00 + patch
|
||||
}
|
||||
|
||||
private fun Semver.toPropFileText(): String {
|
||||
val newVersionCode = androidCode()
|
||||
val newVersionName = toString()
|
||||
return buildString {
|
||||
appendLine(VERSIONING_PROP_COMMENT)
|
||||
append(VERSIONING_PROP_VERSION_CODE)
|
||||
append('=')
|
||||
appendLine(newVersionCode)
|
||||
append(VERSIONING_PROP_VERSION_NAME)
|
||||
append('=')
|
||||
appendLine(newVersionName)
|
||||
}
|
||||
}
|
||||
|
||||
override fun getGroup(): String {
|
||||
return "versioning"
|
||||
}
|
||||
|
||||
@TaskAction
|
||||
fun execute() {
|
||||
propertyFile.get().asFile.writeText(Semver(semverString.get()).toPropFileText())
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue