You are viewing a plain text version of this content. The canonical link for it is here.
Posted to ivy-user@ant.apache.org by Luke Renn <lu...@gmail.com> on 2010/02/02 23:26:26 UTC

returnFirst and transitive dependencies

Hello,

First let me say that Ivy is an outstanding project.  Thanks to
everyone who has contributed.

My question is about returnFirst and "enterprise"[1] ivy setups.  We
have a chain resolver set to returnFirst=true.  We've then got local,
integration, nightly, release, and 3rd-party resolvers.  Separating
them into individual repositories was to make cleaning up our old
integration and nightly builds easier.  It also helps manage
permissions on who can publish to what.  At any one time people are
only using 3 repositories: local, 3rd-party, and whatever they choose
(integration, nightly, release).  This is to ensure they never
intermingle.  I know latest.* strategies are normally what would be
used here, see below.  Anyway, here is an example of the issue I'm
having.

--> = depends on
B -> A
C -> B

I'm a developer working on C, and I need to make a change to A and use
it locally in C.  All my other dependencies are coming from the
integration resolver.  If I needed to make a change to B, no problem,
publish it locally and returnFirst would give me my local version
(regardless of revision numbers).  However, if I want to change A, I'd
make the change, publish it locally but I'd still get the integration
version of A, not my local version.  This is because the return first
gets my version of A, resolves B and find that it depends on the
integration version of A and evicts my local copy.  The eviction
occurs because of the way we version our local builds
(LatestVersionMatcher sees 6.1.0-20100201.1 is before
6.1.0-local-20100201.1 and it's right, my fault).

I can think of a few ways to solve this.  And I should mention, it's
working as designed, but that somewhat limits the use of "returnFirst"
no?  A few other things.  Using latest.(integration|release|milestone)
etc won't really fly because we have to maintain previous versions of
the software.  If my revision is latest.integration and I'm fixing
something in 5.1 I don't want it to pick up 6.1 builds.  Then you say
use the branch attribute.  We do, but the latest strategies don't
really provide the flexibility we need so we use dynamic revisons like
6.1.0+.  Branches don't always map to revisions.  Many of these
constraints are out of my hands.  If I could simplify things and use
latest strategies, I would :)

Anyway, to fix this I could do a few things.  I could just publish the
local version as 6.1.0-dev|integration|nightly|release-<build-number>.
 This would work but depends on the fact that d comes before i which
comes before n which comes before r :)  That's kind of cheating.  The
other option would be to write a custom matcher and have the eviction
work off of that.

I'm leaning towards the first option because it's the simplest, but
wonder if there should be a way to "forceFirst" in addition to
returning first.

I can predict people will suggestion using latest.* strategies but I
assure you, since they completely take over revision they aren't as
useful in complex setups.  If I could mix dynamic revisions like
6.1.0+ and latest.revision then it would probably work (again,
branches aren't always revisions so branch= doesn't really solve it).

I'm pretty familiar with the Ivy code base.  I've written some
management software for our repositories and Clojure wrappers to Ivy.
The code is clean and concise, so thanks again for an outstanding job.
 I hope to get some free time in the near future to contribute back.
I'd love to write some documentation on setting up Ivy for closed
organizations.  I've also fixed the CruiseControl plugin but haven't
had time properly package it.

Thanks,

Luke

[1] I hate that word.  I just mean we have a lot of people in one
place working on closed software.