在构建之前替换文件中的令牌,但在源中保留令牌

2022-09-01 14:21:13

我想在构建之前将java源文件中的令牌替换为版本(Gradle是我选择的构建系统)。@VERSION@

在我当前的脚本中,它替换了实际源文件中出现的实例,因此在构建之后,该模式的所有实例都被版本替换,如果我更改版本,gradle构建文件将不再在那里找到任何模式,版本也不会更新。ant.replace(file: 'src/main/java/randers/notenoughvocab/main/Reference.java', token: '@VERSION@', value: version)@VERSION@

我在这里也看到了一个任务,但我没有得到需要为我的特定项目应用哪些值。

我的项目的项目布局(如果需要):
Screenshot of file layout taken from IntelliJ IDEA 14.1.2, Dark theme


答案 1

您只需要在向公众发布软件之前替换令牌。在这里,我定义了一个完成它的任务:@VERSION@compileForRelease

import org.apache.tools.ant.filters.ReplaceTokens

task sourcesForRelease(type: Copy) {
    from 'src/main/java'
    into 'build/adjustedSrc'
    filter(ReplaceTokens, tokens: [VERSION: '2.3.1'])
}

task compileForRelease(type: JavaCompile, dependsOn: sourcesForRelease) {
    source = sourcesForRelease.destinationDir
    classpath = sourceSets.main.compileClasspath
    destinationDir = file('build/adjustedClasses')
}

我不建议搞砸Java插件定义的标准任务,因为这会给每个构建增加不必要的开销。


答案 2

我发现现有的答案有些不令人满意,所以这是我的解决方案:

import org.apache.tools.ant.filters.ReplaceTokens

task processSource(type: Sync) {
    from sourceSets.main.java
    inputs.property 'version', version
    filter(ReplaceTokens, tokens: [VERSION: version])
    into "$buildDir/src"
}

compileJava {
    source = processSource.outputs
}

这解决了各种问题,如下所示:

  1. 与@Opal的答案不同,主要来源仍然不受干扰;相反,它通过任务的修改进行暂存,这反映了标准。$buildDir/srcprocessSourceprocessResources
  2. 与@Gregory Stachowiak的答案不同,它仍然是默认值,并且在指定(尚未)不存在的位置时没有任何技巧sourceSets.main.java.srcDirs
  3. 与@Raffaele的答案不同,发布与其他构建没有单独的任务集。我不同意把它们分开是可取的;我认为增加的复杂性是不值得的,除非你已经测量了任何性能下降并发现它是不可接受的。例如,在使用@Raffaele的解决方案之前,我甚至更愿意限制包含/排除模式的范围。filter
  4. 任务相关性是通过输出隐式定义的。
  5. 所有位置均取自默认值,并且不以字符串方式键入任何内容。这里唯一的魔术值是,处理过的源文件所在的目录。src$buildDir
  6. (编辑:2019/1/12 添加)其他答案无法正确处理仅更改版本的情况。更改版本本身应该会使任务输出失效。这是通过 完成的。inputs.property
  7. (编辑 2019/5/20)使用而不是从源中删除的文件也从过滤的源中删除(谢谢,@Earthcomputer)。SyncCopy

推荐