Gradle doFirst not updating WAR file - gradle

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

Related

Gradle processResources expand on different projects modules

i'm trying to get a project.version so i wrote project2 gradle before codes
processResources {
def props = ['version': project.properties.get('version')]
filesMatching("**/MyConfiguration.kt") {
expand(props)
}
}
the MyConfiguration.kt file located project1 but the code return null
so i fixed codes like below
processResources {
def props = ['version': project.properties.get('version')]
expand(props)
}
then that codes return right value
maybe the problem is filesMatching input another module file?
i missed filesMatching input
need to setup .properties or .yaml (get project.properties this scope)

In a custom task in my buildSrc folder: How do I determine the file path of the subproject it is called in?

If I define a custom gradle task in buildSrc: How do I find out the relative path to the project from which the task is called?
In my buildSrc folder, I have a custom task that creates a Enum our of my message.properties file:
open class GenerateEnumTask : DefaultTask() {
#get:Input
open var inputFolder: String = "src/main/resources"
#get:Input
open val targetFilePath: String = "src/generated/kotlin/MessageCode.kt"
#get:OutputFile
val enumFile = File(targetFilePath)
#TaskAction
fun generateEnum() {
...
}
#Internal
override fun getDescription() = "This task uses downloaded property files and creates an enum kotlin file"
}
I then want to make sure the enum is generated before code compilation.
So I put this in the subproject "core", where I need the Enum.
build.gradle.kts:
tasks {
val generateEnumTask by registering(GenerateEnumTask::class)
withType<KotlinCompile> {
kotlinOptions.jvmTarget = Versions.jvmTarget
dependsOn(generateEnumTask)
dependsOn(formatKotlin)
doFirst{
println("compile kotlin in core project")
}
}
}
This does indeed work if I run gradle compileKotlin directly from the subfolder of the core project.
However, if I run the same command from the root project, the code searches for a src folder in the root directory.
Ah, the answer was simple: DefaultTask inherits from AbstractTask, which has a reference to the project that the task was called in (getProject)
This works nicely:
open var targetFolder: String = this.project.file("src/main/resources").absolutePath

How to refer to resources folder in debug mode?

I want to debug my web application in Jetty using gradle. I have some of my property files in source code. Since these files are not copied to WAR, I used the below code to use resources folder,
sourceSets.main.resources {
srcDirs = ["src/main/java"]; include "**/*.*"
}
This includes properties files in WAR. But when I debug in eclipse, it points to classes folder which doesnot contain properties folder. How to make debug to point to resources folder?
Build.gradle:
war {
doFirst {
def propertyFile = file "src/main/java/com/properties/about/About.properties"
def props = new Properties()
propertyFile.withReader { props.load(it) }
println "Before setProperty:"
println props.getProperty('releaseDate')
props.setProperty('releaseDate', new Date().format('yyyy-MM-dd-HH:mm:ss'))
propertyFile.withWriter { props.store(it, null) }
println "After setProperty:"
println props.getProperty('releaseDate')
}
buildDir = new File(rootProject.projectDir, "gradleBuild/" + project.name)
}
I solved this by creating src/main/resources folder and included all files other than class files in it. Say, I created properties\sample.properties and referred this path in code. Now there occurs no issue while debugging and also when deployed as WAR. By having resources folder all the files are included in WAR without having to modify build.gradle

How to copy properties file first and then load them in 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.

Run a groovy class file without main method using gradle task

I have a class file which does not have a main method. I need to run the class file only when needed with the help of a gradle task. Can someone help me with writing a gradle task for it?
I'd guess it'd be something like
buildscript {
// add your library to the buildscript classpath
classpath 'foo.bar:mygroovylib:1.0'
}
task runMyGroovy {
// let's assume your service accepts an input file and writes to an output directory
File inFile = file('path/to/some/file.xml')
File outDir = file("$buildDir/myGroovy")
// set task inputs/outputs to benefit from gradle's up-to-date checks
inputs.file inFile
outputs.dir outDir
doLast {
// actually do stuff in gradle's execution phase
def myObject = new MyGroovyObject();
myObject.doSomethingFantastic(inFile, outDir)
}
}

Resources