How to make gradle build script constants available in the built code? - gradle

I am building and running some unit tests from within a gradle build script. The tests need to access some resources located in gradle_project_dir/src/test/resources/fixtures which in gradle.build logic can be expressed as
apply plugin: 'java'
// ...
File fixturesDir = new File(sourceSets.test.resources.srcDirs[0], "fixtures")
What is the best way of pointing the test source to the file as seen in build.gradle?
I want to avoid hard-coding the path in the tests to keep them DRY.
The cleanest solution that currently comes to my mind is to make the gradle build script first build some .jar with BuildConstants class or similar which will contain the fixturesDir file and make the tests source depend on it.
Another option is to make both the build script and the tests depend on some external .jar (possibly built with yet another gradle build script).
Something tells me there should be a simpler way, though.

Related

Setting target directory for gRPC classes generated by Quarkus Gradle plugin

Running ./gradlew quarkusGenerateCode works well, however the generated sources fall under the build directory:
I wouldn't like to set this path as a Gradle SourcesSet, "Mark Directory As" Generated Sources Root in Intellij, and so on as it's under the build directory.
Is there a way to set the output dir to something such as src/quarkus-generated-sources? The Quarkus user guides and the gradle plugin documentation are not too informative regarding that subject.
There's the build.gradle, nothing much special about it
plugins {
id 'io.quarkus'
}
dependencies {
implementation enforcedPlatform("${quarkusPlatformGroupId}:${quarkusPlatformArtifactId}:${quarkusPlatformVersion}")
implementation 'io.quarkus:quarkus-grpc'
...
}
There is no way to specify an alternative path for the built-in code generation mechanism.
The classes generated by Quarkus from your *.proto files may change quite often. If you run Quarkus in the development mode, they will be regenerated on each change (in the *.proto files). In such a set up this is an outcome of the build rather than a source, that's why I put it in build.
I think you could use Gradle protobuf plugin to generate the java files. It has an option to specify the output directory. Don't forget to register quarkus-grpc-protoc-plugin similarly to Maven protobuf plugin configuration.
The drawback of switching to it is that you won't be able to use the full power of the development mode when modifying the *.proto files.

In Maven, how to compile a class outside the source directory into an arbitrary target directory?

I have a legacy app that I'm porting from Ant to Maven. My Maven build works fine for the main project, which I've moved into the standard Maven directory layout (*.java files in /src/main/java/) and it outputs the compiled classes into /target/classes/ as neat as you could wish. These are packaged in a .war file.
However, the project also has a class outside of the folder hierarchy, indeed outside of the web application, that contains scripts that run via cron job. Let's say it's /cronjobs/MyClass.java. I need that class to be compiled and output to /target/cronjobs/MyClass.class and zipped up as part of the resulting .war file, in its /cronjobs/ folder.
Can Maven do this? I know it's possible to change the default "src" directory and "target" directory, but I don't know if (or how) it's possible to run a separate, parallel compile step for just one class.
I can move the source file, of course, if it's easier to compile it with the other classes and then move it later (maybe with the WAR plugin?) but I definitely need the compiled MyClass.class file in the /cronjobs/ directory of the .war.
I'd split the project in 2 parts, webapp as war and cronjobs as jar. Maven knows about multi-module format and it is somewhat the best way to go forward and decouple the webapp from non-webapp code.

Task with name "classes" not found, even tough I can run it

I am trying to create a gradle plugin. I want it to run after all java class-files were created. Therefore, I call task.dependsOn("classes").
During configuration phase, Gradle says Task with path 'classes' not found in root project. even tough I can just run the task via gradlew classes
How can that be? How can I create the dependency I need?
According to documentation:
Classes from buildSrc are no longer visible to settings scripts
Previously, the buildSrc project was built before applying the
project’s settings script and its classes were visible within the
script. Now, buildSrc is built after the settings script and its
classes are not visible to it. The buildSrc classes remain visible to
project build scripts and script plugins.

Gradle clean build - build kicks off prior to clean completing

I have a multi project Gradle build script that runs successfully on Windows 10. It reads and updates a Version.properties file that is located away from project managed directories.
All file manipulations are done using Gradle/groovy. After the Version file has been read, incremented and rewritten it is copied to a build/classes directory where it will be picked up by subsequent jar and shadowjar tasks.
Everything works as advertised if I invoke gradle as follows:
gradle build shadowjar ... etc.
However, if I invoke the clean task prior to build the file is read and incremented properly but the copy of the file fails silently.
The command used is:
gradle clean build shadowjar
My suspicion is that gradle does not wait for the clean task to finish prior to starting the build task. The file gets read and incremented but meanwhile, the multi-project clean activities have not yet finished. I have tried variations on dependencies{} blocks, doFirst{} and doLast{} to try and push the file copy back further in the build process. My main requirement is to have the Version.properties file in place prior to the jar or shadowjar task executing. I'm suspicious of trying to write into gradle's build/ directories in that it might not be possible to put anything into the build directories while gradle is performing its activities. Is there any way to ensure that the Version.properties file (or any generated file) gets copied? Or is there another location that I can use that will not be blown away by gradle at clean time yet still get picked up in the build:jar / build:shadowjar?
You are not supposed to call gradle clean 99.99% of the time, it is redundant due to gradle's incremental build feature. So as long as you correctly define your task inputs and outputs and start from ground up in each task, the problem solves itself.
Anyway in your case the wrong order could be caused by dependency between clean and other tasks, is there any?
I have found a way to write out a generated Version.properties file that will get picked up by the jar and shadowjar tasks. Use the gradle copy task and place the revised Version.properties file into a resources directory. The build activity includes the files found in resources/ in subsequent tasks (jar, shadowjar, test, etc.) My suspicion is that because clean blows away build directories gradle assumes that the activity has fully completed when it starts the build. I think that I've proven that this is not the case. doFirst{}, doLast{} and dependencies{} do not seem to work as modifiers to clean build.

How to utilize buildSrc directory with gradle?

In the gradle documentation says:
Builds which utilize a buildSrc directory will generate a second
profile report for buildSrc in the buildSrc/build directory.
How can we do that (utilize build/Src) via the gradle sript, couldn't you help me?
You may put your helper scripts/classes to various places. One of them is buildSrc directory.
See below quote from gradle documentation.
When you run Gradle, it checks for the existence of a directory called
buildSrc. Gradle then automatically compiles and tests this code and
puts it in the classpath of your build script. You don't need to
provide any further instruction. This can be a good place to add your
custom tasks and plugins.
Your qoute only tells that if you use buildSrc directory, you will have second profile report.

Resources