Skip to content

Commit

Permalink
build: normalize build logic
Browse files Browse the repository at this point in the history
  • Loading branch information
WhiredPlanck committed Dec 20, 2023
1 parent cb76a43 commit 1dc7a45
Show file tree
Hide file tree
Showing 10 changed files with 211 additions and 142 deletions.
139 changes: 7 additions & 132 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,18 +1,8 @@
@file:Suppress("UnstableApiUsage")

import android.databinding.tool.ext.capitalizeUS
import com.android.build.gradle.internal.tasks.factory.dependsOn
import com.google.common.hash.Hashing
import com.google.common.io.Files
import groovy.json.JsonOutput
import groovy.json.JsonSlurper
import java.io.ByteArrayOutputStream
import java.nio.charset.Charset
import java.io.StringWriter
import java.util.Properties
import java.util.TimeZone
import java.util.Date
import java.text.SimpleDateFormat
import org.gradle.configurationcache.extensions.capitalized

plugins {
id("com.android.application")
Expand All @@ -22,42 +12,6 @@ plugins {
id("com.mikepenz.aboutlibraries.plugin")
}

fun exec(cmd: String): String = ByteArrayOutputStream().use {
project.exec {
commandLine = cmd.split(" ")
standardOutput = it
}
it.toString().trim()
}
fun envOrDefault(env: String, default: () -> String): String {
val v = System.getenv(env)
return if (v.isNullOrBlank()) default() else v
}

val gitUserOrCIName = envOrDefault("CI_NAME") {
exec("git config user.name")
}
val gitVersionName = exec("git describe --tags --long --always")
val gitHashShort = exec("git rev-parse --short HEAD")
val gitRemoteUrl = exec("git remote get-url origin")
.replaceFirst("^git@github\\.com:", "https://github.com/")
.replaceFirst("\\.git\$", "")

fun buildInfo(): String {
val writer = StringWriter()
val time = SimpleDateFormat("yyyy-MM-dd HH:mm:ss").apply {
timeZone = TimeZone.getTimeZone("UTC")
}.format(Date(System.currentTimeMillis()))
writer.append("Builder: ${gitUserOrCIName}\\n")
writer.append("Build Time: $time UTC\\n")
writer.append("Build Version Name: ${gitVersionName}\\n")
writer.append("Git Hash: ${gitHashShort}\\n")
writer.append("Git Repo: $gitRemoteUrl")
val info = writer.toString()
println(info)
return info
}

android {
namespace = "com.osfans.trime"
compileSdk = 34
Expand All @@ -73,10 +27,11 @@ android {

multiDexEnabled = true
setProperty("archivesBaseName", "trime-$versionName")
buildConfigField("String", "BUILD_GIT_HASH", "\"${gitHashShort}\"")
buildConfigField("String", "BUILD_GIT_REPO", "\"${gitRemoteUrl}\"")
buildConfigField("String", "BUILD_VERSION_NAME", "\"${gitVersionName}\"")
buildConfigField("String", "BUILD_INFO", "\"${buildInfo()}\"")
buildConfigField("String", "BUILDER", "\"${project.builder}\"")
buildConfigField("long", "BUILD_TIMESTAMP", project.buildTimestamp)
buildConfigField("String", "BUILD_COMMIT_HASH", "\"${project.buildCommitHash}\"")
buildConfigField("String", "BUILD_GIT_REPO", "\"${project.buildGitRepo}\"")
buildConfigField("String", "BUILD_VERSION_NAME", "\"${project.buildVersionName}\"")
}

signingConfigs {
Expand Down Expand Up @@ -190,7 +145,7 @@ val generateDataChecksum by tasks.register<DataChecksumsTask>("generateDataCheck
}

android.applicationVariants.all {
val variantName = name.capitalizeUS()
val variantName = name.capitalized()
tasks.findByName("merge${variantName}Assets")?.dependsOn(generateDataChecksum)
}

Expand Down Expand Up @@ -236,83 +191,3 @@ dependencies {
testImplementation("junit:junit:4.13.2")
androidTestImplementation("junit:junit:4.13.2")
}

abstract class DataChecksumsTask : DefaultTask() {
@get:Incremental
@get:PathSensitive(PathSensitivity.NAME_ONLY)
@get:InputDirectory
abstract val inputDir: DirectoryProperty

@get:OutputFile
abstract val outputFile: RegularFileProperty

private val file by lazy { outputFile.get().asFile }

private fun serialize(map: Map<String, String>) {
file.deleteOnExit()
file.writeText(
JsonOutput.prettyPrint(
JsonOutput.toJson(
mapOf<Any, Any>(
"sha256" to Hashing.sha256()
.hashString(
map.entries.joinToString { it.key + it.value },
Charset.defaultCharset()
)
.toString(),
"files" to map
)
)
)
)
}

@Suppress("UNCHECKED_CAST")
private fun deserialize(): Map<String, String> =
((JsonSlurper().parseText(file.readText()) as Map<Any, Any>))["files"] as Map<String, String>

companion object {
fun sha256(file: File): String =
Files.asByteSource(file).hash(Hashing.sha256()).toString()
}

@TaskAction
fun execute(inputChanges: InputChanges) {
val map =
file.exists()
.takeIf { it }
?.runCatching {
deserialize()
// remove all old dirs
.filterValues { it.isNotBlank() }
.toMutableMap()
}
?.getOrNull()
?: mutableMapOf()

fun File.allParents(): List<File> =
if (parentFile == null || parentFile.path in map)
listOf()
else
listOf(parentFile) + parentFile.allParents()
inputChanges.getFileChanges(inputDir).forEach { change ->
if (change.file.name == file.name)
return@forEach
logger.log(LogLevel.DEBUG, "${change.changeType}: ${change.normalizedPath}")
val relativeFile = change.file.relativeTo(file.parentFile)
val key = relativeFile.path
if (change.changeType == ChangeType.REMOVED) {
map.remove(key)
} else {
map[key] = sha256(change.file)
}
}
// calculate dirs
inputDir.asFileTree.forEach {
it.relativeTo(file.parentFile).allParents().forEach { p ->
map[p.path] = ""
}
}
serialize(map.toSortedMap())
}
}
15 changes: 11 additions & 4 deletions app/src/main/java/com/osfans/trime/ui/fragments/AboutFragment.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@ import androidx.navigation.fragment.findNavController
import androidx.preference.Preference
import androidx.preference.get
import com.blankj.utilcode.util.ToastUtils
import com.osfans.trime.BuildConfig
import com.osfans.trime.R
import com.osfans.trime.core.Rime
import com.osfans.trime.data.opencc.OpenCCDictManager
import com.osfans.trime.ui.components.PaddingPreferenceFragment
import com.osfans.trime.ui.main.MainViewModel
import com.osfans.trime.util.Const
import com.osfans.trime.util.formatDateTime
import com.osfans.trime.util.optionalPreference
import com.osfans.trime.util.thirdPartySummary
import splitties.systemservices.clipboardManager
Expand All @@ -35,11 +35,18 @@ class AboutFragment : PaddingPreferenceFragment() {
intent =
Intent(
Intent.ACTION_VIEW,
Uri.parse("${Const.currentGitRepo}/commits/${Const.buildGitHash}"),
Uri.parse("${Const.currentGitRepo}/commits/${Const.buildCommitHash}"),
)
}
get<Preference>("about__buildinfo")?.apply {
summary = BuildConfig.BUILD_INFO
get<Preference>("about__build_info")?.apply {
summary =
requireContext().getString(
R.string.about__build_info_format,
Const.builder,
formatDateTime(Const.buildTimestamp),
Const.buildCommitHash,
Const.currentGitRepo,
)
setOnPreferenceClickListener {
val info = ClipData.newPlainText("BuildInfo", summary)
clipboardManager.setPrimaryClip(info)
Expand Down
4 changes: 3 additions & 1 deletion app/src/main/java/com/osfans/trime/util/Const.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ package com.osfans.trime.util
import com.osfans.trime.BuildConfig

object Const {
val buildGitHash = BuildConfig.BUILD_GIT_HASH
val builder = BuildConfig.BUILDER
val buildTimestamp = BuildConfig.BUILD_TIMESTAMP
val buildCommitHash = BuildConfig.BUILD_COMMIT_HASH
val displayVersionName = "${BuildConfig.BUILD_VERSION_NAME}-${BuildConfig.BUILD_TYPE}"
val originalGitRepo = "https://github.com/osfans/trime"
val currentGitRepo = BuildConfig.BUILD_GIT_REPO
Expand Down
3 changes: 2 additions & 1 deletion app/src/main/res/values-zh-rCN/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
<string name="pref_credits">贡献代码</string>
<string name="about__product_prime">微软平台PRIME输入法</string>
<string name="about__privacy_policy">隐私策略</string>
<string name="about__build_info_format">构建者:%s\nGit 仓库: %s\n构建 Git 哈希: %s\n构建时间: %s</string>
<string name="pref_enable">启用</string>
<string name="pref_enable_summary">启用同文输入法</string>
<string name="pref_select">选取软键盘</string>
Expand Down Expand Up @@ -181,7 +182,7 @@
<string name="keyboard__swipe_enabled">允许触发按键的滑动手势</string>
<string name="keyboard__key_swipe_velocity">触发按键滑动手势的速度(距离/速度满足其一即可)</string>
<string name="keyboard__key_swipe_velocity_hi">连续击键时触发滑动手势的速度</string>
<string name="about__buildinfo">编译信息</string>
<string name="about__build_info">构建信息</string>
<string name="keyboard__use_mini_keyboard_title">连接实体键盘时,显示迷你软键盘</string>
<string name="pref_trime_custom_qq">修改版QQ群</string>
<string name="pref_keyboard__candidate">候选栏</string>
Expand Down
3 changes: 2 additions & 1 deletion app/src/main/res/values-zh-rTW/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
<string name="pref_credits">貢獻代碼</string>
<string name="about__product_prime">Win10 PRIME輸入法平臺</string>
<string name="about__privacy_policy">隱私權政策</string>
<string name="about__build_info_format">建構者:%s\nGit 倉庫: %s\n建構 Git 雜湊值: %s\n建構時間: %s</string>
<string name="pref_enable">啓用</string>
<string name="pref_enable_summary">啓用同文輸入法平臺</string>
<string name="pref_select">選取軟鍵盤</string>
Expand Down Expand Up @@ -185,7 +186,7 @@
<string name="keyboard__swipe_enabled">允許觸發按鍵的滑動手勢</string>
<string name="keyboard__key_swipe_velocity">觸發按鍵滑動手勢的速度(距離/速度滿足其一即可)</string>
<string name="keyboard__key_swipe_velocity_hi">連續擊鍵時觸發滑動手勢的速度</string>
<string name="about__buildinfo">編譯信息</string>
<string name="about__build_info">建構資訊</string>
<string name="keyboard__use_mini_keyboard_title">連接實體鍵盤時,顯示迷你軟鍵盤</string>
<string name="pref_trime_custom_qq">修改版QQ羣</string>
<string name="pref_keyboard__candidate">候選欄</string>
Expand Down
3 changes: 2 additions & 1 deletion app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
<string name="pref_credits">Contribute</string>
<string name="about__product_prime">Win10 PRIME Platform</string>
<string name="about__privacy_policy">Privacy Policy</string>
<string name="about__build_info_format">Builder: %s\nGit Repo: %s\nBuild Git Hash: %s\nBuild Time: %s</string>
<string name="pref_enable">Enable</string>
<string name="pref_enable_summary">Enable Trime</string>
<string name="pref_select">Change Keyboard</string>
Expand Down Expand Up @@ -189,7 +190,7 @@
<string name="keyboard__swipe_enabled">Allow swipe gestures to trigger keys</string>
<string name="keyboard__key_swipe_velocity">The speed of triggering the button swipe gesture (the distance/velocity is sufficient)</string>
<string name="keyboard__key_swipe_velocity_hi">The velocity of the swipe gesture on consecutive keystrokes</string>
<string name="about__buildinfo">Build info</string>
<string name="about__build_info">Build Info</string>
<string name="keyboard__use_mini_keyboard_title">Show mini keyboard with real keyboard attached</string>
<string name="pref_trime_custom_qq">Custom QQ Group</string>
<string name="pref_trime_custom_qq_summary" translatable="false"> </string>
Expand Down
4 changes: 2 additions & 2 deletions app/src/main/res/xml/about_preference.xml
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
app:iconSpaceReserved="false">
</Preference>

<Preference app:key="about__buildinfo"
app:title="@string/about__buildinfo"
<Preference app:key="about__build_info"
app:title="@string/about__build_info"
app:iconSpaceReserved="false"> />
</Preference>

Expand Down
9 changes: 9 additions & 0 deletions buildSrc/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,7 +1,16 @@
plugins {
`kotlin-dsl`
kotlin("plugin.serialization") version embeddedKotlinVersion
}

repositories {
google()
mavenCentral()
gradlePluginPortal()
}

dependencies {
compileOnly("com.android.tools.build:gradle:8.2.0")
compileOnly("org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.20")
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.1")
}
76 changes: 76 additions & 0 deletions buildSrc/src/main/kotlin/Utils.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import kotlinx.serialization.json.Json
import org.gradle.api.Project
import org.gradle.api.Task
import java.io.ByteArrayOutputStream
import java.io.File

inline fun envOrDefault(
env: String,
default: () -> String,
) = System.getenv(env)?.takeIf { it.isNotBlank() } ?: default()

inline fun Project.propertyOrDefault(
prop: String,
default: () -> String,
) = runCatching { property(prop)!!.toString() }.getOrElse {
default()
}

fun Project.runCmd(cmd: String): String =
ByteArrayOutputStream().use {
project.exec {
commandLine = cmd.split(" ")
standardOutput = it
}
it.toString().trim()
}

val json = Json { prettyPrint = true }

internal inline fun Project.envOrProp(
env: String,
prop: String,
block: () -> String,
) = envOrDefault(env) {
propertyOrDefault(prop) {
block()
}
}

val Project.assetsDir: File
get() = file("src/main/assets").also { it.mkdirs() }

val Project.cleanTask: Task
get() = tasks.getByName("clean")

val Project.builder
get() =
envOrProp("CI_NAME", "ciName") {
runCmd("git config user.name")
}

val Project.buildGitRepo
get() =
envOrProp("BUILD_GIT_REPO", "buildGitRepo") {
runCmd("git remote get-url origin")
.replaceFirst("^git@github\\.com:", "https://github.com/")
.replaceFirst("\\.git\$", "")
}

val Project.buildVersionName
get() =
envOrProp("BUILD_VERSION_NAME", "buildVersionName") {
runCmd("git describe --tags --long --always")
}

val Project.buildCommitHash
get() =
envOrProp("BUILD_COMMIT_HASH", "buildCommitHash") {
runCmd("git rev-parse HEAD")
}

val Project.buildTimestamp
get() =
envOrProp("BUILD_TIMESTAMP", "buildTimestamp") {
System.currentTimeMillis().toString()
}
Loading

0 comments on commit 1dc7a45

Please sign in to comment.