feat(build): pull out Crowdin tasks to their own classes

This commit is contained in:
Harsh Shandilya 2023-03-21 13:28:16 +05:30
parent 9f554376e7
commit e8bd4c9bc0
No known key found for this signature in database
2 changed files with 101 additions and 0 deletions

View file

@ -0,0 +1,40 @@
package app.passwordstore.gradle.crowdin
import java.util.concurrent.TimeUnit
import okhttp3.OkHttpClient
import okhttp3.Request
import org.gradle.api.DefaultTask
import org.gradle.api.provider.Property
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.Internal
import org.gradle.api.tasks.TaskAction
import org.gradle.work.DisableCachingByDefault
@DisableCachingByDefault(because = "This calls into a remote API and has nothing to cache")
abstract class BuildOnApiTask : DefaultTask() {
@get:Input abstract val crowdinIdentifier: Property<String>
@get:Internal abstract val crowdinLogin: Property<String>
@get:Internal abstract val crowdinKey: Property<String>
@TaskAction
fun doWork() {
val client =
OkHttpClient.Builder()
.connectTimeout(5, TimeUnit.MINUTES)
.writeTimeout(5, TimeUnit.MINUTES)
.readTimeout(5, TimeUnit.MINUTES)
.callTimeout(10, TimeUnit.MINUTES)
.build()
val url =
CROWDIN_BUILD_API_URL.format(crowdinIdentifier.get(), crowdinLogin.get(), crowdinKey.get())
val request = Request.Builder().url(url).get().build()
client.newCall(request).execute().close()
}
private companion object {
private const val CROWDIN_BUILD_API_URL =
"https://api.crowdin.com/api/project/%s/export?login=%s&account-key=%s"
}
}

View file

@ -0,0 +1,61 @@
package app.passwordstore.gradle.crowdin
import java.io.File
import javax.xml.parsers.DocumentBuilderFactory
import org.gradle.api.DefaultTask
import org.gradle.api.GradleException
import org.gradle.api.file.DirectoryProperty
import org.gradle.api.tasks.InputDirectory
import org.gradle.api.tasks.TaskAction
import org.gradle.work.DisableCachingByDefault
import org.w3c.dom.Document
@DisableCachingByDefault(because = "The task runs quickly and has complicated semantics")
abstract class StringCleanupTask : DefaultTask() {
@get:InputDirectory abstract val sourceDirectory: DirectoryProperty
@TaskAction
fun clean() {
val sourceSets = arrayOf("main", "nonFree")
for (sourceSet in sourceSets) {
val fileTreeWalk = sourceDirectory.dir("$sourceSet/res").get().asFile.walkTopDown()
val valuesDirectories =
fileTreeWalk.filter { it.isDirectory }.filter { it.name.startsWith("values") }
val stringFiles = fileTreeWalk.filter { it.name == "strings.xml" }
val sourceFile =
stringFiles.firstOrNull { it.path.endsWith("values/strings.xml") }
?: throw GradleException("No root strings.xml found in '$sourceSet' sourceSet")
val sourceDoc = parseDocument(sourceFile)
val baselineStringCount = countStrings(sourceDoc)
val threshold = 0.80 * baselineStringCount
stringFiles.forEach { file ->
if (file != sourceFile) {
val doc = parseDocument(file)
val stringCount = countStrings(doc)
if (stringCount < threshold) {
file.delete()
}
}
}
valuesDirectories.forEach { dir ->
if (dir.listFiles().isNullOrEmpty()) {
dir.delete()
}
}
}
}
private fun parseDocument(file: File): Document {
val dbFactory = DocumentBuilderFactory.newInstance()
val documentBuilder = dbFactory.newDocumentBuilder()
return documentBuilder.parse(file)
}
private fun countStrings(document: Document): Int {
// Normalization is beneficial for us
// https://stackoverflow.com/questions/13786607/normalization-in-dom-parsing-with-java-how-does-it-work
document.documentElement.normalize()
return document.getElementsByTagName("string").length
}
}