How to copy properties file first and then load them in gradle? - gradle

I am writing a build script where I want to first copy a test.properties file to a directory build/spec/ and load those using Properties.
Here is my code bellow:
Properties props = new Properties()
task resourceCopy(type:Copy){
from resourceDir
into "build"
}
task loadProp(dependsOn:resourceCop){
props.load(new FileInputStream("build/spec/test.properties"))
}
But this is always giving error as:
* What went wrong:
A problem occurred evaluating root project 'ultra-core-rpm'.
build/spec/test.properties (No such file or directory)
Please suggest how to first copy and then load properties file at runtime?

task loadProp(dependsOn:resourceCop){
props.load(new FileInputStream("build/spec/test.properties"))
}
should be
task loadProp(dependsOn:resourceCopy) {
doLast {
props.load(new FileInputStream("build/spec/test.properties"))
}
}
Otherwise, you're not loading the properties when the task is executed, but when the task is configured.

Related

Pass arguments to gradle task from command line

How do I access the value of an argument from the command line in a gradle task? I know that this can be done by -P but I have the same property in my properties file and gradle picks the argument from the properties file rather than the command line. How do I prioritize accepting arguments from the command line over the properties file?
build.gradle
Properties props = new Properties()
props.load(new FileInputStream("./local.properties"))
props.each { prop ->
project.ext.set(prop.key, prop.value)
}
task print {
println("Gets = ${remote}");
}
local.properties
remote=from_properties
Command from cmd
gradle print -Premote=from_commandline
Output
Gets = from_properties
You shouldn't use your own local.properties file if you intend to use a properties file for Gradle properties.
Just use gradle.properties instead.
Also notice that you shouldn't declare task code inside its configuration block, you need to use doFirst or doLast:
gradle.properties
remote = properties
build.gradle
task print {
doLast { println "Gets = ${remote}" }
}
If you run ./gradlew print you will see Gets = properties.
If you run ./gradlew print -Premote=foo you should see Gets = foo.
That said.... if you really want your own properties file, you need to implement the order of priority yourself, Gradle cannot guess what you prefer.
For example, you could check if a property is already set before setting it:
def props = new Properties()
props.load(new FileInputStream("./local.properties"))
props.each { key, value ->
if (!project.hasProperty(key)) {
project.ext.set(key, value)
}
}

Set the properties in the configuration phase of a task in another task

I have spent the last few hours trying to find a solution for my requirement, without luck:
I have a task that has to run some logic in a certain path:
task run(type: MyPlugin) {
pathForPlugin = myPath //Defined as a property in another gradle file
}
I want to set the "pathForPlugin" property dynamically in another task because it has to be read from some configuration file.
task initPaths(type: PathFinder) {
configurationFile = 'C:\\myConfig.conf'
}
The myConfig.conf would look like this:
pathForPlugin = 'C:\\Correct\\Path'
The problem is that "initPaths" has to run before the configuration phase of "run".
I have tried several approaches for this (GradleBuild task, dependsOn, Using Properties in the Plugin for "Lazy Configuration") but every approach only takes effect in the Execution phase leading to the "pathForPlugin" always staying at its default value.
Is there some way i can realize this or should i look for another solution outside of the gradle build?
I found a solution for the problem:
Instead of defining a task "initPaths" i directly used the java class "Pathfinder" in the build script:
import mypackage.PathFinder;
new PathFinder(project).run()
You only have to make sure that this part is above the definition of the task where the properties are used.
I admit this is a bit of a "hacky" solution but it works fine for my requirement.
you can do like this:
ext {
myPath //use it as a global variable that you can set and get from different gradle tasks and files
}
task firstTask {
doLast {
ext.myPath = "your path"
}
}
task run(type: MyPlugin) {
doFirst { //executed on runtime not on task definition
pathForPlugin = ext.myPath //Defined as a property in another gradle file
}
}
//example 2 - create run task dynamic
task initPath {
doLast {
tasks.create(name: "run", type: MyPlugin) {
pathForPlugin = ext.myPath
}
}
}

Gradle doFirst not updating WAR file

