Вот простой пример задачи gradle, выполняемой перед preBuild, которая проверяет все строки. xml находит строковые значения с неэкранированными апострофами. Если обнаружены ошибки, не удается построить. Измените зависимость, как необходимо для задачи загрузки.
(обратите внимание, что сценарий завершается неудачно при первой обнаруженной ошибке - поэтому, если в версии en и в версии es есть ошибка, то только один файл сообщается как ошибка.)
(Примечание 2, поскольку используется синтаксический анализатор XML, он обрабатывает только значения, помеченные строками, и, следовательно, также игнорирует любые нарушения в комментариях xml - это очевидно в первом тестовом примере без ошибок.)
(в модуле: app (build.gradle))
task checkUnescapedApostrophes {
doFirst {
println("checkUnescapedApostrophes")
fileTree("src").matching {
include "**/strings.xml"
}.each {
def stringsFile = it
def parser = (new XmlParser()).parse(stringsFile)
println("Processing file: "+stringsFile)
parser.'string'.each { m ->
def s = m.text()
def ss = "[^\\\\]\'"
println "[" + m.@name + "]: " + s
if (s =~ ss) {
throw new GradleException(
"Found a string value in " + stringsFile +
" have unescaped apostrophe: "+s)
}
}
}
println("strings.xml OK")
}
}
preBuild.dependsOn(checkUnescapedApostrophes)
В случае ошибок без строк. xml (языковой стандарт по умолчанию + es):
<resources>
<!-- <string name="test">some value with '</string> -->
<string name="test2">some with escaped \'</string>
</resources>
<resources>
<!-- <string name="test">algún valor con apóstrofe sin escape '</string> -->
<string name="test2">algún valor con el apóstrofe escapado \'</string>
</resources>
Построить вывод:
> Configure project :app
checkUnescapedApostrophes
Processing file: ...\app\src\main\res\values\strings.xml
[test2]: some with escaped \'
Processing file: ....\app\src\main\res\values-es\strings.xml
[test2]: algún error con el apóstrofe escapado \'
strings.xml OK
> Task :app:checkUnescapedApostrophes UP-TO-DATE
> Task :app:preBuild UP-TO-DATE
> Task :app:preDebugBuild UP-TO-DATE
> Task :app:compileDebugAidl NO-SOURCE
> Task :app:compileDebugRenderscript NO-SOURCE
> Task :app:checkDebugManifest UP-TO-DATE
> Task :app:generateDebugBuildConfig UP-TO-DATE
> Task :app:prepareLintJar UP-TO-DATE
> Task :app:prepareLintJarForPublish UP-TO-DATE
> Task :app:generateDebugSources UP-TO-DATE
BUILD SUCCESSFUL in 1s
4 actionable tasks: 4 up-to-date
И в случае ошибки строк. xml (по умолчанию локальный и es)
<resources>
<string name="test">some value with '</string>
<string name="test2">some with escaped \'</string>
</resources>
<resources>
<string name="test">algún valor con apóstrofe sin escape '</string>
<string name="test2">algún valor con el apóstrofe escapado \'</string>
</resources>
(Обратите внимание, что в вышеупомянутых случаях неоткрытый apostraphe помечается в студии красным цветом с ошибкой - как и ожидалось.)
Вывод сборки:
> Configure project :app
checkUnescapedApostrophes
Processing file: ...\app\src\main\res\values\strings.xml
[test]: some value with '
FAILURE: Build failed with an exception.
* Where:
Build file '...\app\build.gradle' line: 43
* What went wrong:
A problem occurred evaluating project ':app'.
> Found a string value in ...\app\src\main\res\values\strings.xml have unescaped apostrophe: some value with '
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.
* Get more help at https://help.gradle.org
BUILD FAILED in 1s
Общее примечание к gradle: при тестировании для себя и изменении build.gradle - обязательно «Перестройте проект», а не просто «Создайте проект», как любой чан Похоже, что ges не обнаруживаются в случае, если сборка ранее не удалась.
Также в качестве альтернативы, о которой вы упомянули, эта задача будет избегать не спасавшихся апострофов путем замены во всех строках. xml найдено , Это обновление на месте - здесь есть более надежный подход: { ссылка }.
task replaceUnescapedApostrophes {
doFirst {
ant.replaceregexp(match: "([^\\\\])'", replace: "\\1\\\\\\\\'", byline: "true") {
fileset(dir: 'src/', excludes: '*', includes: '**/*strings.xml')
}
}
}
//preBuild.dependsOn(checkUnescapedApostrophes)
preBuild.dependsOn(replaceUnescapedApostrophes)