Replace token in file before building, but keep token in sources
You only need to replace @VERSION@
tokens before releasing your software to the public. Here I defined a task compileForRelease
that accomplishes it:
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')
}
I don't recommend messing with standard tasks defined by the Java plugin because that would add unnecessary overhead to each and every build.
I found existing answers somewhat unsatisfying, so here is my solution:
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
}
This addresses various concerns as follows:
- Unlike @Opal's answer, the main source remains unmolested; instead it is staged with modifications to
$buildDir/src
by theprocessSource
task, which mirrors the standardprocessResources
. - Unlike @Gregory Stachowiak's answer,
sourceSets.main.java.srcDirs
remains the default value and there is no sleight of hand in specifying a location that does not (yet) exist - Unlike @Raffaele's answer, there is no separate task set for release vs other builds. I disagree that separating them is desirable; I think the added complexity is not worth it unless you have measured any performance hit and found it to be unacceptable. Before going with @Raffaele's solution I would even for instance prefer to limit the scope of the
filter
with include/exclude patterns. - Task dependencies are implicitly defined via outputs.
- All locations are taken from defaults and nothing is stringly typed. The only magic value here is
src
, the directory under$buildDir
where the processed source files are put. - (Edit: added 2019/1/12) Other answers do not properly handle situations where only the version has changed. Changing the version should, by itself, invalidate the task output. This is accomplished via
inputs.property
. - (Edit 2019/5/20) Uses
Sync
rather thanCopy
so that files deleted from source are deleted from the filtered source as well (thanks, @Earthcomputer).