Using a gradle plugin before loading other plugins in the buildscript - gradle

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.

Related

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.

Inheriting gradle plugin in subprojects

I want to avoid redundancy and therefore I got one "shared" project that contains looks like this:
plugins {
id "org.flywaydb.flyway" version "4.2.0"
}
repositories {
mavenCentral()
jcenter()
}
apply plugin: "java"
dependencies {
compile "commons-io:commons-io:2.4"
// ...
}
Then I also have my regular projects that inherit the compile dependencies from my shared project like this:
apply plugin: "java"
repositories {
mavenCentral()
jcenter()
}
dependencies {
compile project(":shared")
testCompile project(":shared")
}
Is there any way I can make my regular projects inherit the plugin block or the actual plugin as well?
Not inherit as such. It seems to me that what you're trying to do can be achieved by configuring the subprojects from the root project. Basically in your root build.gradle (which script that will configure your root project) you can write:
subprojects {
// configuration
}
You can probably get rid of your shared project and have this in root project's build.gradle:
plugins {
id "org.flywaydb.flyway" version "4.2.0" apply false
}
subprojects {
repositories {
mavenCentral()
jcenter()
}
apply plugin: "java"
apply plugin: "org.flywaydb.flyway"
dependencies {
compile "commons-io:commons-io:2.4"
// ...
}
}
This way all your subprojects will be configured using the same closure - this is equivalent to copy-pasting everything in subprojects block to your individual subprojects' build.gradle files. The advantage over your initial solution is ability to also apply plugins, configure extensions, everything you normally can do.
As a side note, you don't need both jcenter() and mavenCentral in repositories block - jCenter is a superset of mavenCentral and is the preferred one

Gradle NoClassDefFoundError in jar dependency

I have developed a custom Gradle plugin and assembled as jar. This plugin has one dependency:
plugin/build.gradle
dependencies {
compile 'com.jcraft:jsch:0.1.53'
}
I have included my plugin in another consumer project (as jar in libs):
consumer/build.gradle
apply plugin: 'gg-release-plugin'
buildscript {
repositories {
flatDir {
dirs 'libs'
}
mavenCentral()
}
dependencies {
classpath 'com.myplugin.plugin:myplugin:1.0'
}
}
Everything works fine, but when code that uses classes of the dependency com.jcraft:jsch:0.1.53 is executed, I get an error:
java.lang.NoClassDefFoundError: com/jcraft/jsch/JSch
What am I doing wrong? How can I include the dependencies in jar file?
Seems, you've created a plugin jar library with compile time depnedency, that is not included anywhere in your final jar.
You can try to create your plugin jar as a fat jar, using Gradle FatJar plugin or something else. In that case, you'll have a single jar with all the dependent classes inside. But this could lead to problems, if someone will use the same library.
Or you can try to provide a JSch library together with your plugin jar and make a consumer build script dependency like:
buildscript {
repositories {
flatDir {
dirs 'libs'
}
mavenCentral()
}
dependencies {
classpath 'com.myplugin.plugin:myplugin:1.0'
classpath 'com.jcraft:jsch:0.1.53'
}
}
As I know, if you use a Maven repo to publish your plugin, you can provide a pom.xml to describe all the plugin's dependencies, but as I see, you are using a flatDir for it, so, it seems not to be possible.

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.

Gradle custom plugin dependencies

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'
}
}

Resources