Repo cloned
This commit is contained in:
commit
496ae75f58
7988 changed files with 1451097 additions and 0 deletions
30
build-logic/plugins/build.gradle.kts
Normal file
30
build-logic/plugins/build.gradle.kts
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
plugins {
|
||||
`kotlin-dsl`
|
||||
}
|
||||
|
||||
val signalJavaVersion: JavaVersion by rootProject.extra
|
||||
val signalKotlinJvmTarget: String by rootProject.extra
|
||||
|
||||
java {
|
||||
sourceCompatibility = signalJavaVersion
|
||||
targetCompatibility = signalJavaVersion
|
||||
}
|
||||
|
||||
kotlin {
|
||||
jvmToolchain {
|
||||
languageVersion.set(JavaLanguageVersion.of(signalKotlinJvmTarget))
|
||||
}
|
||||
compilerOptions {
|
||||
suppressWarnings = true
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(libs.kotlin.gradle.plugin)
|
||||
implementation(libs.android.library)
|
||||
implementation(libs.android.application)
|
||||
|
||||
// These allow us to reference the dependency catalog inside of our compiled plugins
|
||||
implementation(files(libs.javaClass.superclass.protectionDomain.codeSource.location))
|
||||
implementation(files(testLibs.javaClass.superclass.protectionDomain.codeSource.location))
|
||||
}
|
||||
200
build-logic/plugins/src/main/java/molly.gradle.kts
Normal file
200
build-logic/plugins/src/main/java/molly.gradle.kts
Normal file
|
|
@ -0,0 +1,200 @@
|
|||
import com.android.build.gradle.AppExtension
|
||||
import org.jetbrains.kotlin.com.google.gson.Gson
|
||||
import org.w3c.dom.Document
|
||||
import org.w3c.dom.Element
|
||||
import javax.xml.parsers.DocumentBuilderFactory
|
||||
import javax.xml.transform.TransformerFactory
|
||||
import javax.xml.transform.dom.DOMSource
|
||||
import javax.xml.transform.stream.StreamResult
|
||||
|
||||
/**
|
||||
* Utility object for parsing and manipulating xml resource files.
|
||||
*/
|
||||
object XmlRes {
|
||||
fun parseStrings(stringsFile: File): Pair<Document, List<Element>> {
|
||||
val doc = parseXmlFile(stringsFile)
|
||||
val strings = doc.getElements("string") + doc.getElements("plurals")
|
||||
return doc to strings
|
||||
}
|
||||
|
||||
fun parseColors(stringsFile: File): Pair<Document, Map<String, String>> {
|
||||
val doc = parseXmlFile(stringsFile)
|
||||
val colors = doc.getElements("color").associateBy(
|
||||
{ it.getAttribute("name") }, { it.firstChild.nodeValue }
|
||||
)
|
||||
return doc to colors
|
||||
}
|
||||
|
||||
fun writeToFile(doc: Document, file: File) {
|
||||
val transformer = TransformerFactory.newInstance().newTransformer()
|
||||
transformer.transform(DOMSource(doc), StreamResult(file))
|
||||
}
|
||||
|
||||
private fun parseXmlFile(file: File): Document {
|
||||
val docBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder()
|
||||
return docBuilder.parse(file).apply {
|
||||
xmlStandalone = true
|
||||
}
|
||||
}
|
||||
|
||||
private fun Document.getElements(tagName: String) =
|
||||
getElementsByTagName(tagName).let { nodes ->
|
||||
(0 until nodes.length).map { nodes.item(it) as Element }
|
||||
}
|
||||
}
|
||||
|
||||
val updateTranslationsForMolly by tasks.registering {
|
||||
group = "Molly"
|
||||
description = "Updates references to \"Signal\" with \"Molly\" in all translation files."
|
||||
|
||||
doLast {
|
||||
val englishFile = file("src/main/res/values/strings.xml")
|
||||
val (_, englishStrings) = XmlRes.parseStrings(englishFile)
|
||||
|
||||
// Gather all string names containing "mollyify" attribute
|
||||
val mollyifyList = englishStrings
|
||||
.filter { it.getAttribute("mollyify") == "true" }
|
||||
.map { it.getAttribute("name") }
|
||||
.toSet()
|
||||
|
||||
// Iterate through each translation file and perform the replacements
|
||||
project.fileTree("src/main/res") {
|
||||
include("**/values-*/strings.xml")
|
||||
}.forEach { translationFile ->
|
||||
try {
|
||||
val (translationDoc, translatedStrings) = XmlRes.parseStrings(translationFile)
|
||||
var modified = false
|
||||
|
||||
translatedStrings.forEach { elem ->
|
||||
val name = elem.getAttribute("name")
|
||||
if (name in mollyifyList) {
|
||||
when (elem.tagName) {
|
||||
"string" -> {
|
||||
modified = elem.replaceSignalRefs() or modified
|
||||
}
|
||||
|
||||
"plurals" -> {
|
||||
val items = elem.getElementsByTagName("item")
|
||||
for (i in 0 until items.length) {
|
||||
val item = items.item(i) as Element
|
||||
modified = item.replaceSignalRefs() or modified
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (modified) {
|
||||
// Write back the modified translation file only if replacements were made
|
||||
XmlRes.writeToFile(translationDoc, translationFile)
|
||||
logger.lifecycle("Updated translations in: ${translationFile.toRelativeString(project.rootDir)}")
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
logger.error("Error processing file: ${translationFile.path}, ${e.message}")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun Element.replaceSignalRefs(): Boolean {
|
||||
val oldContent = textContent
|
||||
textContent = textContent
|
||||
.replace("Signal", "Molly")
|
||||
.replace("signal.org", "molly.im")
|
||||
return oldContent != textContent
|
||||
}
|
||||
|
||||
val updateColorsForMolly by tasks.registering {
|
||||
group = "custom"
|
||||
description = "Replaces Signal colors with Molly colors in the app source set."
|
||||
|
||||
doLast {
|
||||
val appModule = project.rootProject.project(":app")
|
||||
val mappingFile = appModule.file("src/main/res/values/molly_colors.xml")
|
||||
val (_, colors) = XmlRes.parseColors(mappingFile)
|
||||
|
||||
val colorMappings = colors
|
||||
.filterKeys { it.startsWith("stock_") }
|
||||
.map { (signalColorName, signalColor) ->
|
||||
val mollyColor = colors[signalColorName.replaceFirst("stock_", "molly_")]
|
||||
?: throw GradleException("No 'molly_*' color found for '$signalColorName' in '$mappingFile'")
|
||||
signalColor.uppercase() to mollyColor.uppercase()
|
||||
}
|
||||
.toSet()
|
||||
|
||||
val signalToMolly = colorMappings.groupBy({ it.first }, { it.second })
|
||||
val mollyToSignal = colorMappings.groupBy({ it.second }, { it.first })
|
||||
|
||||
val signalConflicts = signalToMolly.filterValues { it.size > 1 }
|
||||
val mollyConflicts = mollyToSignal.filterValues { it.size > 1 }
|
||||
|
||||
val cycles = mollyToSignal.keys.intersect(signalToMolly.keys).filterNot { color ->
|
||||
color in signalToMolly[color].orEmpty() && color in mollyToSignal[color].orEmpty()
|
||||
}
|
||||
|
||||
if (signalConflicts.isNotEmpty() || mollyConflicts.isNotEmpty() || cycles.isNotEmpty()) {
|
||||
logger.error("Conflict detected! Some colors map to multiple values:")
|
||||
signalConflicts.forEach { (color, set) -> logger.error("Signal $color → Molly: $set") }
|
||||
mollyConflicts.forEach { (color, set) -> logger.error("Molly $color ← Signal: $set") }
|
||||
cycles.forEach { logger.error("Signal ↔ Molly: $it") }
|
||||
|
||||
throw GradleException("Conflicting color mappings found in '$mappingFile'")
|
||||
}
|
||||
|
||||
val regexReplacements = colorMappings.map { (signalColor, mollyColor) ->
|
||||
val signalHex = signalColor.drop(1)
|
||||
val mollyHex = mollyColor.drop(1)
|
||||
val pattern = """(0x|#)([0-9A-Fa-f]{2})?($signalHex)\b""".toRegex(RegexOption.IGNORE_CASE)
|
||||
pattern to mollyHex
|
||||
}
|
||||
|
||||
val sourceFiles = fileTree(project.file("src/main")) {
|
||||
include("**/*.xml", "**/*.kt", "**/*.java")
|
||||
exclude("**/${mappingFile.name}", "res/values*/strings*.xml")
|
||||
}
|
||||
|
||||
var anyChanges = false
|
||||
|
||||
sourceFiles.files.parallelStream().forEach { file ->
|
||||
val originalContent = file.readText()
|
||||
var modifiedContent = originalContent
|
||||
var changesInFile = 0
|
||||
|
||||
regexReplacements.forEach { (regex, newColor) ->
|
||||
modifiedContent = regex.replace(modifiedContent) { match ->
|
||||
val (_, prefix, alpha, color) = match.groupValues
|
||||
if (!color.equals(newColor, ignoreCase = true)) {
|
||||
changesInFile++
|
||||
"$prefix$alpha$newColor"
|
||||
} else match.value
|
||||
}
|
||||
}
|
||||
|
||||
if (changesInFile > 0) {
|
||||
file.writeText(modifiedContent)
|
||||
logger.lifecycle("Updated: ${file.toRelativeString(project.rootDir)}: $changesInFile change(s)")
|
||||
anyChanges = true
|
||||
}
|
||||
}
|
||||
|
||||
logger.lifecycle(
|
||||
if (anyChanges) "Finished updating Signal colors to Molly."
|
||||
else "No changes needed. Colors are already updated."
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
val version by tasks.registering {
|
||||
doLast {
|
||||
val android = project.extensions.getByType(AppExtension::class)
|
||||
val versionCode = android.defaultConfig.versionCode
|
||||
val versionName = android.defaultConfig.versionName
|
||||
|
||||
val versionInfo = mapOf(
|
||||
"versionCode" to versionCode,
|
||||
"versionName" to versionName
|
||||
)
|
||||
|
||||
println(Gson().toJson(versionInfo))
|
||||
}
|
||||
}
|
||||
68
build-logic/plugins/src/main/java/signal-library.gradle.kts
Normal file
68
build-logic/plugins/src/main/java/signal-library.gradle.kts
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
@file:Suppress("UnstableApiUsage")
|
||||
|
||||
import org.gradle.accessors.dm.LibrariesForLibs
|
||||
import org.gradle.accessors.dm.LibrariesForTestLibs
|
||||
import org.gradle.api.JavaVersion
|
||||
import org.gradle.kotlin.dsl.extra
|
||||
|
||||
val libs = the<LibrariesForLibs>()
|
||||
val testLibs = the<LibrariesForTestLibs>()
|
||||
|
||||
val signalBuildToolsVersion: String by rootProject.extra
|
||||
val signalCompileSdkVersion: String by rootProject.extra
|
||||
val signalTargetSdkVersion: Int by rootProject.extra
|
||||
val signalMinSdkVersion: Int by rootProject.extra
|
||||
val signalJavaVersion: JavaVersion by rootProject.extra
|
||||
val signalKotlinJvmTarget: String by rootProject.extra
|
||||
|
||||
plugins {
|
||||
// We cannot use the version catalog in the plugins block in convention plugins (it's not supported).
|
||||
// Instead, plugin versions are controlled through the dependencies block in the build.gradle.kts.
|
||||
id("com.android.library")
|
||||
id("kotlin-android")
|
||||
}
|
||||
|
||||
android {
|
||||
buildToolsVersion = signalBuildToolsVersion
|
||||
compileSdkVersion = signalCompileSdkVersion
|
||||
|
||||
defaultConfig {
|
||||
minSdk = signalMinSdkVersion
|
||||
vectorDrawables.useSupportLibrary = true
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
isCoreLibraryDesugaringEnabled = true
|
||||
sourceCompatibility = signalJavaVersion
|
||||
targetCompatibility = signalJavaVersion
|
||||
}
|
||||
|
||||
kotlinOptions {
|
||||
jvmTarget = signalKotlinJvmTarget
|
||||
suppressWarnings = true
|
||||
}
|
||||
|
||||
lint {
|
||||
disable += "InvalidVectorPath"
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
lintChecks(project(":lintchecks"))
|
||||
|
||||
coreLibraryDesugaring(libs.android.tools.desugar)
|
||||
|
||||
implementation(libs.androidx.core.ktx)
|
||||
implementation(libs.androidx.fragment.ktx)
|
||||
implementation(libs.androidx.annotation)
|
||||
implementation(libs.androidx.appcompat)
|
||||
implementation(libs.rxjava3.rxandroid)
|
||||
implementation(libs.rxjava3.rxjava)
|
||||
implementation(libs.rxjava3.rxkotlin)
|
||||
implementation(libs.kotlin.stdlib.jdk8)
|
||||
|
||||
testImplementation(testLibs.junit.junit)
|
||||
testImplementation(testLibs.robolectric.robolectric)
|
||||
testImplementation(testLibs.androidx.test.core)
|
||||
testImplementation(testLibs.androidx.test.core.ktx)
|
||||
}
|
||||
|
|
@ -0,0 +1,85 @@
|
|||
@file:Suppress("UnstableApiUsage")
|
||||
|
||||
import org.gradle.accessors.dm.LibrariesForLibs
|
||||
import org.gradle.accessors.dm.LibrariesForTestLibs
|
||||
import org.gradle.api.JavaVersion
|
||||
import org.gradle.kotlin.dsl.extra
|
||||
import org.gradle.kotlin.dsl.provideDelegate
|
||||
import org.gradle.kotlin.dsl.the
|
||||
|
||||
val libs = the<LibrariesForLibs>()
|
||||
val testLibs = the<LibrariesForTestLibs>()
|
||||
|
||||
val signalBuildToolsVersion: String by rootProject.extra
|
||||
val signalCompileSdkVersion: String by rootProject.extra
|
||||
val signalTargetSdkVersion: Int by rootProject.extra
|
||||
val signalMinSdkVersion: Int by rootProject.extra
|
||||
val signalJavaVersion: JavaVersion by rootProject.extra
|
||||
val signalKotlinJvmTarget: String by rootProject.extra
|
||||
|
||||
plugins {
|
||||
// We cannot use the version catalog in the plugins block in convention plugins (it's not supported).
|
||||
// Instead, plugin versions are controlled through the dependencies block in the build.gradle.kts.
|
||||
id("com.android.application")
|
||||
id("kotlin-android")
|
||||
}
|
||||
|
||||
android {
|
||||
buildToolsVersion = signalBuildToolsVersion
|
||||
compileSdkVersion = signalCompileSdkVersion
|
||||
|
||||
defaultConfig {
|
||||
versionCode = 1
|
||||
versionName = "1.0"
|
||||
|
||||
minSdk = signalMinSdkVersion
|
||||
targetSdk = signalTargetSdkVersion
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
isCoreLibraryDesugaringEnabled = true
|
||||
sourceCompatibility = signalJavaVersion
|
||||
targetCompatibility = signalJavaVersion
|
||||
}
|
||||
|
||||
kotlinOptions {
|
||||
jvmTarget = signalKotlinJvmTarget
|
||||
suppressWarnings = true
|
||||
}
|
||||
|
||||
buildFeatures {
|
||||
buildConfig = true
|
||||
compose = true
|
||||
}
|
||||
|
||||
composeOptions {
|
||||
kotlinCompilerExtensionVersion = "1.5.4"
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
coreLibraryDesugaring(libs.android.tools.desugar)
|
||||
|
||||
implementation(project(":core-util"))
|
||||
|
||||
coreLibraryDesugaring(libs.android.tools.desugar)
|
||||
|
||||
implementation(libs.androidx.core.ktx)
|
||||
implementation(libs.androidx.fragment.ktx)
|
||||
implementation(libs.androidx.annotation)
|
||||
implementation(libs.androidx.appcompat)
|
||||
implementation(libs.rxjava3.rxandroid)
|
||||
implementation(libs.rxjava3.rxjava)
|
||||
implementation(libs.rxjava3.rxkotlin)
|
||||
implementation(libs.material.material)
|
||||
implementation(libs.androidx.constraintlayout)
|
||||
implementation(libs.kotlin.stdlib.jdk8)
|
||||
implementation(libs.androidx.activity.compose)
|
||||
implementation(platform(libs.androidx.compose.bom))
|
||||
implementation(libs.androidx.compose.material3)
|
||||
|
||||
testImplementation(testLibs.junit.junit)
|
||||
testImplementation(testLibs.robolectric.robolectric)
|
||||
testImplementation(testLibs.androidx.test.core)
|
||||
testImplementation(testLibs.androidx.test.core.ktx)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue