Gradle: Applying from external gradle file which is downloaded as artifact - gradle

I have a test lrg.gradle file which is supposed to do the following
lrg.gradle
dependencies {
classpath group: '<group path>', name: '<gradle file>', version: "${Version}",
}
apply from <above downloaded gradle file>
I am looking on how to apply from the above downloaded gradle file. Where will the gradle file downloaded and which variable i need to refer to access the cached location. Assuming it is stored in GRADLE_USER_HOME/caches.
Basically we want to have this in all Test LRG files so that all common tasks and dependencies can be applied from common artifact gradle file. So that they can be used like dependent tasks for the tasks defined.

You can apply from a URL like so:
apply from: "http://artifactory.url/maven/repo/$group/$name/$version/common.gradle"
That should allow you to avoid declaring a dependency on the common.gradle file.

Related

How to refer resource files from dependent jar in gradle task?

I want to use resource file from dependent jar to generate code/POJO. Maven has maven-remote-resources-plugin. I didn't find any equivalent gradle plugin. Also not sure if gradle has any default task for the same.
I use this way to use my custom lib with Gradle:
Copy your JAR file to your module ‘libs’ folder. If you don’t have ‘libs’ folder then create one.
Add the library to your ‘module’ Gradle dependencies
dependencies:
dependencies {
compile files('libs/your-library-file-name.jar')
}

when downloading a dependency jar, how to make its dependencies get downloaded

I have built two jars and put them in Artifactory. One of the jars depends on the other (the dependency is in its build.gradle file). When I download the main jar as a dependency of my main app, the dependent jar is not downloaded. The only way I can get both is to put two compile statements in the build.gradle. How do I cause the dependent jar to also get downloaded?
The main jar file is user-cache.jar and it depends on blue-redis.jar. The build.gradle in the app that uses my main jar uses this compile statement:
compile(group: 'etd.user-cache', name: 'user-cache', version: '1.0.2', ext: '12.SNAPSHOT.jar')
The build.gradle for user-cache has this in it:
compile(group: 'etd.blue-redis', name: 'blue-redis', version: '1.0.1', ext: '4.SNAPSHOT.jar')
When I build my app, it only gets user-cache.jar. That makes it necessary to put both compile statements in my app's build.jar
What should I do to cause the blue-redis.jar to also be downloaded without needing its compile statement?
I assume that you are using a maven repository in Artifactory. When gradle is doing dependency resolution it will attempt to download a POM file and check for transitive dependencies as well as parent poms which may list additional dependencies.
To get the desired behavior, when you publish the main jar to Artifactory you need to include in its POM file a dependency on the other JAR.

How can I download and reference a single artifact in Gradle?

I am creating a Gradle task in which I want to download and reference the jar file for an artifact that exists in a Maven repository. Specifically, I plan to call an external script through the Gradle exec task using the location of that jar as an argument to the script. Using the exec task is straightforward; what I am trying to figure out is how to acquire the location of artifact's jar file on the filesystem.
As a simple yet concrete example, assume I have the following files in my Gradle project directory:
build.gradle:
task myScript(type: Exec) {
executable './my_script.sh'
args jarFilePath // How do I get this value?
}
my_script.sh:
#!/usr/bin/env bash
echo "Jar file location: $1"
How can I get the file path to the artifact jar, downloading it from the remote repository if necessary? For instance, it should be downloaded if it's not in my local artifact cache, or it's an updated snapshot version.
Let's assume that the jar file we want is guava-26.0-jre.jar. The following build.gradle file will retrieve the artifact (if necessary) and provide the file location as an argument to the script:
import java.nio.file.Files
import java.nio.file.Path
import java.nio.file.StandardCopyOption
repositories {
mavenCentral()
}
configurations {
myArtifact
}
dependencies {
myArtifact group: 'com.google.guava', name: 'guava',
version: '26.0-jre', transitive: false
}
task myScript(type: Exec) {
Path artifactPath =
temporaryDir.toPath().resolve('guava.jar').toAbsolutePath()
doFirst {
Files.copy(configurations.myArtifact.singleFile.toPath(), artifactPath,
StandardCopyOption.REPLACE_EXISTING)
}
executable './my_script.sh'
args artifactPath.toString()
}
This creates a custom configuration named "myArtifact" with a single dependency on guava-26.0-jre. By marking it as transitive: false none of the artifact's dependencies will be included in the configuration, nor will they be downloaded if they do not yet exist in the local artifact cache.
The call to configurations.myArtifact.singleFile returns a java.io.File reference to the artifact's jar file. This getSingleFile() method also ensures that there is exactly one file in the collection, throwing an IllegalStateException if there are zero or more than one. This guards against referencing the wrong artifact if the configuration gets incorrectly misconfigured in the future to having multiple artifacts (e.g. if somebody removes the "transitive" option from our script).
The toAbsolutePath() method ensures that the path to the script is absolute, and therefore does not need to be resolved relative to any particular directory.
Note that this is copying the artifact to the task's temporary directory in a doFirst block, rather than referencing the file's path directly. This is so that the artifact doesn't need to be resolved when loading the script. Otherwise, the artifact would need to be resolved (and possibly downloaded) even when doing unrelated tasks — including such basic tasks as clean and tasks — causing a build failure if the artifact could not be resolved.
The StandardCopyOption.REPLACE_EXISTING option is used to overwrite any previous jar file from previous builds.
The following snippet with a copy task copyDependencies works for both single and multiple dependencies. You can define any other tasks (e.g. type Exec) that depend on this task.
configurations {
web {
transitive = false
}
}
dependencies {
web "com.foo:foo-messaging:$version:#war",
"com.foo:foo-ng:$version:#war"
}
task copyDependencies(type: Copy) {
from configurations.web
into "$buildDir/web"
}

