Rework buildSrc and remove usage of subprojects

This commit is contained in:
AntsyLich 2024-04-06 11:07:11 +06:00
parent aed53d3bdc
commit e448e40406
No known key found for this signature in database
26 changed files with 262 additions and 155 deletions

View file

@ -1,11 +1,14 @@
import mihon.buildlogic.getBuildTime
import mihon.buildlogic.getCommitCount
import mihon.buildlogic.getGitSha
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins { plugins {
id("com.android.application") id("mihon.android.application")
id("mihon.android.application.compose")
id("com.mikepenz.aboutlibraries.plugin") id("com.mikepenz.aboutlibraries.plugin")
kotlin("android")
kotlin("plugin.serialization")
id("com.github.zellius.shortcut-helper") id("com.github.zellius.shortcut-helper")
kotlin("plugin.serialization")
} }
if (gradle.startParameter.taskRequests.toString().contains("Standard")) { if (gradle.startParameter.taskRequests.toString().contains("Standard")) {
@ -119,7 +122,6 @@ android {
buildFeatures { buildFeatures {
viewBinding = true viewBinding = true
compose = true
buildConfig = true buildConfig = true
// Disable some unused things // Disable some unused things
@ -132,10 +134,6 @@ android {
abortOnError = false abortOnError = false
checkReleaseBuilds = false checkReleaseBuilds = false
} }
composeOptions {
kotlinCompilerExtensionVersion = compose.versions.compiler.get()
}
} }
dependencies { dependencies {
@ -150,7 +148,6 @@ dependencies {
implementation(projects.presentationWidget) implementation(projects.presentationWidget)
// Compose // Compose
implementation(platform(compose.bom))
implementation(compose.activity) implementation(compose.activity)
implementation(compose.foundation) implementation(compose.foundation)
implementation(compose.material3.core) implementation(compose.material3.core)
@ -295,25 +292,6 @@ tasks {
"-opt-in=kotlinx.coroutines.InternalCoroutinesApi", "-opt-in=kotlinx.coroutines.InternalCoroutinesApi",
"-opt-in=kotlinx.serialization.ExperimentalSerializationApi", "-opt-in=kotlinx.serialization.ExperimentalSerializationApi",
) )
if (project.findProperty("tachiyomi.enableComposeCompilerMetrics") == "true") {
kotlinOptions.freeCompilerArgs += listOf(
"-P",
"plugin:androidx.compose.compiler.plugins.kotlin:reportsDestination=" +
project.layout.buildDirectory.dir("compose_metrics").get().asFile.absolutePath,
)
kotlinOptions.freeCompilerArgs += listOf(
"-P",
"plugin:androidx.compose.compiler.plugins.kotlin:metricsDestination=" +
project.layout.buildDirectory.dir("compose_metrics").get().asFile.absolutePath,
)
}
// https://developer.android.com/jetpack/androidx/releases/compose-compiler#1.5.9
kotlinOptions.freeCompilerArgs += listOf(
"-P",
"plugin:androidx.compose.compiler.plugins.kotlin:nonSkippingGroupOptimization=true",
)
} }
} }

View file

