Repo created

This commit is contained in:
Fr4nz D13trich 2025-11-21 15:11:39 +01:00
parent d6b5d53060
commit d90a1dc8df
2145 changed files with 210227 additions and 2 deletions

21
buildSrc/build.gradle.kts Normal file
View file

@ -0,0 +1,21 @@
plugins {
`kotlin-dsl`
}
dependencies {
implementation(libs.android.gradle)
implementation(libs.kotlin.gradle)
implementation(libs.compose.compiler.gradle)
implementation(libs.spotless.gradle)
implementation(gradleApi())
implementation(libs.javapoet)
implementation(libs.json)
implementation(files(libs.javaClass.superclass.protectionDomain.codeSource.location))
}
repositories {
gradlePluginPortal()
mavenCentral()
google()
}

View file

@ -0,0 +1,7 @@
dependencyResolutionManagement {
versionCatalogs {
create("libs") {
from(files("../gradle/libs.versions.toml"))
}
}
}

View file

@ -0,0 +1,12 @@
import breezy.buildlogic.configureCompose
plugins {
id("com.android.application")
kotlin("android")
id("breezy.code.lint")
}
android {
configureCompose(this)
}

View file

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

View file

@ -0,0 +1,39 @@
import org.gradle.accessors.dm.LibrariesForLibs
plugins {
id("com.diffplug.spotless")
}
val libs = the<LibrariesForLibs>()
val xmlFormatExclude = buildList(2) {
add("**/build/**/*.xml")
projectDir
.resolve("src/main/res/")
.takeIf {
it.isDirectory &&
(!it.name.startsWith("values-") ||
it.name.endsWith("hdpi") ||
it.name.endsWith("v29") ||
it.name.endsWith("v31")
)
}?.let(::fileTree)
?.let(::add)
}.toTypedArray()
spotless {
kotlin {
target("**/*.kt", "**/*.kts")
targetExclude("**/build/**/*.kt")
ktlint(libs.ktlint.core.get().version)
trimTrailingWhitespace()
endWithNewline()
}
format("xml") {
target("**/*.xml")
targetExclude(*xmlFormatExclude)
trimTrailingWhitespace()
endWithNewline()
}
}

View file

@ -0,0 +1,13 @@
import breezy.buildlogic.configureAndroid
import breezy.buildlogic.configureTest
plugins {
id("com.android.library")
id("breezy.code.lint")
}
android {
configureAndroid(this)
configureTest()
}

View file

@ -0,0 +1,15 @@
package breezy.buildlogic
import org.gradle.api.JavaVersion as GradleJavaVersion
import org.jetbrains.kotlin.gradle.dsl.JvmTarget as KotlinJvmTarget
object AndroidConfig {
const val COMPILE_SDK = 36
const val MIN_SDK = 21
const val TARGET_SDK = 36
const val BUILD_TOOLS = "35.0.1"
// https://youtrack.jetbrains.com/issue/KT-66995/JvmTarget-and-JavaVersion-compatibility-for-easier-JVM-version-setup
val JavaVersion = GradleJavaVersion.VERSION_1_8
val JvmTarget = KotlinJvmTarget.JVM_1_8
}

View file

@ -0,0 +1,25 @@
package breezy.buildlogic
import org.gradle.api.Project
// Git is needed in your system PATH for these commands to work.
// If it's not installed, you can return a random value as a workaround
fun Project.getCommitCount(): String {
return runCommand("git rev-list --count HEAD")
// return "1"
}
fun Project.getGitSha(): String {
return runCommand("git rev-parse --short=8 HEAD")
// return "1"
}
fun Project.runCommand(command: String): String {
return providers.exec {
commandLine = command.split(" ")
}
.standardOutput
.asText
.get()
.trim()
}

View file

@ -0,0 +1,47 @@
package breezy.buildlogic
/**
* Taken from Mihon
* Apache License, Version 2.0
*
* https://github.com/mihonapp/mihon/blob/290efb0283145d81290972991047064c1d905c9c/buildSrc/src/main/kotlin/LocalesConfigPlugin.kt
*/
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()
private val valuesPrefix = "values(-(b\\+)?)?".toRegex()
fun TaskContainerScope.registerLocalesConfigTask(project: Project): TaskProvider<Task> {
return with(project) {
register("generateLocalesConfig") {
val languages = fileTree("$projectDir/src/main/res/")
.matching { include("**/strings.xml") }
.filterNot { it.readText().contains(emptyResourcesElement) }
.map { it.parentFile.name }
.sorted()
.joinToString(separator = "\n") {
val language = it
.replace(valuesPrefix, "")
.replace("-r", "-")
.replace("+", "-")
.takeIf(String::isNotBlank) ?: "en"
"| <locale android:name=\"$language\" />"
}
val content = """
|<?xml version="1.0" encoding="utf-8"?>
|<locale-config xmlns:android="http://schemas.android.com/apk/res/android">
$languages
|</locale-config>
""".trimMargin()
val localeFile = file("$projectDir/src/main/res/xml/locales_config.xml")
localeFile.parentFile.mkdirs()
localeFile.writeText(content)
}
}
}

View file

