I want to replace a @VERSION@
token in a java source file with a version before building (Gradle is my build system of choice).
In my current script a
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:
$buildDir/src
by the processSource
task, which mirrors the standard processResources
.sourceSets.main.java.srcDirs
remains the default value and there is no sleight of hand in specifying a location that does not (yet) existfilter
with include/exclude patterns.src
, the directory under $buildDir
where the processed source files are put.inputs.property
.Sync
rather than Copy
so that files deleted from source are deleted from the filtered source as well (thanks, @Earthcomputer).WARNING: As indicated in comments by @Raffaele filtering source code may result in serious problems. This answer assumes that you know well what are you doing and are conscious about potential problems that may occur.
The problem is in the fact that java source files are not copied - they're compiled only - in place. So you need to:
@VERSION@
Not sure about paths but the following piece of code should be helpful:
apply plugin: 'java'
version = '0.0.1'
group = 'randers.notenoughvocab'
archivesBaseName = 'NotEnoughVocab'
def versionFile = 'src/main/java/randers/notenoughvocab/main/Reference.java'
def tempDir = 'build/tmp/sourcesCache'
def versionFileName = 'Reference.java'
compileJava.doFirst {
copy {
from(versionFile)
into(tempDir)
}
ant.replace(file: versionFile, token: '@VERSION@', value: version)
}
compileJava.doLast {
copy {
from(tempDir + '/' + versionFileName)
into(project.file(versionFile).parent)
}
}
To complement other answers, I found this idiom more simple if there's only one value you are looking to change:
task generateSources(type: Copy) {
from 'src/main/java'
into 'build/src/main/java'
filter { line -> line.replaceAll('xxx', 'aaa') }
}
I faced the same problem. And I was unable to find working solution. None of the examples I found worked. I believe it might to a fact, that I am new to Gradle and those examples omit some obvious pieces of code. So I looked into Gradle and found my own solution, that I'd like to share:
import org.apache.tools.ant.filters.ReplaceTokens
// Change compiler source directory
sourceSets {
main {
java {
srcDirs = ['build/src/main/java']
}
}
}
// Prepare sources for compilation
task prepareSources(type: Copy) {
from('src/main/java')
into('build/src/main/java')
filter(ReplaceTokens, tokens: [pluginVersion: version])
}
// Prepare sources, before compile
compileJava {
dependsOn prepareSources
}
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.