Signal-Android/app/translations.gradle

145 wiersze
5.6 KiB
Groovy

import groovy.io.FileType
import groovy.transform.stc.ClosureParams
import groovy.transform.stc.SimpleType
import org.signal.StaticIpResolver
ext {
autoResConfig = this.&autoResConfig
}
def allStringsResourceFiles(@ClosureParams(value = SimpleType.class, options = ['java.io.File']) Closure c) {
file('src/main/res').eachFileRecurse(FileType.FILES) { f ->
if (f.name == 'strings.xml') {
c(f)
}
}
}
/**
* Discovers supported languages listed as under the res/values- directory.
*/
def autoResConfig() {
def files = []
allStringsResourceFiles { f ->
files.add(f.parentFile.name)
}
['en'] + files.collect { f -> f =~ /^values-([a-z]{2,3}(-r[A-Z]{2})?)$/ }
.findAll { matcher -> matcher.find() }
.collect { matcher -> matcher.group(1) }
.sort()
}
task replaceEllipsis {
group 'Translate'
description 'Process strings for ellipsis characters.'
doLast {
allStringsResourceFiles { f ->
def before = f.text
def after = f.text.replace('...', '…')
if (before != after) {
f.text = after
logger.info("$f.parentFile.name/$f.name...updated")
}
}
}
}
task cleanApostropheErrors {
group 'Translate'
description 'Fix transifex apostrophe string errors.'
doLast {
allStringsResourceFiles { f ->
def before = f.text
def after = before.replaceAll(/([^\\=08])(')/, '$1\\\\\'')
if (before != after) {
f.text = after
logger.info("$f.parentFile.name/$f.name...updated")
}
}
}
}
task excludeNonTranslatables {
group 'Translate'
description 'Remove strings that are marked "translatable"="false" or are ExtraTranslations.'
doLast {
def englishFile = file('src/main/res/values/strings.xml')
def english = new XmlParser().parse(englishFile)
def nonTranslatable = english
.findAll { it['@translatable'] == 'false' }
.collect { it['@name'] }
.toSet()
def all = english.collect { it['@name'] }.toSet()
def translatable = all - nonTranslatable
def inMultiline = false
def endBlockName = ""
allStringsResourceFiles { f ->
if (f != englishFile) {
def newLines = f.readLines()
.collect { line ->
if (!inMultiline) {
def singleLineMatcher = line =~ /name="([^"]*)".*(<\/|\/>)/
if (singleLineMatcher.find()) {
def name = singleLineMatcher.group(1)
if (!line.contains('excludeNonTranslatables') && !translatable.contains(name)) {
return " <!-- Removed by excludeNonTranslatables ${line.trim()} -->"
}
} else {
def multilineStartMatcher = line =~ /<(.*) .?name="([^"]*)".*/
if (multilineStartMatcher.find()) {
endBlockName = multilineStartMatcher.group(1)
def name = multilineStartMatcher.group(2)
if (!line.contains('excludeNonTranslatables') && !translatable.contains(name)) {
inMultiline = true;
return " <!-- Removed by excludeNonTranslatables ${line.trim()}"
}
}
}
} else {
def multilineEndMatcher = line =~ /<\/${endBlockName}/
if (multilineEndMatcher.find()) {
inMultiline = false
return "${line} -->"
}
}
return line
}
f.write(newLines.join("\n") + "\n")
}
}
}
}
task postTranslateQa {
group 'Translate'
description 'Runs QA to check validity of updated strings, and ensure presence of any new languages in internal lists.'
dependsOn ':qa'
}
task postTranslateIpFetch {
group 'Translate'
description 'Fetches static IPs for core hosts and writes them to static-ips.gradle'
doLast {
new File(projectDir, "static-ips.gradle").text = """
ext.service_ips='${StaticIpResolver.resolveToBuildConfig("chat.signal.org")}'
ext.storage_ips='${StaticIpResolver.resolveToBuildConfig("storage.signal.org")}'
ext.cdn_ips='${StaticIpResolver.resolveToBuildConfig("cdn.signal.org")}'
ext.cdn2_ips='${StaticIpResolver.resolveToBuildConfig("cdn2.signal.org")}'
ext.cds_ips='${StaticIpResolver.resolveToBuildConfig("api.directory.signal.org")}'
ext.kbs_ips='${StaticIpResolver.resolveToBuildConfig("api.backup.signal.org")}'
ext.sfu_ips='${StaticIpResolver.resolveToBuildConfig("sfu.voip.signal.org")}'
ext.content_proxy_ips='${StaticIpResolver.resolveToBuildConfig("contentproxy.signal.org")}'
""".stripIndent().trim()
}
}
task translateQa {
group 'Translate'
description 'Post-process for ellipsis, apostrophes and non-translatables.'
dependsOn replaceEllipsis, cleanApostropheErrors, excludeNonTranslatables, postTranslateIpFetch, postTranslateQa
}