What parameters can I pass to `gradle dependencies` - gradle

When I run gradle dependencies, I can show the dependency tree of a gradle project. Is there any parameter I can pass?
I know just one --configuration compile from somewhere, but can't find any documentation

gradle dependencies is a DependencyReportTask task. Checking Gradle source code for this task it looks like the configuration is the only option for this task (the only one decorated with the #Option annotation), i.e:
#Option(option = "configuration", description = "The configuration to generate the report for.")
public void setConfiguration(String configurationName) {
this.configurations = Collections.singleton(getProject().getConfigurations().getByName(configurationName));
}

Related

Does Gradle automatically infer dependency between tasks? If so, when?

In my build script, when I configure the downloadAndUnzipFile task, I am explicitly querying output of downloadZipFile task. I expected this is sufficient for Gradle to infer a dependency between the tasks, but it apparently is not, because I get an error when invoking downloadAndUnzipFile`.
Execution failed for task ':downloadAndUnzipFile'.
> Cannot expand ZIP '/home/jdanek/repos/testing/gradle-infer-deps/build/1.0.zip' as it does not exist.
My build script build.gradle.kts is
import de.undercouch.gradle.tasks.download.Download
group = "org.example"
version = "1.0-SNAPSHOT"
plugins {
id("de.undercouch.download").version("4.0.4")
}
tasks {
val downloadZipFile by registering(Download::class) {
src("https://github.com/michel-kraemer/gradle-download-task/archive/1.0.zip")
dest(File(buildDir, "1.0.zip"))
}
val downloadAndUnzipFile by registering(Copy::class) {
from(zipTree(downloadZipFile.get().outputFiles.first()))
into(buildDir)
}
}
I also tried
from(zipTree(downloadZipFile.get().outputFiles.first()))
and that does not define a dependency either.
My Gradle is the latest 6.2.2.
In order for Gradle to discover task dependencies, they have to use specific types for their inputs and outputs so that Gradle can track the dependencies for you. See this documentation page on the topic.
In your use case, the de.undercouch.download plugin seems to expose a simple List<File> which is not a rich type, so Gradle cannot figure out the link. In that case you have be explicit about the task dependency, using dependsOn(downloadZipFile)

dependencies task not found with project.tasks.findByName

When I run gradle tasks it always lists dependencies task; But when I run the following code in my build.gradle it always return null : project.tasks.findByName('dependencies')
My requirement is to print the output of dependencies task into the log for reference as part of build.
I am on gradle version 1.11 (not authorized to upgrade)
Please help:
You may try to use a custom task of org.gradle.api.tasks.diagnostics.DependencyReportTask type, and configured to print just sepecified configuration dependencies, as:
task printDeps(type: org.gradle.api.tasks.diagnostics.DependencyReportTask) {
configurations = project.buildscript.configurations + project.configurations
}
If you wish, you may exclude buildscript dependencies, if you don't need them.

Reading Gradle build parameters

I have a Gradle project with subprojects that I can issue separate build commands if I don't want to build all the subprojects at once. For example,
parent
subprojectA
subprojectB
subprojectC
I can then issue commands like ./gradlew :subprojectA:assemble :subprojectC:assemble. What I like to do is construct a meaning git tag from each subproject group and version values for those subprojects that are being built, i.e., group and version for only subprojectA and subprojectC in this case. I am thinking of writing a standalone plugin to do this but unsure where / how to get this information at build time. Any suggestions would be much appreciated.
Both group and version (as well as any other project property) is available globally in your build script.
task myTask << {
println group + "-" + version
}
If you are writing a binary plugin you can also access properties off the Project object itself via the property() method.
def group = project.property('group')
Edit
If you want to determine if a particular project is being built you can inspect the TaskExecutionGraph.
gradle.taskGraph.whenReady { graph ->
if (graph.hasTask(':subprojectA:assemble')) {
println 'Will build subprojectA'
}
}

Creating a post build copy task with Gradle

I am struggling with the Gradle build lifecycle; specifically with the split between the configuration and execution phases. I have read a number of sections in the Gradle manual and have seen a number of ideas online, but have not found a solution to the following problem:
I want to run a specific task to produce an artifact at the end of my java-library-distribution build that is a flattened version of the runtime configuration jars. That is, I only want to produce the artifact when I run the specific task to create the artifact.
I have created the following task:
task packageSamplerTask(type: Tar, dependsOn: distTar) {
description "Packages the build jars including dependencies as a flattened tar file. Artifact: ${distsDir}/${archivesBaseName}-${version}.tar"
from tarTree("${distsDir}/${archivesBaseName}-${version}.tar").files
classifier = 'dist'
into "${distsDir}/${archivesBaseName}-dist-${version}.tar"
}
Although this task does produce the required artifact, the task runs during gradle's configuration phase. This behavior has the following consequences:
Irrespective of which task I run from the command line, this packageSamplerTask task is always run, often unnecessarily; and
If I clean the project, then the build fails on the next run because $distsDir doesn't exist during the configuration phase (obviously).
It appears that if I extend the Copy task in this manner I'm always going to get this kind of premature behavior.
Is there a way to use the << closure / doLast declarations to get what I want? Or is there something else I'm missing / should be doing?
Update
After further work I have clarified my requirements, and resolved my question as follows (specifically):
"I want to package my code and my code's dependencies as a flat archive of jars that can be deployed as a jMeter plugin. The package can then be installed by unpacking into the jMeter lib/ext directory, as is. The package, therefore, must not include the jMeter jars (and their dependencies) which are used for building and testing"
Because Gradle doesn't appear to support the Maven-like provided dependency management, I created a new configuration for my package which excludes the jMeter jars.
configurations {
jmpackage {
extendsFrom runtime
exclude group: 'org.apache.jmeter', name: 'ApacheJMeter_core', version: '2.11'
exclude group: 'org.apache.jmeter', name: 'ApacheJMeter_java', version: '2.11'
}
}
And then created the following task (using the closure recommendation from Peter Niederwieser):
task packageSamplerTask(type: Tar, dependsOn: assemble) {
from { libsDir }
from { configurations.jmpackage.getAsFileTree() }
classifier = 'dist'
}
This solution appears to work, and it allows me to use just theGradle java plugin, too.
The task declaration is fine, but the flattening needs to be deferred too:
...
from { tarTree("${distsDir}/${archivesBaseName}-${version}.tar").files }
Also, the Tar file should be referred to in a more abstract way. For example:
from { tarTree(distTar.archivePath).files }
First your task isn't executed in the configuration phase but like EVERY task it is configured in that phase. And your closure is just a configuration of your task (a Configuration closure, not an Action closure). That is why your code is "executed" in the configuration phase".
If you want your code to be executed in the execution phase have to write it in a doLastclosure or doFirst. But in your case it is better to keep it in a configuration closure, because you are configuring your task.
To make sure your build doesn't fail because of the missing folder, you can create it with distsDir.mkdirs().

Make The Sonar Runner Gradle Task Depend On One Of My Tasks

I am trying out the new Sonar Runner task recently released in gradle 1.5. What I would like to do is be able to make the sonar runner task dependent on another task so that I can set the Sonar properties correctly for this project (i.e. sonar.sources, sonar.binaries, sonar.libraries, sonar.java.source, sonar.java.target).
Specifically I am using an osgi build tool called bnd which will provide these values when an ant init task is executed (note that whilst I include the default bnd build.xml file, my complete build is really being done using gradle).
I thought I would be able to customize the sonar runner task by doing this (this is a multi-module build):
subprojects {
sonarRunner.dependsOn init
}
Eventually adding something like this (from what I understand of the bnd ant variables):
subprojects {
sonarRunner {
sonarProperties {
property "sonar.java.source", ant.property["project.sourcepath"]
property "sonar.java.target", ant.property["project.output"]
property "sonar.sources", ant.property["project.allsourcepath"]
property "sonar.libraries", ant.property["project.buildpath"]
}
}
sonarRunner.dependsOn init
}
Unfortunately when I try to add the dependsOn I get the error:
* What went wrong:
A problem occurred evaluating root project 'myproject'.
> Could not find property 'init' on project ':com.company.myproject.mymodule'.
If I try to make sonarRunner depend on a gradle task I get the following error:
* What went wrong:
A problem occurred evaluating root project 'myproject'.
> Could not find method dependsOn() for arguments [task ':gradletask'] on org.gradle.api.sonar.runner.SonarRunnerExtension_Decorated#c4d7c0c.
Am I missing something obvious here? If someone could point me in the right direction it would be a big help.
Your problem with not being able to call dependsOn() on sonarRunner task comes from the fact that the plugin defines both both sonarRunner extension and a sonarRunner task. It looks like extensions take precedence over tasks when objects are resolved by name in a gradle build file, hence your stacktrace points out that you are trying to call dependsOn() on an instance of org.gradle.api.sonar.runner.SonarRunnerExtension_Decorated instead of caling it on a SonarRunner task instance.
I think that if you retrieved the task from the task container explicitly you should be ok:
tasks.sonarRunner.dependsOn init
The root project gradle file is evaluated before the child project gradle files, that means init does not exist on the location you try to address it.
A workaround if you want to declare dependencies in the root project is to use afterEvaluate as described in http://www.gradle.org/docs/current/userguide/build_lifecycle.html, try:
subprojects {
afterEvaluate{
sonarRunner.dependsOn init
}
}
Another solution would be to add the dependency in the sub projects, directly or by applying another root gradle file.
apply from: '../sonardependency.gradle'
If anyone is interested, this is one way of getting the bnd information to be set correctly in Sonar for each subproject (I am sure there are better ways):
subprojects {
afterEvaluate {
sonarRunner {
sonarProperties {
ant.taskdef(resource:"aQute/bnd/ant/taskdef.properties",
classpath: "../cnf/plugins/biz.aQute.bnd/biz.aQute.bnd-2.0.0.jar");
def projectDir = project.rootDir.toString() + "/" + project.name;
ant.bndprepare(basedir:projectDir,print:"false",top:null);
def binaries = ant.properties['project.buildpath'].split(':') as ArrayList;
binaries.remove(0);
def binariesString = binaries.join(',');
properties["sonar.java.source"] = ant.properties['javac.source'];
properties["sonar.java.target"] = ant.properties['javac.target'];
properties["sonar.binaries"] = ant.properties['project.output'].replace(':',',');
properties["sonar.sources"] = ant.properties['project.sourcepath'].replace(':',',');
properties["sonar.libraries"] = binariesString;
}
}
}
}

Resources