How do I make an alias for a Gradle task? - java

As a part of a TDD workflow, I want to be able to check if my Java codebase compiles, but not if the tests pass.
Currently, if I run gradle build it runs the compile tasks (for source and tests) and then also executes the test task (and returns a non-zero exit code since the tests fail).
So I find that I have to run gradle build -x test to exclude the test task, and get a successful zero exit code.
What do I add to my build.gradle to define a new task, say compile that is an alias for build x test?
So far I have this, but it doesn't seem like dependsOn takes any arguments to customize the build task I want to execute:
task compile {
dependsOn build
}
I've been reading the docs here, I see different kinds of dependency chaining mechanisms, but not to disable/exclude a particular task. How does the -x flag even work then? I assumed there would be a way to control it programmatically too.
Thanks to Bjørn Vester's answer and reading the docs, I have implemented my task as follows:
task compile {
dependsOn classes
dependsOn testClasses
}

There are lots of different tasks you can run individually. For instance:
gradle classes: Will compile your "main" code.
gradle testClasses: Will compile your "main" code as well as test code.
gradle jar: Will compile your "main" code and assemble it into a jar.
None of the above will run your unit tests. On the other hand, the build task depends on all of the above, as well as the test task and more.
In general, if you like to run a particular set of tasks, you do that by defining a new task and then make dependencies to those other tasks you like to run with it. You tried that already, but instead of build you should have used something like compileJava or classes whatever other tasks you need. But always check if there isn't one already that satisfies your needs, like there are in this case. You can read about what tasks are available in Java projects in the documentation for the Gradle java plugin.

Related

How to call a Gradle task in all subprojects?

Say, I have a hierarchy of Gradle projects and some of them have java plugin applied:
root
projA
projA1
projA2 (java)
projB
projB1 (java)
projB2
projB21 (java)
projB22 (java)
projC (java)
I want to execute the test task in all subprojects where this task exists: :projA:projA2:test, :projB:projB1:test and :projC:test. Probably I will add more projects in future and I don't want to manually support a list of all test tasks in all subprojects. How can I achieve it?
One thing that came to my mind is something like the following:
// In root I iterate over all subprojects and find the task by name causing
// its creation and configuration
tasks.register("testAll") {
dependsOn subprojects.findResults { it.tasks.findByName("test") }
}
I don't like this approach as it goes against task configuration avoidance style.
Another option is to iterate over subprojects and check if the java plugin is applied there:
// In root
tasks.register("testAll") {
dependsOn subprojects.findAll { it.plugins.hasPlugin("java") }.collect { it.tasks.named("test") }
}
It works but I have a filling that I miss something simpler...
EDIT 1: Sorry for that but I forgot one important detail - I need to run tests in a subtree of projects. Say, everything down the path :projB.
Unless I'm missing something, you want to run tests for all of your submodules.
You can just...do that.
./gradlew clean test
This will run the test task in all of the subprojects that have it sufficiently configured.
If you need to run the tasks in a specific subproject, from the root project you can specify the subproject you want to run the task.
./gradlew clean :projB:test
If your subprojects have a task that needs to run after test, then you can do this in your subprojects block.
subprojects {
myTask.dependsOn("test")
}

Adding custom command to gradle script

I'm using the shadowJar plugin for Gradle (4.2.1) to build the so-called fatJar or uberJar. This works as expected but I would like to to add some actions after the building is done. More precisely, I'd like to make the resulting file executable (in Unix terms, i.e. chmod +x) and then copy it to a certain directory. I've googled a lot and I know that both task are possible. I'd like to know whether I should write a script (task) that runs shadowJar and then does what I want, or I should change the shadowJar itself to embed the operations I need.
I think a good criteria to decide about such situation is to ask yourself if the new features are really part of the responsibility of the shoadowJar. If the answer is no, then it would be better to (as you mentioned) have another task that runs on top of that. By doing so you can reuse the shadowJar in much more different scenarios by combining it to other tasks. If you define the new one to be dependent on the shadowJar, then you would be sure that you can still call shadowJar task individually while calling the new task would always trigger the shadowJar. Your new task would be something like this:
task afterShadowJar (dependesOn: 'shadowJar') {
// manipulate file permissions, etc.
}

File dependency Gradle

I am a gmake user transitioning to Gradle. I have a multi-project structure, where one sub-project is a Java project and the other a home-brewed language. The home-brewed language does not use any Gradle plugins. Now I want to add a task that runs a Java program to generate XML when any of my home-brewed source files have been modified. In make, I would just declare a dependency on inputFile.mine or *.mine next to the target name, but I could not easily find how to do this basic thing with Gradle. Currently, I force the task to always execute using the potentially ugly work-around below. I want to replace this with some dependsOn *.mine . The Gradle user guide has a whole chapter dedicated to explaining different ways of specifying files, but I did not see how to declare a dependency.
task generateXML(type: Exec) {
generateXML.getOutputs().upToDateWhen({false}) // Force it to execute always
executable("java.exe")
args("-jar", "resources/generateXml.jar", "src/inputFile.mine")
}
Thanks for helping a newbie out.
You can define task inputs and outputs in Gradle.
For example:
task generateXML(type: Exec) {
inputs.file ("src/inputFile.mine")
executable("java.exe")
args("-jar", "resources/generateXml.jar", "src/inputFile.mine")
}
See https://docs.gradle.org/current/userguide/more_about_tasks.html and https://docs.gradle.org/current/javadoc/org/gradle/api/tasks/TaskInputs.html for more information.
Side note: When you run your build with -i, Gradle will tell you what has happened during the up-to-date check.

