Gradle 任务替换 .java 文件中的字符串
Gradle task replace string in .java file
我想在编译代码之前替换 Config.java 文件中的几行。我所能找到的只是在复制过程中通过过滤器解析文件。一旦我必须复制它,我就必须将它保存在某个地方——这就是我寻求解决方案的原因:在替换行时复制到临时位置 > 删除原始文件 > 将复制的文件复制回原始位置 > 删除临时文件。有更好的解决方案吗?
也许你应该尝试像 ant 那样的东西 replaceregexp:
task myCopy << {
ant.replaceregexp(match:'aaa', replace:'bbb', flags:'g', byline:true) {
fileset(dir: 'src/main/java/android/app/cfg', includes: 'TestingConfigCopy.java')
}
}
此任务会将出现的所有 aaa
替换为 bbb
。无论如何,这只是一个例子,你可以根据你的目的修改它或者用ant尝试一些类似的解决方案。
- 我绝对不会覆盖原文件
- 我喜欢基于目录而不是基于文件名,所以如果是我,我会把 Config.java 放在它自己的文件夹中(例如
src/replaceme/java
)
- 我会在
$buildDir
下创建一个 generated-src
目录,以便通过 clean
任务将其删除。
您可以使用复制任务和 ReplaceTokens 过滤器。例如:
apply plugin: 'java'
task generateSources(type: Copy) {
from 'src/replaceme/java'
into "$buildDir/generated-src"
filter(ReplaceTokens, tokens: [
'xxx': 'aaa',
'yyy': 'bbb'
])
}
// the following lines are important to wire the task in with the compileJava task
compileJava.source "$buildDir/generated-src"
compileJava.dependsOn generateSources
为了补充 lance-java
的回答,我发现如果您只想更改一个值,这个习惯用法会更简单:
task generateSources(type: Copy) {
from 'src/replaceme/java'
into "$buildDir/generated-src"
filter { line -> line.replaceAll('xxx', 'aaa') }
}
警告:请记住,如果源文件发生更改,Copy
任务只会 运行。如果您希望根据其他条件进行替换,则需要使用 Gradle 的增量构建功能来指定。
如果您确实希望覆盖原始文件,使用临时文件策略,以下将创建过滤后的文件,将它们复制到原始文件上,然后删除临时文件。
task copyAtoB(dependsOn: [existingTask]) {
doLast {
copy {
from("folder/a") {
include "*.java"
}
// Have to use a new path for modified files
into("folder/b")
filter {
String line ->
line.replaceAll("changeme", "to this")
}
}
}
}
task overwriteFilesInAfromB(dependsOn: [copyAtoB]) {
doLast {
copy {
from("folder/b") {
include "*.java"
}
into("folder/a")
}
}
}
// Finally, delete the files in folder B
task deleteB(type: Delete, dependsOn: overwriteFilesInAfromB) {
delete("folder/b")
}
nextTask.dependsOn(deleteB)
我想在编译代码之前替换 Config.java 文件中的几行。我所能找到的只是在复制过程中通过过滤器解析文件。一旦我必须复制它,我就必须将它保存在某个地方——这就是我寻求解决方案的原因:在替换行时复制到临时位置 > 删除原始文件 > 将复制的文件复制回原始位置 > 删除临时文件。有更好的解决方案吗?
也许你应该尝试像 ant 那样的东西 replaceregexp:
task myCopy << {
ant.replaceregexp(match:'aaa', replace:'bbb', flags:'g', byline:true) {
fileset(dir: 'src/main/java/android/app/cfg', includes: 'TestingConfigCopy.java')
}
}
此任务会将出现的所有 aaa
替换为 bbb
。无论如何,这只是一个例子,你可以根据你的目的修改它或者用ant尝试一些类似的解决方案。
- 我绝对不会覆盖原文件
- 我喜欢基于目录而不是基于文件名,所以如果是我,我会把 Config.java 放在它自己的文件夹中(例如
src/replaceme/java
) - 我会在
$buildDir
下创建一个generated-src
目录,以便通过clean
任务将其删除。
您可以使用复制任务和 ReplaceTokens 过滤器。例如:
apply plugin: 'java'
task generateSources(type: Copy) {
from 'src/replaceme/java'
into "$buildDir/generated-src"
filter(ReplaceTokens, tokens: [
'xxx': 'aaa',
'yyy': 'bbb'
])
}
// the following lines are important to wire the task in with the compileJava task
compileJava.source "$buildDir/generated-src"
compileJava.dependsOn generateSources
为了补充 lance-java
的回答,我发现如果您只想更改一个值,这个习惯用法会更简单:
task generateSources(type: Copy) {
from 'src/replaceme/java'
into "$buildDir/generated-src"
filter { line -> line.replaceAll('xxx', 'aaa') }
}
警告:请记住,如果源文件发生更改,Copy
任务只会 运行。如果您希望根据其他条件进行替换,则需要使用 Gradle 的增量构建功能来指定。
如果您确实希望覆盖原始文件,使用临时文件策略,以下将创建过滤后的文件,将它们复制到原始文件上,然后删除临时文件。
task copyAtoB(dependsOn: [existingTask]) {
doLast {
copy {
from("folder/a") {
include "*.java"
}
// Have to use a new path for modified files
into("folder/b")
filter {
String line ->
line.replaceAll("changeme", "to this")
}
}
}
}
task overwriteFilesInAfromB(dependsOn: [copyAtoB]) {
doLast {
copy {
from("folder/b") {
include "*.java"
}
into("folder/a")
}
}
}
// Finally, delete the files in folder B
task deleteB(type: Delete, dependsOn: overwriteFilesInAfromB) {
delete("folder/b")
}
nextTask.dependsOn(deleteB)