2019-11-07 08:58:27 -05:00
|
|
|
import groovy.io.FileType
|
|
|
|
import groovy.transform.stc.ClosureParams
|
|
|
|
import groovy.transform.stc.SimpleType
|
|
|
|
|
|
|
|
ext {
|
|
|
|
autoResConfig = this.&autoResConfig
|
|
|
|
}
|
|
|
|
|
|
|
|
def allStringsResourceFiles(@ClosureParams(value = SimpleType.class, options = ['java.io.File']) Closure c) {
|
2020-01-06 10:52:48 -05:00
|
|
|
file('src/main/res').eachFileRecurse(FileType.FILES) { f ->
|
2019-11-07 08:58:27 -05:00
|
|
|
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)
|
|
|
|
}
|
2021-01-22 10:54:09 -04:00
|
|
|
['en'] + files.collect { f -> f =~ /^values-([a-z]{2,3}(-r[A-Z]{2})?)$/ }
|
2019-11-07 08:58:27 -05:00
|
|
|
.findAll { matcher -> matcher.find() }
|
|
|
|
.collect { matcher -> matcher.group(1) }
|
|
|
|
.sort()
|
|
|
|
}
|
|
|
|
|
|
|
|
task pullTranslations(type: Exec) {
|
|
|
|
group 'Translate'
|
|
|
|
description 'Pull translations, requires transifex client and api key.'
|
2021-05-20 11:10:16 -04:00
|
|
|
commandLine 'tx', 'pull', '-a', '--minimum-perc=80', '--force', '--parallel'
|
2019-11-07 08:58:27 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
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")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
mustRunAfter pullTranslations
|
|
|
|
}
|
|
|
|
|
|
|
|
task cleanApostropheErrors {
|
|
|
|
group 'Translate'
|
|
|
|
description 'Fix transifex apostrophe string errors.'
|
|
|
|
doLast {
|
|
|
|
allStringsResourceFiles { f ->
|
|
|
|
def before = f.text
|
2019-11-10 08:14:40 -05:00
|
|
|
def after = before.replaceAll(/([^\\=08])(')/, '$1\\\\\'')
|
2019-11-07 08:58:27 -05:00
|
|
|
if (before != after) {
|
|
|
|
f.text = after
|
|
|
|
logger.info("$f.parentFile.name/$f.name...updated")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
mustRunAfter replaceEllipsis
|
|
|
|
}
|
|
|
|
|
2019-11-10 08:14:40 -05:00
|
|
|
task excludeNonTranslatables {
|
|
|
|
group 'Translate'
|
|
|
|
description 'Remove strings that are marked "translatable"="false" or are ExtraTranslations.'
|
|
|
|
doLast {
|
2020-01-06 10:52:48 -05:00
|
|
|
def englishFile = file('src/main/res/values/strings.xml')
|
2019-11-10 08:14:40 -05:00
|
|
|
|
|
|
|
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
|
2020-08-05 10:54:44 -03:00
|
|
|
def inMultiline = false
|
|
|
|
def endBlockName = ""
|
2019-11-10 08:14:40 -05:00
|
|
|
|
|
|
|
allStringsResourceFiles { f ->
|
|
|
|
if (f != englishFile) {
|
|
|
|
def newLines = f.readLines()
|
|
|
|
.collect { line ->
|
2020-08-05 10:54:44 -03:00
|
|
|
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} -->"
|
2019-11-10 08:14:40 -05:00
|
|
|
}
|
|
|
|
}
|
2020-08-05 10:54:44 -03:00
|
|
|
|
2019-11-10 08:14:40 -05:00
|
|
|
return line
|
|
|
|
}
|
|
|
|
|
|
|
|
f.write(newLines.join("\n") + "\n")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
mustRunAfter cleanApostropheErrors
|
|
|
|
}
|
|
|
|
|
2020-07-17 11:14:47 -03:00
|
|
|
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'
|
|
|
|
mustRunAfter excludeNonTranslatables
|
|
|
|
}
|
|
|
|
|
2019-11-07 08:58:27 -05:00
|
|
|
task translate {
|
|
|
|
group 'Translate'
|
2019-11-10 08:14:40 -05:00
|
|
|
description 'Pull translations and post-process for ellipsis, apostrophes and non-translatables.'
|
2020-07-17 11:14:47 -03:00
|
|
|
dependsOn pullTranslations, replaceEllipsis, cleanApostropheErrors, excludeNonTranslatables, postTranslateQa
|
2019-11-07 08:58:27 -05:00
|
|
|
}
|