How to depend on all *compile and *testCompile tasks in Gradle

I would like to have in animalSniffer plugin one task to depend on compilation of all production classes (Java, Groovy, Scala) in all sourceSets and the second to depend on compilation of all test classes in all sourceSets (possibly separate test and integrationTest).
I wouldn't like to depend on *classes tasks as *classes tasks should depend animalSniffer tasks (which detects Java version API incompatibilities after the compilation and can stop the build).
Is there a better way in Gradle to achieve that than checking if an instance of AbstractCompile task name starts with "compileTest"?
You can use tasks.withType(AbstractCompile) which returns all compile tasks for all source sets (which includes Java, Groovy, Scala). You can then filter on this by eliminating all tasks that have test in them as suggested in the other answer.
For a specific task to depend on all these, you can do the following:
myTask.dependsOn tasks.withType(AbstractCompile).matching {
!it.name.toLowerCase().contains("test")
}
If you need to differentiate between production and test compile tasks/source sets, checking whether the name contains test (case-insensitive) is the best solution that's available.

Gradle build without tests

I want to execute gradle build without executing the unit tests. I tried:
$ gradle -Dskip.tests build
That doesn't seem to do anything. Is there some other command I could use?
You should use the -x command line argument which excludes any task.
Try:
gradle build -x test
Update:
The link in Peter's comment changed. Here is the diagram from the Gradle user's guide
Try:
gradle assemble
To list all available tasks for your project, try:
gradle tasks
UPDATE:
This may not seem the most correct answer at first, but read carefully gradle tasks output or docs.
Build tasks
-----------
assemble - Assembles the outputs of this project.
build - Assembles and tests this project.
You can add the following lines to build.gradle, **/* excludes all the tests.
test {
exclude '**/*'
}
The accepted answer is the correct one.
OTOH, the way I previously solved this was to add the following to all projects:
test.onlyIf { ! Boolean.getBoolean('skip.tests') }
Run the build with -Dskip.tests=true and all test tasks will be skipped.
Every action in gradle is a task, and so is test. And to exclude a task from gradle run, you can use the option --exclude-task or it's shorthand -x followed by the task name which needs to be excluded. Example:
gradle build -x test
The -x option should be repeated for all the tasks that needs to be excluded.
If you have different tasks for different type of tests in your build.gradle file, then you need to skip all those tasks that executes test. Say you have a task test which executes unit-tests and a task testFunctional which executes functional-tests. In this case, you can exclude all tests like below:
gradle build -x test -x testFunctional
Using -x test skip test execution but this also exclude test code compilation.
gradle build -x test
In our case, we have a CI/CD process where one goal is compilation and next goal is testing (Build -> Test).
So, for our first Build goal we wanted to ensure that the whole project compiles well. For this we have used:
./gradlew build testClasses -x test
On the next goal we simply execute tests:
./gradlew test
You can exclude tasks
gradle build --exclude-task test
https://docs.gradle.org/current/userguide/command_line_interface.html#sec:command_line_executing_tasks
the different way to disable test tasks in the project is:
tasks.withType(Test) {enabled = false}
this behavior needed sometimes if you want to disable tests in one of a project(or the group of projects).
This way working for the all kind of test task, not just a java 'tests'. Also, this way is safe. Here's what I mean
let's say: you have a set of projects in different languages:
if we try to add this kind of record in main build.gradle:
subprojects{
.......
tests.enabled=false
.......
}
we will fail in a project when if we have no task called tests
Reference
To exclude any task from gradle use -x command-line option. See the below example
task compile << {
println 'task compile'
}
task compileTest(dependsOn: compile) << {
println 'compile test'
}
task runningTest(dependsOn: compileTest) << {
println 'running test'
}
task dist(dependsOn:[runningTest, compileTest, compile]) << {
println 'running distribution job'
}
Output of: gradle -q dist -x runningTest
task compile
compile test
running distribution job
Hope this would give you the basic
In The Java Plugin:
$ gradle tasks
Build tasks
-----------
assemble - Assembles the outputs of this project.
build - Assembles and tests this project.
testClasses - Assembles test classes.
Verification tasks
------------------
test - Runs the unit tests.
Gradle build without test you have two options:
$ gradle assemble
$ gradle build -x test
but if you want compile test:
$ gradle assemble testClasses
$ gradle testClasses
Please try this:
gradlew -DskipTests=true build

Categories

Resources