On 27 Apr 2014, at 6:37 am, Szczepan Faber <szczepan.fa...@gradleware.com> 
wrote:

> Thanks Adam, that's the input I was looking for. Some more questions / 
> feedback below.
> 
> On Mon, Apr 21, 2014 at 9:39 AM, Adam Murdoch <adam.murd...@gradleware.com> 
> wrote:
> 
> On 20 Apr 2014, at 7:38 am, Szczepan Faber <szczepan.fa...@gradleware.com> 
> wrote:
> 
>> I was asked by the client to perform a quick spike on conflict resolution 
>> rules. I decided spike it first before kicking off a discussion. Here're my 
>> findings.
>> 
>> Intro.
>> 
>> Currently, a version conflict means that there are modules with the same 
>> group+name but different version. However, there is also a different class 
>> of conflicts - different modules (different group or name) are conflicting 
>> and only one of them should be chosen. In the spike, the ResolutionStrategy 
>> a) allows declaring that certain modules are conflicting and b) allows to 
>> choose preferred module version in case of such conflict.
>> 
>> Some specific use cases I found so far:
>> 
>>  1. 'com.google.collections:google-collections' and 'com.google.guava:guava' 
>> are conflicting, prefer guava.
>>  2. 'org.jboss.netty:netty' and 'io.netty:netty*' are conflicting, prefer 
>> io.netty.
>>  3. 'org.springframework:spring' and 'org.springframework:spring-*' are 
>> conflicting, prefer 'org.springframework:spring-*' (for example, 
>> spring-core).
>>  4. 'kafka:kafka_2.8.2' VS 'kafka:kafka_2.10' VS 'kafka:kafka' are 
>> conflicting, prefer _2.10 (say)
>>  5. A team in an organization decided to extract a standalone project out of 
>> a bigger project. The group id of the modules moved to a new project needed 
>> to change. Now there's a risk that consumers will have problems with 
>> conflict resolution.
> 
> You can boil this down to 3 use cases:
> 
> 1. A given component moves to some new coordinates. This would be #1 and #2 
> above.
> 2. A given component is repackaged, by splitting it into a set of smaller 
> components. This would be #3 and #5 above. Groovy 1.x -> 2.x is another 
> example of this.
> 3. A given component is build for multiple versions of some runtime. This 
> would be #4 above, where Scala is the runtime.
> 
> You can generalise #1 and #2 into a ‘replaces’ abstraction:
> 
> - com.google.guava:guava replaces com.google.collections.google-collections
> - io.netty:netty-all replaces org.jboss.netty:netty
> - io.netty:(everything except -all and -parent) replace org.jboss.netty:netty
> - my.org:(a, b) replace my.old.org:ab
> 
> This can also be used to model Maven relocations too.
> 
> Given we know that a replaces b, we can do two things:
> 
> 1. Detect conflicts. Only one of a or b can be present in the result.
> 2. Resolve the conflict. The result should include a and not b.
> 
> I like where this model is going. Not sure if 'replaces' is the right word. 
> At first sight I associate it with 'forcing', e.g. an unconditional 
> replacement. However, I cannot think about anything that is better.

It ‘replaces’ in the sense of ‘supersedes’ or ‘is newer than’ or ‘should be 
used instead of’. Perhaps ‘supersedes’ is a better term.


--
Adam Murdoch
Gradle Co-founder
http://www.gradle.org
VP of Engineering, Gradleware Inc. - Gradle Training, Support, Consulting
http://www.gradleware.com

Join us for Gradle Summit 2014, June 12th and 13th in Santa Clara, CA: 
http://www.gradlesummit.com

Reply via email to