Gradle custom plugin dependencies - gradle

If a have a custom plugin which handles the building and deploying of a specific component, where do I list the dependencies (other components in my system) which are required for the build?

Dependencies for your Gradle plugins should be listed in the buildscript portion of the build.gradle file. See this chapter of the User Guide, which also has an example:
buildscript {
repositories {
jcenter()
}
dependencies {
classpath "com.jfrog.bintray.gradle:gradle-bintray-plugin:0.4.1"
}
}
apply plugin: "com.jfrog.bintray"
If your custom plugin depends on jar files on your local machine, I gather that you need to add those files as a "flatDir" repository in the repositories entry, as described here:
repositories {
flatDir {
dirs 'lib1', 'lib2'
}
}

Related

Configuring Repositories for All Projects in Gradle

I am trying to configure repositories for all subprojects.
I have the main build.gradle:
buildscript {
repositories {
mavenLocal()
mavenCentral()
google()
jcenter()
...
}
dependencies {
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
plugins {
id 'base'
}
allprojects {
apply plugin: 'base'
repositories {
mavenLocal()
mavenCentral()
google()
jcentre()
...
}
wrapper{
gradleVersion = '6.5.1'
distributionType = Wrapper.DistributionType.ALL
}
dependencies {
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
In the subprojects build.gradle I just have:
...
dependencies {
implementation ....
}
I am getting:
Execution failed for task ':compileJava'.
> Could not resolve all files for configuration ':compileClasspath'.
> Cannot resolve external dependency .... because no repositories are defined.
Required by:
project :
I want to define repositories once in the main file as these do not change in subprojects.
In the settings.gradle of the main project I have:
rootProject.name = 'main-project-name'
include 'sub-project-name'
And in the settings.gradle of the sub project I have:
rootProject.name = 'sub-project-name'
A multi-project build in Gradle may have multiple build.gradle files, but only one settings.gradle file (usually in the root project directory). Your second settings.gradle files defines a second setup that only contains a single project. You can check this by running gradle projects. Just delete the second settings.gradle file to solve your problem.
Usually you can simply define the names of your sub-projects by naming the respective directories and then calling include. The name of the rootProject may be defined inside settings.gradle, because the name of the directory is often not stored in version control systems like Git. Developers may check out the repository to different directories causing Gradle to use different names for the root project. If you want a subproject to have a different name than its containing directory, use include with the desired name and then change the project directory via project(':foo').projectDir = file('path/to/foo').
Modern Gradle versions provide a recommended way to declare dependencies in a centralized way.
TLDR: Use the dependencyResolutionManagement DSL in your settings files to configure the repositories in all the subprojects. Both Groovy and Kotlin DSL look the same 👇
dependencyResolutionManagement {
repositories {
mavenCentral()
}
}
Read more in the docs: "Centralizing repositories declaration".

build.gradle buildscript dependencies vs. dependencies?

Can someone explain to me how depedencies listed in the "buildscript" in the build.gradle file are different than regular dependencies listed in the dependencies block { } ? and why they have to be listed with the syntax "implementation"? I've googled this and responses say the dependencies in the buildscript and used to "build the project" but I don't understand this? can anyone give a more clear picture and answer?
buildscript:
buildscript
{
repositories
{
maven {
url 'myMavenFeed'
credentials {
username "myUsername"
password myPassword
}
}
mavenCentral()
jcenter()
}
dependencies
{
classpath "com.microsoft.azure.sdk.iot:iot-device-client:1.14.1"
}
}
Dependencies block:
dependencies
{
compile group: 'com.microsoft.azure.sdk.iot', name: 'iot-device-client', version: '1.16.0'
}
Can someone explain to me how depedencies listed in the "buildscript" in the build.gradle file are different than regular dependencies listed in the dependencies block { } ?
Dependencies defined in the buildscript { } block are dependencies to use to build your project. These dependencies are available to use in your Gradle build file (build.gradle or build.gradle.kts)
Dependencies defined in the dependencies { } are for your application code.
So for your samples in your questions, does it make sense for Gradle (the build system) to have iot-device-client on its classpath? Why does a build system need iot-device-client on its classpath to build your project? It doesn't make sense therefore it should be removed.
Now let's say you are developing an application the requires some functionality or class from iot-device-client. You need a way to add this library to your application's code/classpath. You when then declare it as a dependency as you have done above:
dependencies {
implementation("com.microsoft.azure.sdk.iot:iot-device-client:1.16.0")
}
References:
External dependencies for the build script
Declaring depenedncies
and why they have to be listed with the syntax "implementation"?
implementation is known as a configuration: A Configuration represents a group of artifacts and their dependencies
There are many more configurations depending on the plugins you apply to your project. For example, if you apply the Java plugin:
plugins {
id("java")
}
The following configurations are available to use:
implementation
compileOnly
compileClasspath
...and many more
Each one has their own meaning/usage and I strongly suggest reading about them here.

Using a gradle plugin before loading other plugins in the buildscript

I have my own gradle plugin that contains a file with versions for other plugins. Currently, whenever I make a new project, I have to copy them over as I can't use the versions from the plugin.
Is there anyway to load my plugin, apply it, and then load other plugins afterwards? Currently, I can only do this for the project myself when I make my plugin model named buildSrc, as it automatically adds it to other modules.
Example of what I want to achieve:
buildscript {
repositories {
google()
jcenter()
maven { url 'https://maven.fabric.io/public' }
maven { url "https://plugins.gradle.org/m2/" }
}
dependencies {
classpath "ca.allanwang:kau:$kau_version"
}
// Apply plugin before other dependencies so I can use it
apply plugin: "ca.allanwang.kau"
dependencies {
classpath kauPlugin.android
classpath kauPlugin.kotlin
classpath kauPlugin.androidMaven
classpath kauPlugin.playPublisher
classpath kauPlugin.dexCount
classpath kauPlugin.gitVersion
classpath kauPlugin.spotless
}
wrapper.setDistributionType(Wrapper.DistributionType.ALL)
}
and how it looks like when I have the plugin as a module in my main project:
buildscript {
repositories {
google()
jcenter()
maven { url 'https://maven.fabric.io/public' }
maven { url "https://plugins.gradle.org/m2/" }
}
apply plugin: "ca.allanwang.kau"
dependencies {
classpath kauPlugin.android
classpath kauPlugin.kotlin
classpath kauPlugin.androidMaven
classpath kauPlugin.playPublisher
classpath kauPlugin.dexCount
classpath kauPlugin.gitVersion
classpath kauPlugin.spotless
}
wrapper.setDistributionType(Wrapper.DistributionType.ALL)
}
You should be able to achieve what you want by combining different things:
Define your versions in a Plugin<Settings> that you apply in you settings.gradle(.kts) by leveraging the fact that the Settings object is ExtensionAware
Define your plugin classpath in that same settings file using pluginManagement
Apply plugins in your projects, without specifying a version - see this example for a simpler version that does not define versions through pluginManagement
Example: https://github.com/ljacomet/setttings-plugin-props with the plugin in buildSrc but it could be published and used as a binary plugin without any problem.

How Do We Run a Gradle Dependency Report for Plugins?

Running gradle dependencies lists compile-time dependencies. IOW, it reports direct and transitive dependencies coming from the dependencies closure for the subproject.
What is the equivalent means of determining the transitive dependencies being used by Gradle plugins, the ones specified by the dependencies closure in the buildscript closure?
For example, suppose I have this top-level build.gradle file in an Android project:
buildscript {
repositories {
jcenter()
maven { url 'https://oss.sonatype.org/content/repositories/snapshots/' }
}
dependencies {
classpath 'com.android.tools.build:gradle:2.3.1'
classpath 'com.apollographql.apollo:gradle-plugin:0.3.1-SNAPSHOT'
}
}
allprojects {
repositories {
jcenter()
maven { url 'https://oss.sonatype.org/content/repositories/snapshots/' }
}
}
How do I find out what transitive dependencies are being pulled in by the com.apollographql.apollo:gradle-plugin:0.3.1-SNAPSHOT dependency?
Gradle provides various help tasks. A list of them is available via gradle tasks -all.
To access the buildscript dependencies, one can use the gradle buildEnvironment command, as described in the Gradle docs:
4.7.5. Listing project buildscript dependencies
Running gradle buildEnvironment visualises the buildscript dependencies of the selected project, similarly to how gradle dependencies visualises the dependencies of the software being built.
As addition, CommonsWare stated, that the command must be executed from the project directory.

How to configure Gradle to find local SNAPSHOT resource?

I'm trying to do some work with the springfox project which has been broken up into two separate projects: the springfox runtime, and a suite of demos.
In order to investigate the behavior of certain configurations, I need to change the module in springfox/springfox-petstore, and compile that into springfox-demos/springfox-java-swagger.
In springfox, I built and published a new version of springfox-petstore, and validated that it exists correctly in ~/.m2/repository/io/springfox/springfox-petstore/2.2.2-SNAPSHOT.
Next, in springfox-demos I added mavenLocal() as a repository, and added the springfox-petstore-2.2.2-SNAPSHOT as a changing=true dependency.
When I attempt to build the springfox-demos runtime, I get the following error:
* What went wrong:
A problem occurred configuring project ':spring-java-swagger'.
> Could not resolve all dependencies for configuration ':spring-java-swagger:runtimeCopy'.
> Could not find io.springfox:springfox-petstore:2.2.2-SNAPSHOT.
Searched in the following locations:
https://jcenter.bintray.com/io/springfox/springfox-petstore/2.2.2-SNAPSHOT/maven-metadata.xml
https://jcenter.bintray.com/io/springfox/springfox-petstore/2.2.2-SNAPSHOT/springfox-petstore-2.2.2-SNAPSHOT.pom
https://jcenter.bintray.com/io/springfox/springfox-petstore/2.2.2-SNAPSHOT/springfox-petstore-2.2.2-SNAPSHOT.jar
http://oss.jfrog.org/artifactory/oss-snapshot-local/io/springfox/springfox-petstore/2.2.2-SNAPSHOT/maven-metadata.xml
http://oss.jfrog.org/artifactory/oss-snapshot-local/io/springfox/springfox-petstore/2.2.2-SNAPSHOT/springfox-petstore-2.2.2-SNAPSHOT.pom
http://oss.jfrog.org/artifactory/oss-snapshot-local/io/springfox/springfox-petstore/2.2.2-SNAPSHOT/springfox-petstore-2.2.2-SNAPSHOT.jar
Required by:
springfox-demos:spring-java-swagger:unspecified
I've tried a variety of combinations of build tasks but I can't seem to get Gradle to honor my request for using the local maven repo with a -SNAPSHOT artifact.
Here is the top-level build.gradle:
buildscript {
repositories {
mavenLocal()
jcenter()
}
dependencies {
classpath "com.github.adrianbk:gradle-jvmsrc-plugin:0.6.1"
classpath 'com.ofg:uptodate-gradle-plugin:1.6.0'
}
}
apply from: "$rootDir/gradle/dependencies.gradle"
subprojects {
apply plugin: 'com.github.adrianbk.jvmsrc'
jvmsrc {
packageName "springfoxdemo"
}
apply plugin: 'java'
apply plugin: 'com.ofg.uptodate'
repositories {
jcenter()
maven { url 'http://oss.jfrog.org/artifactory/oss-snapshot-local/' }
}
sourceCompatibility = 1.7
targetCompatibility = 1.7
configurations.all {
//Dont cache snapshots
resolutionStrategy.cacheChangingModulesFor 0, 'seconds'
}
}
wrapper {
gradleVersion = "2.4"
}
So it appears that the top-level build.gradle can have more than one repositories{} block. I had correctly added the mavenLocal() to one, but missed the other. Once adding the mavenLocal() to the second block, all worked well.

Resources