Where does gradle stores the jars of external plugins?

I am using an external gradle plugin called jsonschema2pojo. For that I added the following code inside build.gradle file and I could successfully use that plugin. But I cannot locate the jar that must be downloaded and stored somewhere.
Where do I find the jar that is downloaded for external plugin?
I looked inside ~/.gradle/caches/ folder. For me the caches folder contains the following subfolders:
2.11, 3.3, jars-1, modules-2, artifacts-24, jars-2.
In this project I am using gradle wrapper (with gradle version 2.11) to build the project. So I looked inside ~/.gradle/caches/2.11 folder which contains the following subdirectories:
plugin-resolution, scripts, workerMain.
I was expecting a jar starts with jsonschema2pojo somewhere here, but could not locate one.
buildscript {
repositories {
mavenLocal()
}
dependencies {
classpath 'org.jsonschema2pojo:jsonschema2pojo-gradle-plugin:0.4.29'
}
}
apply plugin: 'jsonschema2pojo'
You will find the plugin .jar file inside the ~/.gradle/caches/modules-2/files-2.1/ folder.

How can I share build config between two build.gradle.kts files?

I have two projects (in a single git repository) that should have the same
repository {
}
section in their build.gradle.kts, but otherwise are completely unrelated.
Can I factor this common part out and include it in each respective build.gradle.kts? How?
Update In the 0.11.0 release, applyFrom(uri) was removed.
You should now instead use:
apply {
from("dir/myfile.gradle")
}
Old answer
With Groovy build scripts you can do something like apply from: 'dir/myfile.gradle' where dir/myfile.gradle is a file containing your shared repositories block.
In a similar fashion with Gradle Script Kotlin (at least with 0.4.1), you can use the applyFrom(script: Any) method.
build.gradle.kts
applyFrom("dir/myfile.gradle")
If you need to apply it from a subproject you could do something like:
applyFrom("${rootProject.rootDir}/dir/myfile.gradle")
No idea if it works with kotlin however you can try equivalent from plain gradle:
lol.gradle
apply plugin: 'java'
repositories {
mavenCentral()
}
build.gradle
apply from: 'lol.gradle'
Above works fine. Mind that lol.gradle has java plugin applied - it adds context where repositories is present hence can be applied.
We use an init script bundled in a custom gradle distribution to apply our corporate Nexus repository to every gradle project. It's worth considering if you have a lot of projects.
I encountered a similar problem when common config is replicated in each and every project. Solved it by a custom gradle distribution with the common settings defined in init script.
Created a gradle plugin for preparing such custom distributions - custom-gradle-dist. It works perfectly for my projects, e.g. a build.gradle for a library project looks like this (this is a complete file, all repository, plugin, common dependencies etc are defined in the custom init script):
dependencies {
compile 'org.springframework.kafka:spring-kafka'
}

Resources