mirror of
https://github.com/d4rken-org/capod.git
synced 2026-09-14 18:26:11 -04:00
Refactor: Convert build configuration to Gradle plugin pattern
- Migrate ProjectConfig from static object to proper Gradle plugin - Add version type support (beta/rc) to version.properties - Clean up legacy fastlane changelogs - Update release script to support version types - Remove automatic fastlane changelog generation from release script - Add BuildConfig field injection for version info
This commit is contained in:
@@ -3,10 +3,20 @@ plugins {
|
||||
`java-library`
|
||||
}
|
||||
|
||||
gradlePlugin {
|
||||
plugins {
|
||||
create("projectConfigPlugin") {
|
||||
id = "projectConfig"
|
||||
implementationClass = "ProjectConfigPlugin"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation("com.android.tools.build:gradle:8.13.0")
|
||||
implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:2.2.10")
|
||||
|
||||
@@ -1,64 +1,56 @@
|
||||
import org.gradle.api.Plugin
|
||||
import org.gradle.api.Project
|
||||
import java.io.File
|
||||
import java.io.FileInputStream
|
||||
import java.util.Properties
|
||||
|
||||
object ProjectConfig {
|
||||
const val packageName = "eu.darken.capod"
|
||||
open class ProjectConfig {
|
||||
val packageName = "eu.darken.capod"
|
||||
val minSdk = 26
|
||||
|
||||
const val minSdk = 26
|
||||
const val compileSdk = 36
|
||||
const val targetSdk = 36
|
||||
val compileSdk = 36
|
||||
val targetSdk = 36
|
||||
|
||||
object Version {
|
||||
lateinit var version: Version
|
||||
|
||||
override fun toString(): String {
|
||||
return "ProjectConfig($packageName, min=$minSdk, compile=$compileSdk, target=$targetSdk, version=$version)"
|
||||
}
|
||||
|
||||
fun init(project: Project) {
|
||||
val versionProperties = Properties().apply {
|
||||
load(FileInputStream(File("version.properties")))
|
||||
val propsPath = File(project.rootDir, "version.properties")
|
||||
println("Version: From $propsPath:")
|
||||
load(FileInputStream(propsPath))
|
||||
println("$this")
|
||||
}
|
||||
val major = versionProperties.getProperty("project.versioning.major").toInt()
|
||||
val minor = versionProperties.getProperty("project.versioning.minor").toInt()
|
||||
val patch = versionProperties.getProperty("project.versioning.patch").toInt()
|
||||
val build = versionProperties.getProperty("project.versioning.build").toInt()
|
||||
version = Version(
|
||||
major = versionProperties.getProperty("project.versioning.major").toInt(),
|
||||
minor = versionProperties.getProperty("project.versioning.minor").toInt(),
|
||||
patch = versionProperties.getProperty("project.versioning.patch").toInt(),
|
||||
build = versionProperties.getProperty("project.versioning.build").toInt(),
|
||||
type = versionProperties.getProperty("project.versioning.type"),
|
||||
)
|
||||
}
|
||||
|
||||
val name = "${major}.${minor}.${patch}-rc${build}"
|
||||
val code = major * 10000000 + minor * 100000 + patch * 1000 + build * 10
|
||||
data class Version(
|
||||
val major: Int,
|
||||
val minor: Int,
|
||||
val patch: Int,
|
||||
val build: Int,
|
||||
val type: String,
|
||||
) {
|
||||
val name: String
|
||||
get() = "${major}.${minor}.${patch}-$type${build}"
|
||||
val code: Long
|
||||
get() = major * 10000000 + minor * 100000 + patch * 1000 + build * 10L
|
||||
}
|
||||
}
|
||||
|
||||
fun lastCommitHash(): String = Runtime.getRuntime().exec("git rev-parse --short HEAD").let { process ->
|
||||
process.waitFor()
|
||||
val output = process.inputStream.use { input ->
|
||||
input.bufferedReader().use {
|
||||
it.readText()
|
||||
}
|
||||
class ProjectConfigPlugin : Plugin<Project> {
|
||||
override fun apply(project: Project) {
|
||||
val extension = project.extensions.create("projectConfig", ProjectConfig::class.java)
|
||||
extension.init(project)
|
||||
project.afterEvaluate { println("ProjectConfigPlugin loaded: $extension") }
|
||||
}
|
||||
process.destroy()
|
||||
output.trim()
|
||||
}
|
||||
|
||||
fun com.android.build.api.dsl.SigningConfig.setupCredentials(
|
||||
signingPropsPath: File? = null
|
||||
) {
|
||||
|
||||
val keyStoreFromEnv = System.getenv("STORE_PATH")?.let { File(it) }
|
||||
|
||||
if (keyStoreFromEnv?.exists() == true) {
|
||||
println("Using signing data from environment variables.")
|
||||
storeFile = keyStoreFromEnv
|
||||
storePassword = System.getenv("STORE_PASSWORD")
|
||||
keyAlias = System.getenv("KEY_ALIAS")
|
||||
keyPassword = System.getenv("KEY_PASSWORD")
|
||||
} else {
|
||||
println("Using signing data from properties file.")
|
||||
val props = Properties().apply {
|
||||
signingPropsPath?.takeIf { it.canRead() }?.let { load(FileInputStream(it)) }
|
||||
}
|
||||
|
||||
val keyStorePath = props.getProperty("release.storePath")?.let { File(it) }
|
||||
|
||||
if (keyStorePath?.exists() == true) {
|
||||
storeFile = keyStorePath
|
||||
storePassword = props.getProperty("release.storePassword")
|
||||
keyAlias = props.getProperty("release.keyAlias")
|
||||
keyPassword = props.getProperty("release.keyPassword")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
import com.android.build.api.dsl.SigningConfig
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.tasks.testing.Test
|
||||
import org.gradle.api.tasks.testing.TestDescriptor
|
||||
import org.gradle.api.tasks.testing.TestListener
|
||||
import org.gradle.api.tasks.testing.TestResult
|
||||
import org.gradle.api.tasks.testing.logging.TestExceptionFormat
|
||||
import org.gradle.api.tasks.testing.logging.TestLogEvent
|
||||
import java.io.File
|
||||
import java.io.FileInputStream
|
||||
import java.util.Properties
|
||||
|
||||
val Project.projectConfig: ProjectConfig
|
||||
get() = extensions.findByType(ProjectConfig::class.java)!!
|
||||
|
||||
fun SigningConfig.setupCredentials(
|
||||
signingPropsPath: File? = null
|
||||
) {
|
||||
|
||||
val keyStoreFromEnv = System.getenv("STORE_PATH")?.let { File(it) }
|
||||
|
||||
if (keyStoreFromEnv?.exists() == true) {
|
||||
println("Using signing data from environment variables.")
|
||||
storeFile = keyStoreFromEnv
|
||||
storePassword = System.getenv("STORE_PASSWORD")
|
||||
keyAlias = System.getenv("KEY_ALIAS")
|
||||
keyPassword = System.getenv("KEY_PASSWORD")
|
||||
} else {
|
||||
println("Using signing data from properties file.")
|
||||
val props = Properties().apply {
|
||||
signingPropsPath?.takeIf { it.canRead() }?.let { load(FileInputStream(it)) }
|
||||
}
|
||||
|
||||
val keyStorePath = props.getProperty("release.storePath")?.let { File(it) }
|
||||
|
||||
if (keyStorePath?.exists() == true) {
|
||||
storeFile = keyStorePath
|
||||
storePassword = props.getProperty("release.storePassword")
|
||||
keyAlias = props.getProperty("release.keyAlias")
|
||||
keyPassword = props.getProperty("release.keyPassword")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun Test.setupTestLogging() {
|
||||
testLogging {
|
||||
events(
|
||||
TestLogEvent.FAILED,
|
||||
TestLogEvent.PASSED,
|
||||
TestLogEvent.SKIPPED,
|
||||
// TestLogEvent.STANDARD_OUT,
|
||||
)
|
||||
exceptionFormat = TestExceptionFormat.FULL
|
||||
showExceptions = true
|
||||
showCauses = true
|
||||
showStackTraces = true
|
||||
|
||||
addTestListener(object : TestListener {
|
||||
override fun beforeSuite(suite: TestDescriptor) {}
|
||||
override fun beforeTest(testDescriptor: TestDescriptor) {}
|
||||
override fun afterTest(testDescriptor: TestDescriptor, result: TestResult) {}
|
||||
override fun afterSuite(suite: TestDescriptor, result: TestResult) {
|
||||
if (suite.parent != null) {
|
||||
val messages = """
|
||||
------------------------------------------------------------------------------------------------
|
||||
| ${result.resultType} ${result.testCount} tests: ${result.successfulTestCount} passed, ${result.failedTestCount} failed, ${result.skippedTestCount} skipped)
|
||||
------------------------------------------------------------------------------------------------
|
||||
|
||||
""".trimIndent()
|
||||
println(messages)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user