@ -0,0 +1,133 @@
package breezy.buildlogic
import org.gradle.api.Project
import org.gradle.api.Task
import org.gradle.api.tasks.TaskProvider
import org.gradle.kotlin.dsl.TaskContainerScope
import org.json.JSONArray
import org.json.JSONObject
import java.math.RoundingMode
/**
* 4 is ~10 m
* 5 is ~1 m
* 6 is ~10 cm
*/
const val COORDINATES_PRECISION = 5
/**
* Performs a few corrections and optimize by removing unused properties
* on the original Natural Earth file already converted to JSON
*
* TODO: Make this task convert shapefile to json instead of relying on external tools
*/
fun TaskContainerScope.registerNaturalEarthConfigTask(project: Project): TaskProvider<Task> {
return with(project) {
register("generateNaturalEarthConfig") {
val originalFileContents = file("$projectDir/work/ne_50m_admin_0_countries.json")
.bufferedReader().use { it.readText() }
val json = JSONObject(originalFileContents)
json.put(
"features",
(json.getJSONArray("features")).map { features ->
if (features is JSONObject) {
// Geometry
if (features.has("geometry")) {
features.put(
"geometry",
features.getJSONObject("geometry").let { geometry ->
if (geometry.has("type")) {
when (geometry.getString("type")) {
"MultiPolygon", "Polygon" -> {
geometry.put(
"coordinates",
reduceDecimalPrecision(geometry.getJSONArray("coordinates"))
)
}
// No other cases in this file
else -> {}
}
}
geometry
}
)
}
// Properties
if (features.has("properties")) {
features.put(
"properties",
features.getJSONObject("properties").let { properties ->
// Fix Taiwan inexisting ISO A2 code
// Fix a few countries with no code, such as France and Norway
if (properties.has("ISO_A2")) {
when (properties.getString("ISO_A2")) {
"CN-TW" -> properties.put("ISO_A2", "TW")
"-99" -> properties.put(
"ISO_A2",
properties.getString("ISO_A2_EH").takeIf { it != "-99" } ?: ""
)
else -> {}
}
}
// Must be stored to avoid ConcurrentModificationException
val propertiesToRemove = mutableSetOf(
"NAME_CIAWF",
"NAME_SORT",
"NAME_ALT",
"NAME_LEN"
)
properties.keys().forEach { k ->
if (k != "ISO_A2") {
if (!k.startsWith("NAME_")) {
// Remove everything we don't need
propertiesToRemove.add(k)
} else if (!properties.getString("ISO_A2").isNullOrEmpty()) {
// Remove every name as Android already provides it
// Unless it's an unknown country (with no ISO A2)
propertiesToRemove.add(k)
}
}
}
propertiesToRemove.forEach { p ->
properties.remove(p)
}
properties
}
)
}
}
features
}
)
val localeFile = file("$projectDir/src/main/res/raw/ne_50m_admin_0_countries.json")
localeFile.parentFile.mkdirs()
localeFile.writeText(json.toString())
}
}
}
private fun reduceDecimalPrecision(coordinates: JSONArray): JSONArray {
if (coordinates.get(0) is Number) {
coordinates.put(
0,
coordinates.getBigDecimal(0)
.setScale(COORDINATES_PRECISION, RoundingMode.HALF_UP)
)
coordinates.put(
1,
coordinates.getBigDecimal(1)
.setScale(COORDINATES_PRECISION, RoundingMode.HALF_UP)
)
}
if (coordinates.get(0) is JSONArray) {
coordinates.map {
reduceDecimalPrecision(it as JSONArray)
}
}
return coordinates
}

View file

@ -0,0 +1,64 @@
package breezy.buildlogic
import com.android.build.api.dsl.CommonExtension
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.provideDelegate
import org.gradle.kotlin.dsl.the
import org.gradle.kotlin.dsl.withType
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
val Project.libs get() = the<LibrariesForLibs>()
internal fun Project.configureAndroid(commonExtension: CommonExtension<*, *, *, *, *, *>) {
commonExtension.apply {
compileSdk = AndroidConfig.COMPILE_SDK
buildToolsVersion = AndroidConfig.BUILD_TOOLS
defaultConfig {
minSdk = AndroidConfig.MIN_SDK
}
compileOptions {
sourceCompatibility = AndroidConfig.JavaVersion
targetCompatibility = AndroidConfig.JavaVersion
// isCoreLibraryDesugaringEnabled = true
}
}
tasks.withType<KotlinCompile>().configureEach {
compilerOptions {
jvmTarget.set(AndroidConfig.JvmTarget)
freeCompilerArgs.addAll(
"-Xcontext-receivers",
"-opt-in=kotlin.RequiresOptIn",
)
// 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.set(warningsAsErrors.toBoolean())
}
}
}
internal fun Project.configureCompose(commonExtension: CommonExtension<*, *, *, *, *, *>) {
pluginManager.apply(libs.plugins.compose.compiler.get().pluginId)
commonExtension.apply {
buildFeatures {
compose = true
}
}
}
internal fun Project.configureTest() {
tasks.withType<Test> {
useJUnitPlatform()
testLogging {
events(TestLogEvent.PASSED, TestLogEvent.SKIPPED, TestLogEvent.FAILED)
}
}
}