@ -1,8 +1,3 @@
import com.android.build.gradle.BaseExtension
import com.android.build.gradle.BasePlugin
import org.gradle.api.tasks.testing.logging.TestLogEvent
import org.jetbrains.kotlin.gradle.tasks.KotlinJvmCompile
buildscript { buildscript {
dependencies { dependencies {
classpath(libs.android.shortcut.gradle) classpath(libs.android.shortcut.gradle)
@ -17,45 +12,6 @@ plugins {
alias(kotlinx.plugins.serialization) apply false alias(kotlinx.plugins.serialization) apply false
} }
subprojects {
tasks.withType<KotlinJvmCompile> {
kotlinOptions {
jvmTarget = JavaVersion.VERSION_17.toString()
}
}
tasks.withType<Test> {
useJUnitPlatform()
testLogging {
events(TestLogEvent.PASSED, TestLogEvent.SKIPPED, TestLogEvent.FAILED)
}
}
plugins.withType<BasePlugin> {
plugins.apply("detekt")
configure<BaseExtension> {
compileSdkVersion(AndroidConfig.compileSdk)
defaultConfig {
minSdk = AndroidConfig.minSdk
targetSdk = AndroidConfig.targetSdk
ndk {
version = AndroidConfig.ndk
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
isCoreLibraryDesugaringEnabled = true
}
dependencies {
add("coreLibraryDesugaring", libs.desugar)
}
}
}
}
tasks.register<Delete>("clean") { tasks.register<Delete>("clean") {
delete(rootProject.layout.buildDirectory) delete(rootProject.layout.buildDirectory)
} }

View file

@ -4,8 +4,11 @@ plugins {
dependencies { dependencies {
implementation(files(libs.javaClass.superclass.protectionDomain.codeSource.location)) implementation(files(libs.javaClass.superclass.protectionDomain.codeSource.location))
implementation(androidxLibs.gradle) implementation(files(androidx.javaClass.superclass.protectionDomain.codeSource.location))
implementation(kotlinLibs.gradle) implementation(files(compose.javaClass.superclass.protectionDomain.codeSource.location))
implementation(files(kotlinx.javaClass.superclass.protectionDomain.codeSource.location))
implementation(androidx.gradle)
implementation(kotlinx.gradle)
implementation(libs.detekt.gradlePlugin) implementation(libs.detekt.gradlePlugin)
implementation(gradleApi()) implementation(gradleApi())
} }

View file

@ -3,10 +3,13 @@ dependencyResolutionManagement {
create("libs") { create("libs") {
from(files("../gradle/libs.versions.toml")) from(files("../gradle/libs.versions.toml"))
} }
create("androidxLibs") { create("androidx") {
from(files("../gradle/androidx.versions.toml")) from(files("../gradle/androidx.versions.toml"))
} }
create("kotlinLibs") { create("compose") {
from(files("../gradle/compose.versions.toml"))
}
create("kotlinx") {
from(files("../gradle/kotlinx.versions.toml")) from(files("../gradle/kotlinx.versions.toml"))
} }
} }

View file

@ -1,6 +0,0 @@
object AndroidConfig {
const val compileSdk = 34
const val minSdk = 26
const val targetSdk = 34
const val ndk = "26.1.10909125"
}

View file

@ -1,39 +0,0 @@
import org.gradle.api.Project
import org.gradle.api.Task
import org.gradle.api.tasks.TaskProvider
import org.gradle.kotlin.dsl.TaskContainerScope
private val emptyResourcesElement = "<resources>\\s*</resources>|<resources/>".toRegex()
fun TaskContainerScope.registerLocalesConfigTask(project: Project): TaskProvider<Task> {
return with(project) {
register("generateLocalesConfig") {
val languages = fileTree("$projectDir/src/commonMain/resources/MR/")
.matching { include("**/strings.xml") }
.filterNot { it.readText().contains(emptyResourcesElement) }
.map {
it.parentFile.name
.replace("base", "en")
.replace("-r", "-")
.replace("+", "-")
.takeIf(String::isNotBlank) ?: "en"
}
.sorted()
.joinToString(separator = "\n") {
" <locale android:name=\"$it\"/>"
}
val content = """
<?xml version="1.0" encoding="utf-8"?>
<locale-config xmlns:android="http://schemas.android.com/apk/res/android">
$languages
</locale-config>
""".trimIndent()
val localeFile = file("$projectDir/src/androidMain/res/xml/locales_config.xml")
localeFile.parentFile.mkdirs()
localeFile.writeText(content)
}
}
}

View file

@ -0,0 +1,11 @@
import mihon.buildlogic.AndroidConfig
import mihon.buildlogic.configureCompose
plugins {
id("com.android.application")
kotlin("android")
}
android {
configureCompose(this)
}

View file

@ -0,0 +1,17 @@
import mihon.buildlogic.AndroidConfig
import mihon.buildlogic.configureAndroid
import mihon.buildlogic.configureTest
plugins {
id("mihon.code.detekt")
id("com.android.application")
kotlin("android")
}
android {
defaultConfig {
targetSdk = AndroidConfig.TARGET_SDK
}
configureAndroid(this)
configureTest()
}

View file

@ -0,0 +1,13 @@
import mihon.buildlogic.configureAndroid
import mihon.buildlogic.configureTest
plugins {
id("mihon.code.detekt")
id("com.android.test")
kotlin("android")
}
android {
configureAndroid(this)
configureTest()
}

View file

@ -0,0 +1,10 @@
import mihon.buildlogic.configureCompose
plugins {
id("mihon.code.detekt")
id("com.android.library")
}
android {
configureCompose(this)
}

View file

@ -0,0 +1,12 @@
import mihon.buildlogic.configureAndroid
import mihon.buildlogic.configureTest
plugins {
id("mihon.code.detekt")
id("com.android.library")
}
android {
configureAndroid(this)
configureTest()
}

View file

@ -0,0 +1,11 @@
package mihon.buildlogic
import org.gradle.api.JavaVersion as GradleJavaVersion
object AndroidConfig {
const val COMPILE_SDK = 34
const val TARGET_SDK = 34
const val MIN_SDK = 26
const val NDK = "26.1.10909125"
val JavaVersion = GradleJavaVersion.VERSION_17
}

View file

@ -1,3 +1,5 @@
package mihon.buildlogic
import org.gradle.api.Project import org.gradle.api.Project
import java.io.ByteArrayOutputStream import java.io.ByteArrayOutputStream
import java.time.LocalDateTime import java.time.LocalDateTime
@ -23,9 +25,9 @@ fun Project.getBuildTime(): String {
return LocalDateTime.now(ZoneOffset.UTC).format(BUILD_TIME_FORMATTER) return LocalDateTime.now(ZoneOffset.UTC).format(BUILD_TIME_FORMATTER)
} }
fun Project.runCommand(command: String): String { private fun Project.runCommand(command: String): String {
val byteOut = ByteArrayOutputStream() val byteOut = ByteArrayOutputStream()
project.exec { exec {
commandLine = command.split(" ") commandLine = command.split(" ")
standardOutput = byteOut standardOutput = byteOut
} }

View file

@ -0,0 +1,112 @@
package mihon.buildlogic
import com.android.build.api.dsl.CommonExtension
import org.gradle.accessors.dm.LibrariesForAndroidx
import org.gradle.accessors.dm.LibrariesForCompose
import org.gradle.accessors.dm.LibrariesForKotlinx
import org.gradle.accessors.dm.LibrariesForLibs
import org.gradle.api.Project
import org.gradle.api.tasks.testing.Test
import org.gradle.api.tasks.testing.logging.TestLogEvent
import org.gradle.kotlin.dsl.dependencies
import org.gradle.kotlin.dsl.the
import org.gradle.kotlin.dsl.withType
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
val Project.androidx get() = the<LibrariesForAndroidx>()
val Project.compose get() = the<LibrariesForCompose>()
val Project.kotlinx get() = the<LibrariesForKotlinx>()
val Project.libs get() = the<LibrariesForLibs>()
internal fun Project.configureAndroid(commonExtension: CommonExtension<*, *, *, *, *, *>) {
commonExtension.apply {
compileSdk = AndroidConfig.COMPILE_SDK
defaultConfig {
minSdk = AndroidConfig.MIN_SDK
ndk {
version = AndroidConfig.NDK
}
}
compileOptions {
sourceCompatibility = AndroidConfig.JavaVersion
targetCompatibility = AndroidConfig.JavaVersion
isCoreLibraryDesugaringEnabled = true
}
}
tasks.withType<KotlinCompile>().configureEach {
kotlinOptions {
jvmTarget = AndroidConfig.JavaVersion.toString()
// freeCompilerArgs += "-opt-in=kotlin.RequiresOptIn"
// freeCompilerArgs += "-Xcontext-receivers"
// Treat all Kotlin warnings as errors (disabled by default)
// Override by setting warningsAsErrors=true in your ~/.gradle/gradle.properties
// val warningsAsErrors: String? by project
// allWarningsAsErrors = warningsAsErrors.toBoolean()
}
}
dependencies {
"coreLibraryDesugaring"(libs.desugar)
}
}
internal fun Project.configureCompose(commonExtension: CommonExtension<*, *, *, *, *, *>) {
commonExtension.apply {
buildFeatures {
compose = true
}
composeOptions {
kotlinCompilerExtensionVersion = compose.versions.compiler.get()
}
dependencies {
"implementation"(platform(compose.bom))
}
}
tasks.withType<KotlinCompile>().configureEach {
kotlinOptions {
freeCompilerArgs += buildComposeMetricsParameters()
// Enable experimental compiler opts
// https://developer.android.com/jetpack/androidx/releases/compose-compiler#1.5.9
freeCompilerArgs += listOf(
"-P",
"plugin:androidx.compose.compiler.plugins.kotlin:nonSkippingGroupOptimization=true",
)
}
}
}
private fun Project.buildComposeMetricsParameters(): List<String> {
val rootProjectDir = rootProject.layout.buildDirectory.asFile.get()
val relativePath = projectDir.relativeTo(rootDir)
val enableMetrics = project.providers.gradleProperty("enableComposeCompilerMetrics").orNull.toBoolean()
val enableReports = project.providers.gradleProperty("enableComposeCompilerReports").orNull.toBoolean()
return listOfNotNull(
("metricsDestination" to "compose-metrics").takeIf { enableMetrics },
("reportsDestination" to "compose-reports").takeIf { enableReports },
).flatMap { (flag, dirName) ->
val buildDirPath = rootProjectDir.resolve(dirName).resolve(relativePath).absolutePath
listOf(
"-P",
"plugin:androidx.compose.compiler.plugins.kotlin:$flag=$buildDirPath"
)
}
}
internal fun Project.configureTest() {
tasks.withType<Test> {
useJUnitPlatform()
testLogging {
events(TestLogEvent.PASSED, TestLogEvent.SKIPPED, TestLogEvent.FAILED)
}
}
}

View file

@ -0,0 +1,37 @@
package mihon.buildlogic.tasks
import org.gradle.api.Project
import org.gradle.api.Task
import org.gradle.api.tasks.TaskProvider
private val emptyResourcesElement = "<resources>\\s*</resources>|<resources/>".toRegex()
fun Project.getLocalesConfigTask(): TaskProvider<Task> {
return tasks.register("generateLocalesConfig") {
val locales = fileTree("$projectDir/src/commonMain/resources/MR/")
.matching { include("**/strings.xml") }
.filterNot { it.readText().contains(emptyResourcesElement) }
.map {
it.parentFile.name
.replace("base", "en")
.replace("-r", "-")
.replace("+", "-")
.takeIf(String::isNotBlank) ?: "en"
}
.sorted()
.joinToString("\n") { "| <locale android:name=\"$it\"/>" }
val content = """
|<?xml version="1.0" encoding="utf-8"?>
|<locale-config xmlns:android="http://schemas.android.com/apk/res/android">
$locales
|</locale-config>
""".trimMargin()
file("$projectDir/src/androidMain/res/xml/locales_config.xml").apply {
parentFile.mkdirs()
writeText(content)
}
}
}

View file

@ -1,5 +1,5 @@
plugins { plugins {
id("com.android.library") id("mihon.library")
kotlin("android") kotlin("android")
kotlin("plugin.serialization") kotlin("plugin.serialization")
} }

View file

@ -1,5 +1,5 @@
plugins { plugins {
id("com.android.library") id("mihon.library")
kotlin("android") kotlin("android")
kotlin("plugin.serialization") kotlin("plugin.serialization")
} }

View file

@ -1,8 +1,8 @@
plugins { plugins {
id("com.android.library") id("mihon.library")
id("app.cash.sqldelight")
kotlin("android") kotlin("android")
kotlin("plugin.serialization") kotlin("plugin.serialization")
id("app.cash.sqldelight")
} }
android { android {

View file

@ -1,5 +1,5 @@
plugins { plugins {
id("com.android.library") id("mihon.library")
kotlin("android") kotlin("android")
kotlin("plugin.serialization") kotlin("plugin.serialization")
} }

View file

@ -1,7 +1,10 @@
import mihon.buildlogic.tasks.getLocalesConfigTask
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins { plugins {
kotlin("multiplatform") id("mihon.library")
id("com.android.library")
id("dev.icerock.mobile.multiplatform-resources") id("dev.icerock.mobile.multiplatform-resources")
kotlin("multiplatform")
} }
kotlin { kotlin {
@ -41,12 +44,12 @@ multiplatformResources {
} }
tasks { tasks {
val localesConfigTask = registerLocalesConfigTask(project) val localesConfigTask = project.getLocalesConfigTask()
preBuild { preBuild {
dependsOn(localesConfigTask) dependsOn(localesConfigTask)
} }
withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile> { withType<KotlinCompile> {
kotlinOptions.freeCompilerArgs += listOf( kotlinOptions.freeCompilerArgs += listOf(
"-Xexpect-actual-classes", "-Xexpect-actual-classes",
) )

View file

@ -1,6 +1,5 @@
plugins { plugins {
id("com.android.test") id("mihon.benchmark")
kotlin("android")
} }
android { android {

View file

@ -1,5 +1,6 @@
plugins { plugins {
id("com.android.library") id("mihon.library")
id("mihon.library.compose")
kotlin("android") kotlin("android")
} }
@ -10,14 +11,6 @@ android {
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
consumerProguardFiles("consumer-rules.pro") consumerProguardFiles("consumer-rules.pro")
} }
buildFeatures {
compose = true
}
composeOptions {
kotlinCompilerExtensionVersion = compose.versions.compiler.get()
}
} }
dependencies { dependencies {
@ -25,7 +18,6 @@ dependencies {
api(projects.i18n) api(projects.i18n)
// Compose // Compose
implementation(platform(compose.bom))
implementation(compose.activity) implementation(compose.activity)
implementation(compose.foundation) implementation(compose.foundation)
implementation(compose.material3.core) implementation(compose.material3.core)

View file

@ -1,5 +1,6 @@
plugins { plugins {
id("com.android.library") id("mihon.library")
id("mihon.library.compose")
kotlin("android") kotlin("android")
} }
@ -10,14 +11,6 @@ android {
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
consumerProguardFiles("consumer-rules.pro") consumerProguardFiles("consumer-rules.pro")
} }
buildFeatures {
compose = true
}
composeOptions {
kotlinCompilerExtensionVersion = compose.versions.compiler.get()
}
} }
dependencies { dependencies {

View file

@ -1,7 +1,7 @@
plugins { plugins {
id("mihon.library")
kotlin("multiplatform") kotlin("multiplatform")
kotlin("plugin.serialization") kotlin("plugin.serialization")
id("com.android.library")
} }
kotlin { kotlin {

View file

@ -1,6 +1,6 @@
plugins { plugins {
id("mihon.library")
kotlin("multiplatform") kotlin("multiplatform")
id("com.android.library")
} }
kotlin { kotlin {