-
-
Notifications
You must be signed in to change notification settings - Fork 6k
/
translations.gradle
145 lines (132 loc) · 5.68 KB
/
translations.gradle
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
import groovy.io.FileType
import groovy.transform.stc.ClosureParams
import groovy.transform.stc.SimpleType
import org.signal.buildtools.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 {
def staticIpResolver = new StaticIpResolver()
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
}