Source code on github: https://github.com/kendarorg/Gradle101
First, just take the demo002 and copy as demo003
To ease the development i choosed to use a local Maven repository to share the libraries. Again supposing our projects are in the C:\Documents directory, my new repo will be placed in C:\Documents\maven directory
This local repo will be used to overcame the need for the one level max nesting of gradle projects
In the main build.gradle i will add an external variable. This is a variable that will be seen by all build.gradle-s inside the project. This will contain a reference to the our maven directory. Please note that i assume that exists one "container" (kind of pom) project with only direct childrens! No nesting!
ext.repos = [
'LocalMaven' : "file://${projectDir}/../maven"
]
Then i have to tell all the subprojects to use this repository (as a source). I add this at the end of the main build.gradle. This means that all java-type subprojects will first search on the "LocalMaven" and then on the maven central.
All the subprojects will have access to the "repos" variable. The placement inside the main build.gradle is driven by the need to define a common directory for all subprojects. The internal variable will have the form of "repos.LocalMaven": notice the lack of commas!
The definition of the "jar source" repository can be placed in every java-type project, and can have the following form, the declaration order matters a lot! Here first is taken the local maven repository (just declared) and after the maven central repo.
repositories {
maven {
name = 'LocalMaven'
url = uri(repos.LocalMaven)
}
mavenCentral()
}
The idea is to put all the repository informations in one single place to avoid littering the groovy code. We introduce some new constructs.
Inside the main build.gradle now can be added the declaration of the repos.
subprojects {
afterEvaluate { project ->
plugins.withType(JavaPlugin) {
repositories {
maven {
name = 'LocalMaven'
url = uri(repos.LocalMaven)
}
mavenCentral()
...
To demonstrate the previous statement you can add some line and see the differences (i always loved variable scoping...)
subprojects{
println project.name
println project.version
afterEvaluate { project ->
println project.name
println project.version
...
At last i have to tell the projects that publishes artifacts to use the local maven repo. Adding the following to the previously created "subprojects" section.
subprojects {
afterEvaluate { project ->
plugins.withType(JavaPlugin) {
...
}
plugins.withType(MavenPublishPlugin) {
publishing {
publications {
mavenJava(MavenPublication) {
from project.components.java
}
}
repositories {
maven {
name = 'LocalMaven'
url = uri(repos.LocalMaven)
}
...
Remember to close the curly braces!!!!
To publish the services on our local repository it would be enough to add the mavne-publish plugin to the build.gradle, resulting in the following. This because we already handled the publishing behaviour in the root project!
plugins {
id 'java'
id 'java-library'
id 'maven-publish'
}
group 'org.kendar'
version '1.0.0-SNAPSHOT'
Now running "gradle build publish" the new directory C:\Documents\maven have been created containing the poms, md5 and jars for the services!
But this simple "publish" task... will not last long
We can now download a ready copy of Artifactory to simulate a real repo, from Artifactory Portable extract in the same dir previously used for Gradle and Java, then run partifactory.bat.
An UI will then open and the first things to do are
First must be added the variables containing the addresses of the remote repositories
ext.repos = [
...
'RemoteMavenRelease' : "http://localhost:8081/artifactory/libs-release",
'RemoteMavenSnapshot' : "http://localhost:8081/artifactory/libs-snapshot"
]
Now i will add the dependency on the "Remote Repo" to download files and to upload them. Here i have to add the credentials for my local artifactory repository. Of course you can work with any kind of repository following this approach.
subprojects {
afterEvaluate { project ->
plugins.withType(JavaPlugin) {
repositories {
...
maven {
name = 'RemoteMaven'
if (project.version.endsWith('-SNAPSHOT')) {
url = uri(repos.RemoteMavenSnapshot)
} else {
url = uri(repos.RemoteMavenRelease)
}
credentials {
username 'admin'
password '!Passw0rd'
}
}
...
mavenCentral()
}
}
plugins.withType(MavenPublishPlugin) {
publishing {
...
repositories {
...
maven {
name = 'RemoteMaven'
if (project.version.endsWith('-SNAPSHOT')) {
url = uri(repos.RemoteMavenSnapshot)
} else {
url = uri(repos.RemoteMavenRelease)
}
credentials {
username 'admin'
password '!Passw0rd'
}
...
A new task will then appear if we call gradle tasks: publishMavenJavaPublicationToRemoteMavenRepository (pretty long but this will be solved afterwards)
This when called will publish our data on the remote repo choosing the right path for snapshots and releases