mirror of
https://github.com/kiwix/kiwix-android.git
synced 2025-08-03 10:46:53 -04:00
224 lines
7.9 KiB
Plaintext
224 lines
7.9 KiB
Plaintext
import com.slack.keeper.optInToKeeper
|
|
import org.w3c.dom.Element
|
|
import plugin.KiwixConfigurationPlugin
|
|
import java.io.StringWriter
|
|
import javax.xml.parsers.DocumentBuilderFactory
|
|
import javax.xml.transform.OutputKeys
|
|
import javax.xml.transform.TransformerFactory
|
|
import javax.xml.transform.dom.DOMSource
|
|
import javax.xml.transform.stream.StreamResult
|
|
|
|
plugins {
|
|
android
|
|
id("com.github.triplet.play") version Versions.com_github_triplet_play_gradle_plugin
|
|
}
|
|
if (hasProperty("testingMinimizedBuild")) {
|
|
apply(plugin = "com.slack.keeper")
|
|
}
|
|
plugins.apply(KiwixConfigurationPlugin::class)
|
|
|
|
apply(from = rootProject.file("jacoco.gradle"))
|
|
|
|
fun generateVersionName() = "${Config.versionMajor}.${Config.versionMinor}.${Config.versionPatch}"
|
|
|
|
val apkPrefix get() = System.getenv("TAG") ?: "kiwix"
|
|
|
|
android {
|
|
// Added namespace in response to Gradle 8.0 and above.
|
|
// This is now specified in the Gradle configuration instead of declaring
|
|
// it directly in the AndroidManifest file.
|
|
namespace = "org.kiwix.kiwixmobile"
|
|
compileSdkPreview = Config.compileSdk
|
|
defaultConfig {
|
|
minSdk = Config.minSdk
|
|
base.archivesName.set(apkPrefix)
|
|
targetSdkPreview = Config.targetSdk
|
|
resValue("string", "app_name", "Kiwix")
|
|
resValue("string", "app_search_string", "Search Kiwix")
|
|
versionCode = "".getVersionCode()
|
|
versionName = generateVersionName()
|
|
manifestPlaceholders["permission"] = "android.permission.MANAGE_EXTERNAL_STORAGE"
|
|
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
|
}
|
|
lint {
|
|
checkDependencies = true
|
|
}
|
|
|
|
buildTypes {
|
|
getByName("debug") {
|
|
multiDexKeepProguard = file("multidex-instrumentation-config.pro")
|
|
buildConfigField("boolean", "KIWIX_ERROR_ACTIVITY", "false")
|
|
buildConfigField("boolean", "IS_PLAYSTORE", "false")
|
|
}
|
|
|
|
getByName("release") {
|
|
buildConfigField("boolean", "KIWIX_ERROR_ACTIVITY", "true")
|
|
buildConfigField("boolean", "IS_PLAYSTORE", "false")
|
|
if (properties.containsKey("disableSigning")) {
|
|
signingConfig = null
|
|
}
|
|
}
|
|
create("playStore") {
|
|
manifestPlaceholders += mapOf()
|
|
initWith(getByName("release"))
|
|
matchingFallbacks += "release"
|
|
buildConfigField("boolean", "IS_PLAYSTORE", "true")
|
|
manifestPlaceholders["permission"] = "android.permission.placeholder"
|
|
}
|
|
create("standalone") {
|
|
initWith(getByName("release"))
|
|
matchingFallbacks += "release"
|
|
signingConfig = signingConfigs.getByName("releaseSigningConfig")
|
|
applicationIdSuffix = ".standalone" // Bug Fix #3933
|
|
}
|
|
create("nightly") {
|
|
initWith(getByName("debug"))
|
|
matchingFallbacks += "debug"
|
|
// Build the nightly APK with the released keyStore to make the APK updatable. See #3838
|
|
signingConfig = signingConfigs.getByName("releaseSigningConfig")
|
|
applicationIdSuffix = ".standalone" // Bug Fix #3933
|
|
}
|
|
}
|
|
bundle {
|
|
language {
|
|
// This is disabled so that the App Bundle does NOT split the APK for each language.
|
|
// We're gonna use the same APK for all languages.
|
|
enableSplit = false
|
|
}
|
|
}
|
|
sourceSets {
|
|
getByName("androidTest") {
|
|
java.srcDirs("$rootDir/core/src/sharedTestFunctions/java")
|
|
}
|
|
}
|
|
// By default, Android generates dependency metadata (a file containing information
|
|
// about all the dependencies used in the project) and includes it in both APKs and app bundles.
|
|
// This metadata is particularly useful for the Google Play Store, as it provides actionable
|
|
// feedback on potential issues with project dependencies. However, other platforms cannot
|
|
// utilize this metadata. For example, platforms like IzzyOnDroid, GitHub, and our website do not
|
|
// require or utilize the metadata.
|
|
// Since we only upload app bundles to the Play Store for kiwix app, dependency metadata
|
|
// is enabled for app bundles to leverage Google Play Store's analysis
|
|
// and feedback. For APKs distributed outside the Play Store, we exclude this metadata
|
|
// as they do not require this.
|
|
// See https://github.com/kiwix/kiwix-android/issues/4053#issuecomment-2456951610 for details.
|
|
dependenciesInfo {
|
|
// Disables dependency metadata when building APKs.
|
|
// This is for the signed APKs posted on IzzyOnDroid, GitHub, and our website,
|
|
// where dependency metadata is not required or utilized.
|
|
includeInApk = false
|
|
// Enables dependency metadata when building Android App Bundles.
|
|
// This is specifically for the Google Play Store, where dependency metadata
|
|
// is analyzed to provide actionable feedback on potential issues with dependencies.
|
|
includeInBundle = true
|
|
}
|
|
}
|
|
|
|
play {
|
|
enabled.set(true)
|
|
serviceAccountCredentials.set(file("../playstore.json"))
|
|
track.set("internal")
|
|
releaseStatus.set(com.github.triplet.gradle.androidpublisher.ReleaseStatus.COMPLETED)
|
|
resolutionStrategy.set(com.github.triplet.gradle.androidpublisher.ResolutionStrategy.FAIL)
|
|
}
|
|
|
|
androidComponents {
|
|
beforeVariants { variantBuilder ->
|
|
if (variantBuilder.name == "debug" && hasProperty("testingMinimizedBuild")) {
|
|
variantBuilder.optInToKeeper()
|
|
}
|
|
}
|
|
}
|
|
|
|
dependencies {
|
|
androidTestImplementation(Libs.leakcanary_android_instrumentation)
|
|
testImplementation(Libs.kotlinx_coroutines_test)
|
|
}
|
|
task("generateVersionCodeAndName") {
|
|
val file = File("VERSION_INFO")
|
|
if (!file.exists()) file.createNewFile()
|
|
file.printWriter().use {
|
|
it.print("${generateVersionName()}\n7${"".getVersionCode()}")
|
|
}
|
|
}
|
|
|
|
task("renameTarakFile") {
|
|
val taraskFile = File("$rootDir/core/src/main/res/values-b+be+tarask/strings.xml")
|
|
val mainStringsFile = File("$rootDir/core/src/main/res/values/strings.xml")
|
|
|
|
if (taraskFile.exists() && mainStringsFile.exists()) {
|
|
val taraskOldFile = File("core/src/main/res/values-b+be+tarask+old/strings.xml")
|
|
if (!taraskOldFile.exists()) taraskOldFile.createNewFile()
|
|
|
|
// Parse the main strings.xml file and extract the string tags
|
|
val mainTags = getStringTags(mainStringsFile)
|
|
|
|
// Parse the tarask file and filter strings based on tags present in the main strings file
|
|
// This ensures that any string removed from the main strings file will not be
|
|
// added to the old file, and it prevents lint errors.
|
|
val filteredContent = filterStringsByTags(taraskFile, mainTags)
|
|
|
|
// Write the filtered content to the taraskOldFile
|
|
taraskOldFile.printWriter().use { writer ->
|
|
writer.println("""<?xml version="1.0" encoding="utf-8"?>""")
|
|
writer.println("<resources>")
|
|
filteredContent.forEach { string ->
|
|
writer.println(" $string")
|
|
}
|
|
writer.println("</resources>")
|
|
}
|
|
|
|
taraskFile.delete()
|
|
}
|
|
}
|
|
|
|
fun getStringTags(file: File): Set<String> {
|
|
val tags = mutableSetOf<String>()
|
|
val factory = DocumentBuilderFactory.newInstance()
|
|
val builder = factory.newDocumentBuilder()
|
|
val doc = builder.parse(file)
|
|
val nodeList = doc.getElementsByTagName("string")
|
|
|
|
(0 until nodeList.length)
|
|
.asSequence()
|
|
.map { nodeList.item(it) as Element }
|
|
.mapTo(tags) { it.getAttribute("name") }
|
|
|
|
return tags
|
|
}
|
|
|
|
fun filterStringsByTags(
|
|
file: File,
|
|
tags: Set<String>
|
|
): List<String> {
|
|
val filteredStrings = mutableListOf<String>()
|
|
val factory = DocumentBuilderFactory.newInstance()
|
|
val builder = factory.newDocumentBuilder()
|
|
val doc = builder.parse(file)
|
|
val nodeList = doc.getElementsByTagName("string")
|
|
|
|
for (i in 0 until nodeList.length) {
|
|
val element = nodeList.item(i) as Element
|
|
val name = element.getAttribute("name")
|
|
if (name in tags) {
|
|
filteredStrings.add(elementToString(element))
|
|
}
|
|
}
|
|
|
|
return filteredStrings
|
|
}
|
|
|
|
fun elementToString(element: Element): String {
|
|
val transformer = TransformerFactory.newInstance().newTransformer().apply {
|
|
setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes")
|
|
}
|
|
val result = StreamResult(StringWriter())
|
|
val source = DOMSource(element)
|
|
transformer.transform(source, result)
|
|
return result.writer.toString()
|
|
}
|
|
|
|
tasks.build {
|
|
dependsOn("renameTarakFile")
|
|
}
|