how to execute 'gradle build' command from gradle.build script - gradle

I want to execute a gradle build command from build.gradle file.
build.gradle file
apply plugin: 'java'
apply plugin: 'application'
task me{
//Can we perform gradle build command here.
}
Question:
Can we perform gradle build command inside task me, similarly like we do from command prompt(screenshot attached)..?
Note : I am using windows env, please assume I am providing all other statements in build.gradle file.
I am able to build from command prompt by executing
.
I want to execute this task me from command prompt and it should be responsible to call gradle build command.(attached screenshot)

Yes, if you make the task me to a task of type GradleBuild
https://docs.gradle.org/current/dsl/org.gradle.api.tasks.GradleBuild.html
E.g.
task me(type: GradleBuild){
buildFile 'mybuild.gradle' //defaults to build.gradle so not needed
dir 'someDir'
tasks 'clean', 'build'
}

You cannot "call" a Gradle task in a Gradle build.
You might stumble upon the method execute() that each Gradle task has, but this is a purely internal method that must not be used by any build script. Using it will not work properly. It will not ensure the task is run only once, it will not ensure dependency tasks are run before and so on and so on, just don't use it.
Your code snippet is too big for me wanting to interpret it right now to understand what you want to do exactly, but if you want to "call" a Gradle task from another Gradle task, your logic is bogus and should be changed. If you want to run a Gradle task before or after another Gradle task is run, the only supported way is to use dependsOn (before) or finalizedBy (after) and you can not set these properties during execution phase of a task but only during configuration phase.
Well, there is one other way to call a Gradle task from a build script, but this is by using a task of type GradleBuild which would start a complete new and separate build of the project you specify which is most often not the action you really want to do.

Related

Why is task resolution different in command-line vs dependsOn?

I am using the shadowJar plugin in my gradle build. Certain subprojects have a shadowJar task.
If I run gradlew shadowJar from the command line, the shadowJar tasks of all the sub-projects are executed. If on the other hand I have another task that dependsOn shadowJar and I run that, it only runs the shadowJar task on the root project.
What is the reason for this and how can I make my dependency use the same task resolution mechanism as the command line tool?
That is perfectly fine. From command line it's gradle that handles this and resolves the tasks for all projects that are taking part in the current build - were included in included during initialization phase.
Whereas when you use dependsOn it depends on in which: build.gradle you expressed the dependency and also in which block e.g. subprojects or allprojects.

Gradle: Task 'run' not found in root project

I'm trying to use the task 'run' in gradle and it seems that it doesn't exist in my project.
When I type in terminal:
$ gradle run
I get the error message:
FAILURE: Build failed with an exception.
What went wrong: Task 'run' not found in root project 'NA'.
I also built the project again, got "BUILD SUCCESSFUL", and it still didn't help me to commit the 'run' task.
How can I make 'run' task be useful again?
You shouldn't need to manually create a task for run. If it's missing, it means there is something wrong with your build.gradle
In my case, my plugins was missing id 'application' and I didn't have a mainClassName declared at the end of the file. This is what my build.gradle looked like after run became an available task again:
plugins {
id 'java-library'
id 'application'
}
repositories {
jcenter()
}
dependencies {
api 'org.apache.commons:commons-math3:3.6.1'
implementation 'com.google.guava:guava:27.0.1-jre'
testImplementation 'junit:junit:4.12'
}
mainClassName = 'demo.App'
If you don't define a task called run, there is no task called run, so you cannot call a task called run. Either define a task called run that does what you want, or use some plugin that adds a task called run that does what you want. For example the application plugin adds a task called run.
As you said "useful again" you can also track back what you changed from where it was working to where it it not working anymore and then undo it.
check the directory from which you run the build, it should be the same in which the build.gradle file is located

Gradle plugin task ordering

