Gradle prefer repository on duplicate entries - gradle

I have a build tool thats tied the version to the SCM. I can't set the version of a jar when I build it locally. If someone were to change what I'm working on locally it would push the version number (which I can get), but when I publish to my local repo (Ivy) Gradle seems to prefer the external repo.
build.gradle
repositories {
mavenCentral()
ivy {
url "${System.properties['user.home']}/.ivy2/local/"
layout "pattern", {
artifact "[organization]/[module]/[revision]/[artifact](-[classifier]).[ext]"
ivy "[organization]/[module]/[revision]/ivy.xml"
}
}
ivy {
url "https://repo/"
layout "pattern", {
artifact myPattern
ivy myIvyPattern
}
}
}
Without changing the build for the jar that I'm editing. How can I have gradle always prefer the local repo? I have a feeling that resolutionStrategy might be the best way, but I don't know how accomplish this.
Edit 1
To help clarify, Artifactory has a jar (published by jenkins) with version 1.2.3. I have a jar that I build locally that saves into my local repository as 1.2.3. When I build a project having both repositories in my repository closure (with my local one on top) Gradle seems to pull in the one from Artifactory.
Edit 2
Dependency definition
dependencies {
compile ('company:project:1.2.+')
}

I don't really understand what you are saying, but Gradle searches repositories in their declared order, and picks the first matching module that it finds (as least as long as fixed versions are used).

Related

Gradle repository

