Gradle Maven like multi module project - gradle

When you define multi module project in Maven, you have one root project and its modules. When you build the root project, Maven transitivelly builds all its modules in correct order. So far pretty similar to Gradle.
But with Maven, you can clone only one submodule from repository and build it locally without need to download the whole project structure. This is because you define dependencies on other modules within the same project just as any other external dependency and it is downloaded and cached from your local repository (Nexus).
With Gradle, you define cross module dependencies as compile project(':other'). So you need to clone whole project structure from repository in order to resolve and build correctly. Is there any way to use Gradle multi module project support, without having to locally clone whole project structure?

I would argue that Maven's multi-module support is a slapped on after-thought. Unlike Gradle, a project dependency is not a first class concept. Instead the maven "reactor" substitutes local artifacts for dependencies when the GAV (group/artifact/version) matches.
If you'd like to use the same approach in Gradle then you can specify your dependencies using the GAV notation and then use the new composite build feature to join two or more separate gradle builds together and substitute repository dependencies for local source dependencies. Note that that you can define the projects included in the composite using groovy so you could easily script this based on custom logic (eg if a subfolder exists in some root folder etc)
Note that composite build support is a new feature added in Gradle 3.1. Prior to Gradle 3.1 you can use Prezi Pride to achieve the same

Related

How to use custom gradle plugin without publishing it to maven/ivy repositories?

I have 2 gradle projects. One is my custom gradle plugin and the other one is project which uses this plugin.
I know I can build my custom plugin, publish it to some repository and use it in my other project but is there any way how can I set something like "dependency" for my plugin (in build.gradle of my other project) and use it without need of building/publishing it somewhere?
To get and idea what I am trying to accomplish, here is some code which hopefully demonstrates the idea:
buildScript {
dependencies {
compile project(":my-gradle-plugin")
}
}
apply "my-gradle-plugin"
You can do that if your plugin project can be moved inside buildSrc of the project that wants to include it. In that case, the plugin will be by default on the classpath of the project.
If that plugin is shared between multiple projects, you will need to produce the binary and then reference it. Note that a local repository can be used, it does not have to be a remote one. One advantage of using a local repository is that Gradle will not cache the resolved plugin and thus any update, even without a version change, will be picked up immediately.

After making a Gradle groovy jar library how to make it re-usable for multiple local projects?

Here I read about how to make a Groovy library .jar ... i.e. pretty much the same as making a Groovy (standalone) project. But I'm not clear what you do then with the resultant .jar...
Say I have two Eclipse "proper"/"standalone" projects (I'm using Groovy for everything) and I want them to share a third Gradle library project of mine as a dependency, which is merely a library of classes... how are my standalone projects expected to find the latest .jar version of the library which they're both using...?
My expectation would be that somehow these versions of the library .jar would have to under GRADLE_USER_HOME (i.e. same location as all other dependency .jars).
Then I would assume that in the build.gradle of both standalone projects you'd have a line like
compile 'mylibrary:mylibrarymodule:3.+'
... of course the first part of these compile directives normally involves a "domain name in reverse" ... and this is normally used by a repository like Maven. How does it work with something which doesn't need to be published?
NB at the time of writing I don't have a Maven account as such and have no idea whether "publication" for re-use of a local common library project like this is essential or not.
Naturally, when I distribute versions of my standalone projects they will need to be packaged up with the library .jar in question.
A link to a how-to for a case like this would be more than welcome: I haven't found it under gradle.org.
If you are developing by yourself, you can use maven-publish plugin to publish your artifacts to local maven repository(you don't have to install maven for this) and on your dependent project you can simply say use mavenLocal repository for dependencies.
If you are on a company, I suggest installing a repository manager and deploy your artifacts to this repository so others can use. You can use their respective plugins to deploy easily. (Gradle Artifactory Plugin, Gradle Nexus Plugin, these are just deployment plugins, you have to setup respository manager to. There are other repository management tools also.) Doing the above process from CI server is the preferred way.
To use latest version of a dependency, you can use Gradle Versions Plugin. If the versioning happen often, using snapshot versions also a possibility.

Gradle: dependency on tag in other repository

Is there a way to specify a tag in another repository as a dependency in Gradle?
I have a project x in repository a that depends on the tag tags/foo-1.2 in repository b. Is it possible to cause Gradle to checkout this dependency as a source dependency?
It's not something that's currently supported out-of-the-box. Depending on your exact needs, you could:
check out the other project (using a third-party SCM plugin or an Exec task), build it separately (using a GradleBuild task), and do something with its outputs (e.g. put them on the former build's compile class path).
use Prezi's Pride tool to dynamically create a multi-project build spanning multiple SCM repositories.
use SVN externals/Git submodules/etc. to create a unified filesystem view that allows to define a multi-project build.

Custom dependency management plugin in Gradle

How do you write a custom gradle plugin to handle dependencies in a custom module descriptor, from a custom repository? The gradle documentation says the following, but I haven't been able to find anything that tells me how.
Even if your project is using a custom dependency management system or
something like an Eclipse .classpath file as master data for
dependency management, it is very easy to write a Gradle plugin to use
this data in Gradle.
I've been maintaining a Custom Ivy resolver for ATG projects (forked from this project), but Gradle recently deprecated this with version 1.8, and I need to port the implementation to a native Gradle plugin.
Implementations of ATG use 'modules' (not unlike Gradle projects), that have a MANIFEST.MF file for a module descriptor. These files define other 'modules' that a module depends on, and also a list of paths (jars or directories) that form the (direct) classpath for the current module.
e.g.
ATG-Class-Path: lib/classes.jar lib/commons-beanutils-1.7.jar
ATG-Required: MyProj.core MyProj.integration.webservices DAF.Endeca.Assembler
Module dependencies are transitive, and may refer to custom modules or modules that sit within the ATG product installation. Hence, I need to define a custom repository that can use the ATG product installation as a source of artifacts.
Without Gradle, I need to maintain dependencies in the form of
ATG's MANIFEST.MF files
Eclipse .classpath files
Dependencies for the Ant build-script
SonarQube configurations
Since I can't get rid of the ATG MANIFEST.MF files, I would like to write a write a custom plugin to allows them to be used in Gradle builds. I can then use Gradle as my build system, which can also generate Eclipse .classpath and .project files, and run Sonar against the project.
Gradle seems to have a lot of source code, and rummaging through it for the last couple of days hasn't got me anywhere.
If someone can point me to a list of interfaces that need to be implemented to (1) implement a custom repository, and (2) implement a custom dependency resolver (to use custom files as module descriptors), that should be enough to get me started.
The Eclipse .classpath use case mentioned above can be solved by parsing that file and translating it to Gradle file dependencies. It isn't currently possible to plug in a custom repository implementation.

Maven build dependency through pom.xml

For my project, I'm using code from another project found on github. I've included the project as a separate folder in my project. My project uses code from that project, so I want to build that project and include it in my project without really making any changes to that project. So how do I specify in my pom.xml to run the sub-projects pom.xml?
If it helps, here is the repository of the other project that I am using: Soda Java
If you're not planning on changing it, simply download it & build it once using Maven. This will install it into your local repository, and you can simply reference it in your pom without any issue.
If you can find it in an external maven repo somewhere, you wouldn't even have to download & build it.
Only if you're planning on changing it do you need the aggregate project approach.
You create an aggregate project with packaging=pom and a modules element that has one module for the dependency and one module for your project, and you build that.

Resources