In a gradle project, I'm trying to change properties file value before generating WAR in build.gradle as follows,
war {
doFirst {
def propertyFile = file "src/main/resources/properties/about/About.properties"
def props = new Properties()
propertyFile.withReader { props.load(it) }
props.setProperty('releaseDate', new Date().format("yyyy-MM-dd HH:mm:ss"))
propertyFile.withWriter { props.store(it, null) }
}
rootSpec.exclude("**/test.jar")
}
But whenever I give build, it generates WAR with previous date time. Say, I'm giving first build at 11:30 and second build at 11:34. The second built WAR contains time as 11:30 instead of 11:34. My intention is to update date whenever WAR is built. Is this way right?
I simplified your solution and tested it. For me it always updates the date in the properties file when i run build or just war. Be aware that i changed the path for test purposes. Here is the code:
war {
doFirst {
File propsFile = file "src/main/resources/about.properties"
Properties props = new Properties()
props.load(propsFile.newDataInputStream())
props.setProperty('releaseDate', new Date().format('yyyy-MM-dd HH:mm:ss'))
props.store(propsFile.newWriter(), null)
}
}
Keep in mind that the releaseDate of the about.properties is not included into the current war you are currently building since resources for the war you are packing had been processed before you execute war.
If you want to include the about.properties file with the time of the current build into the war archive, you should create a custom task to update your properties file and hook the task to a point into the buildchain before resources are processed. I created a sample task for you:
task updateReleaseDate {
doLast {
File propsFile = file "src/main/resources/about.properties"
Properties props = new Properties()
props.load(propsFile.newDataInputStream())
props.setProperty('releaseDate', new Date().format('yyyy-MM-dd HH:mm:ss'))
props.store(propsFile.newWriter(), null)
}
}
processResources.dependsOn updateReleaseDate
Without the custom task your buildchain looks like this. The properties are updated after the resources are processed by the processResources task and therefore not included in the current war: compileJava->processResources->classes->war
With the custom task your buildchain looks like this. The properties are updated before the resources are processed by the processResources task and therefore included in the current war: compileJava->updateReleaseDate->processResources->classes->war

Gradle copy task, inside filter - gradle.properties file value not working

Inside gradle copy filter task in my build.gradle file, I am trying to read label value from gradle.properties file or from a variable. Please refer below piece of code:
def label = "2.2"
task filterJS(type: Copy) {
from 'src/main/webapp'
into 'build/webapp'
filter(ReplaceTokens, tokens: [vlabel: $label])
}
In HTML file, I have #vlabel#
On running gradle filterJS, getting below exception
What went wrong:
A problem occurred evaluating project ':CargoSystemUX'.
Could not find property $label on task :CargoSystemUX:filterJS.
I am not able to replace $label with its value at run time. Please suggest me the solution for this.
It should be:
import org.apache.tools.ant.filters.ReplaceTokens
def label = "2.2"
task filterJS(type: Copy) {
from 'webapp'
into 'filtered'
filter(ReplaceTokens, tokens: [vlabel: label])
}
Without $ when referring to label and also note the import statement.

How do I define a gradle build script environment variable from a file in my src/main/resources directory?

I'm using Gradle 2.7 on Windows 7. I have a properties file, "src/main/resources/liquibase.properties", whose properties I would like to reference in my build.gradle script. So for instance in my properties file I have
url=jdbc:mysql://localhost:3306/my_db
username=myuser
password=mypass
I would like to reference these in my script like so ...
liquibase {
activities {
main {
changeLogFile 'src/main/resources/db.changelog-1.0.xml'
url '${url}'
username '${username}'
password '${password}'
}
}
}
Also I would like to do this by just runing "gradle build" without having to specify any additional parameters on teh command line. How can I do this?
Thanks, - Dave
You can load the properties file then get the values from that... Here is an example
liquibase {
activities {
main {
File propsFile = new File("${project.rootDir}/src/main/resources/liquibase.properties")
Properties properties = new Properties()
properties.load(new FileInputStream(propsFile))
changeLogFile 'src/main/resources/db.changelog-1.0.xml'
url properties['url']
username properties['username']
password properties['password']
}
}
}

Resources