What I have?
Java source file with Main class (MainApp)
gradle build script
apply plugin: 'application'
mainClassName = "MainApp"
sourceSets.main.java.srcDirs = ['.']
So when I do gradle run, it executes main method and everything works just perfectly.
C:\tmp\gradle-fun>gradle run
:compileJava
:processResources UP-TO-DATE
:classes
:run
Hello MainApp !!
BUILD SUCCESSFUL
What I want to do?
Now I was wondering about clean task (common build tasks) to clean the build directory before run task executes.
There is reason behind that, I want to make sure that every time gradle should compile the java files and all .class file should be refreshed (its some requirement)
What I have tried?
Added a wrapper task which executes clean task and run task in order.
apply plugin: 'application'
mainClassName = "MainApp"
sourceSets.main.java.srcDirs = ['.']
task exec(dependsOn: ['clean', 'run'])
So when I run gradle exec, it does it job properly. However I feel that its patch work when you have extra tasks just for ordering execution.
C:\tmp\gradle-fun>gradle run
:clean
:compileJava
:processResources UP-TO-DATE
:classes
:run
Hello MainApp !!
:exec
BUILD SUCCESSFUL
What I would like to know?
Is there any way to avoid writing wrapper task and do some Gradle magic to achieve the requirement?
Just have the run task depend on clean. This will ensure your project is cleaned before every run. If you want to be more specific in regards to your use case, you can simply clean the compileJava task.
run.dependsOn 'cleanCompileJava'
Edit: To avoid deleting your classes before the run add:
classes.mustRunAfter 'cleanCompileJava'
You could create your own task, with clean and run as dependencies:
task cleanRun(dependsOn: [clean, run])
Or, you could follow Mark Vieira's answer and change the wiring:
run.dependsOn 'clean'
classes.mustRunAfter 'clean'
The second line makes sure that it doesn't clean the compiled classes.
Hope this helps =)

Gradle task at the end of build with a multiproject build

I am attempting to create my own task, that will create a package of all the artifacts generated during my multi-project build.
Currently what I do right is now just:
gradle build createPackage
Which gives output like the following:
:test-utility:compileJava UP-TO-DATE
:test-utility:processResources UP-TO-DATE
...
:test-utility:check UP-TO-DATE
:test-utility:build UP-TO-DATE
Creating Package...
Created.
BUILD SUCCESSFUL
Total time: 4.654 secs
With the createPackage task being:
task createPackage {
println "Creating Package..."
println "Created."
}
However, I would like to simply it by running just one command, so what would the best way to do this and ensure the order stays maintained?
Ideally I would like to call build within the createPackage task or append to the build task with my task.
Ok reading between the lines there are a few things to clear up
1) Your printlns are being run in the configuration phase, not the execution phase. See http://www.gradle.org/docs/current/userguide/build_lifecycle.html for more info.
2) You do not have a single 'build' task. gradle build on the command line will run the 'build' task of each of your subprojects. Your package task would need to depend on all of them. Something like..
apply plugin: 'java'
evaluationDependsOnChildren()
task createPackage(type:Zip) {
dependsOn subprojects*.build
}
3) You can be more declarative with gradle - just tell it what you want to package up and it will figure out what it needs to run. For example, you can say that you want to zip up all the jars from your subprojects.
apply plugin: 'java'
evaluationDependsOnChildren()
task createPackage(type:Zip) {
from subprojects*.jar
}
There are plenty of ways. One suggestion is to modify build to depend on createPackage to make sure you can call just gradle build. Then you want to enhance your task and tell what are its inputs (probably those are outputs of some other tasks like jar). Gradle will add these tasks to execution when you run the build and can re-run them based on up-to-date status of each task. This is documented in userguide - http://www.gradle.org/docs/current/userguide/more_about_tasks.html#sec:up_to_date_checks and later in a chapter on custom tasks.

Why is uploadArchives not listed at the tasks list?

i thought uploadArchives is a task which is provided by the java plugin.
In my build.gradle i use the java plugin:
apply plugin: 'java'
But if i invoke gradle tasks on command line, i can't see the uploadArchives task.
Even not with gradle gradle tasks --all
The uploadArchives task is listed in the gradle java plugin documentation
see http://www.gradle.org/java_plugin (table 11).
I use gradle version 1.0-milestone-6.
I can invoke gradle uploadArchives without error, but the task is not listed.
The uploadArchives task is added as a Rule to your build script and not explicitly by name. In the output of "gradle tasks" you should see this line:
Pattern: upload<ConfigurationName>: Assembles and uploads the artifacts belonging to a configuration.
This means, that for each configuration in your build file, an according uploadTask exist. The java plugin adds an configuration named archives to your build script. By adding the configuration "archives" to your build script explicitly by the java plugin, the uploadArchives task is added implicitly too.
There are scenarios, where gradle can't know what tasks need to be materialized by a rule.
E.g.
tasks.addRule("Pattern: ping<ID>") { String taskName ->
if (taskName.startsWith("ping")) {
task(taskName) << {
println "Pinging: " + (taskName - 'ping')
}
}
}
There is no way to figure out which ping tasks should be shown as they are just materialized when triggered from commandline via 'gradle pingServer1 pingServer2 pingServer3'
regards,
René
The uploadArchives task is a part of the maven-plugin. You have to add:
apply plugin: 'maven'

Resources