Sorry, I'm either stupid, or Gradle repository management is really not there where it should be. I have an Eclipse (Mars) workspace with a mix of Maven and Gradle projects. Naturally, before committing anything on our VCS, I want to test locally. This means I mvn clean install an Artifact in order to have it in my local Maven repository. Obviously, part of the needed Artifact required by Gradle project are also on remote repository.
My Gradle repo are configured like this:
repositories {
mavenLocal()
maven { url "http://myrepo.mycompany.com/nexus/content/groups/public/" }
maven { url
"http://myrepo.mycompany.com/nexus/content/repositories/releases/" }
maven { url
"http://myrepo.mycompany.com/nexus/content/repositories/snapshots/" }
maven { url "http://myrepo.mycompany.com/nexus/content/groups/public-
snapshots/" }
}
Why Gradle goes fetch a resource until the last repo? I mean, I updated an Arifact, installed it locally ... obviously the Artifact which is on a remote repo is not yet the latest version ... why does Gradle go and fetch it?

Can I Publish Multiple Files To Nexus From Gradle In One Go?

I am using a closed source vendor application that occasionally sends me updates of jars in a zip file.
I want to refer to the zip in the Gradle build, unzip it and publish all the jars within it to my Nexus repo. I am assuming that they all have the same GroupId and that the name and version can be inferred from the file name itself.
Whilst testing out my script, I would rather not publish to Nexus and have to delete lots of test artifacts so I am using a flatDir repo for now.
So far I have this
apply plugin: 'maven'
configurations {
zipArchives
}
uploadResultArchives {
repositories {
mavenDeployer {
flatDir(dirs: 'mvn')
pom.groupId = 'com.stackoverflow.example'
}
}
}
artifacts{
zipArchives file: file('unzipdir/api-1.2.34.jar')
}
This suffers from multiple problems.
It requires me to manually add the files to the artifacts list
It creates a pom with dependencies from the rest of my project instead of a pom with no dependencies
I haven't parsed out the versionId yet
This solution looks like the versionId is going to be the same for all
Is there a better way to approach this?

Filter dependency lookup for Repository in Gradle

I have defined 2 Repos in my Gradle build:
repositories {
mavenLocal()
maven { url "http://someurl:8081/nexus/content/repositories/myrepo" }
}
Now I just want to resolve specific artifacts (my project-internal groupId) via mavenLocal, all other dependencies shoud get looked up via the maven repo.
My Idea was to do something like
mavenLocal{
addFilter('group') {artifact, file ->
artifact.group == 'my.group'
}
}
but it's not working. Is there a way to intercept dependency lookup for the local maven repository?
Note: I've seen How to configure gradle to use a local repository only for certain dependency groups? , but the solution provided is not satisfactory for me.
As discussed here: http://forums.gradle.org/gradle/topics/problem_mixing_gradle_and_maven_repositories I need the maven local repo to interchange between maven and gradle builds
EDIT: According to Peter Niederwisers Answer, "There isn't currently a finer-grained way to control this." (Current version: 1.5)
an update to who is out on as of gradle 5.1+: we now have (incubating) Declaring a repository filter
repositories {
mavenLocal{
content {
includeGroup "my.group"
}
}
}
A dependency is searched for in all repositories, in the repositories' declared order. The search stops once the dependency has been successfully resolved. There isn't currently a finer-grained way to control this.
If you absolutely need a workaround, you could try to come up with a solution based on spreading dependency declarations over multiple projects (which can have different repositories).

How to publish in order to resolve latest.integration with gradle?

What I have is a maven repository (nexus) to which maven has been publishing. In each artifact version folder in my artifact repository folder there are the standard maven artifacts: a maven-metadata.xml, a jar, and a pom.xml, etc.
Now I want to resolve these using gradle. In my gradle.build file if I list them as:
dependencies {
compile group: 'com.company', name: 'artifact', version: '1.0-SNAPSHOT'
}
Then they will resolve correctly. However, I want to use the version "latest.integration" so that I can automatically integrate the latest versions of my dependencies. When I do this though, gradle fails to resolve it.
I imagine that gradle is looking for some ivy specific files that maven is not publishing up to the repository in order to resolve latest.integration, but I am not sure. Should I go back and re-publish all of my upstream dependencies with gradle before trying to resolve down stream? It would seem that since gradle supports maven repositories under the repositories element that it should already know how to interpret "latest.integration" for that repository type.
This is my repositories section:
repositories {
mavenCentral()
maven { url "http://<server>/nexus/content/repositories/snapshots" }
}
Thank you for any help you can provide
latest.integration is an Ivy concept, and only works for Ivy repositories. In other words, both publication and consumption would have to happen in an Ivy-compatible manner. (Gradle is capable of this; not sure about Nexus.)
The obvious alternative is to use Maven snapshot dependencies. What do you hope to gain from using latest.integration?

How do I resolve flatDir transient dependencies when publishing to an ivy repository in gradle?

I have a project built by gradle that publishes an artifact to a local ivy repository. Historically, we have used gradle purely with flatDir repositories, as we want to keep everything local. However, I'm starting to see the benefit of using ivy over copying the generated artifacts everywhere.
I can publish the artifact to ivy easily, but other projects that use the repository to pull this artifact in fail on its transient flatDir dependencies.
I'm trying to work out the best way to handle these transient dependencies. It's clear they are needed by anyone using the artifact as they have classes that artifact uses. Should I publish the transient dependencies with my artifact to ivy? What's the best way to do this?
I've tried (what I consider a hack) declaring the jars in the flatLib dir as artifacts themselves with:
group 'utils'
repositories {
flatDir {
dirs 'lib'
name 'librepo'
}
}
dependencies {
compile ":antlr:3.4"
// ...
}
artifacts {
project.repositories.librepo.dirs.each { dir ->
dir.eachFile {
if (it.isFile()) {
archives file(it)
}
}
}
}
However, projects that include the artifact fail because the flatDir files are uploaded to the same group as the main artifact (in this case, 'utils'), but are defined with no group in the dependencies section, and so the entries in ivy.xml have no org value, i.e.
<dependency org="" name="antlr" rev="3.4" conf="compile->default"/>
I think I'm missing something, any help would be appreciated on how to mix flatDir and ivy.
Should I migrate the flatDir dependencies to ivy so they resolve correctly, and I can then change my build to use just the ivy repository it's publishing to as a source as well? I can't really think of a better way, but if I do this, it'll have quite an impact in that every dependency will have to move out of the main project dir's lib dir, to ivy, and I only really want to use the ivy repository to manage our generated artifacts, not third party libraries.
For completeness, I couldn't find a decent solution to this and ended up moving all the lib/ jars to ivy too with the help of this article. Still, this question ended up earning me the tumbleweed award!

Resources