Thanks Szczepan!

I've finally found the time to get fully across this feature. I haven't yet
looked into the implementation.

Here's some initial feedback on the model.

1. We've named this feature 'component replacements', but the modelling is
done at the "module" level (ComponentModuleMetadata).  I don't think this
is ideal: I'd like to think about a 'replacement' being modelled at the
component level ("org:name:version" instead of "org:name"). In most cases
we'll consider all components with the same 'org:name as having the same
replacements, and the DSL would make it convenient to define this. But the
underlying model should associate 'replacements' with a component, I think.
2. Eventually, we'd like a published component to contain replacement
information. For this to be convenient, we'd normally publish a component
and say it 'replaces' or 'supercedes' a set of other components. I think it
might be helpful to model the relationship in this way, using 'replaces'
rather than 'replaced by'.

And on the DSL:
The DSLs for all of our 'rules' that apply to dependency resolution are
converging on a pattern that will hopefully allow them to be migrated into
the new configuration rule infrastructure at some stage. The pattern is:

model-rule-type {
    eachXXX { SomeMutableType mutable[, OtherType immutableInput]* ->
    }
    module("group:name") { SomeMutableType mutable[, OtherType
immutableInput]* ->
    }
}

Exceptions:
- For component selection rules, 'all' is used instead of
'eachComponentSelection'.
     - I'm thinking this works better as a partner method to 'module()'
- For component metadata rules, the module() method doesn't exist yet.
- For dependency resolve rules, the 'model-rule-type' containing element
doesn't exist.

If we stick with the same pattern for component replacements, we'd have:

dependencies {
    components {
        module("com.google.guava:guava") { ComponentSubstitutionDetails
component ->

  component.replacesModule("com.google.collections:google-collections")
        }
    }
}

That's it for now. Thanks for restarting the discussion!
Daz

On Wed, Sep 24, 2014 at 3:31 AM, Szczepan Faber <szcze...@gmail.com> wrote:

> Upcoming Gradle 2.2 contains new incubating component replacement rules:
>
> dependencies {
>     components {
>
> module("com.google.collections:google-collections").replacedBy("com.google.guava:guava")
>     }
> }
>
> See more in http://www.gradle.org/docs/nightly/release-notes. This
> declaration is used during conflict resolution, Gradle will prevent
> both collections and guava appear in the same dependency tree,
> preferring any version of guava over every version of collections.
> Most importantly, if the dependency tree _only_ contains collections
> it will _not_ be replaced (because there is no conflict). Multiple
> modules can have the same target replacement. However, we don't
> support (yet) having single module replaced by multiple modules.
>
> The full DSL in the current form, based on our previous discussion on
> the mailing list. I'm starting new email thread on purpose (for good
> or bad, let's see whether it helps).
>
> dependencies {
>     components {
>     //declaring replacement:
>
> module("com.google.collections:google-collections").replacedBy("com.google.guava:guava")
>         module(someModuleIdentifier).replacedBy("com.google.guava:guava")
>
>         //querying for the replacement target:
>         ModuleIdentifier id =
> module("com.google.collections:google-collections").getReplacedBy()
>
>         //querying for the replacement source:
>         ModuleIdentifier id =
> module("com.google.collections:google-collections").getId()
>     }
> }
>
> Javadoc (for interface names, etc.):
>
> http://www.gradle.org/docs/nightly/javadoc/org/gradle/api/artifacts/dsl/ComponentMetadataHandler.html#module(java.lang.Object)
>
> This DSL can grow to accommodate features like:
> a) replacing single module with a set of modules. I'd love to have
> this. I also want to make incremental progress.
> b) other component module metadata (e.g. releasable units, impl module
> consistent with api module). I'd love to have this, too.
>
> Let's confirm this API and/or make changes to it before 2.2 release.
> Other related APIs that we should have in mind (for consistency):
>
> 1. component selection rules:
>
> configurations.conf.resolutionStrategy {
>     componentSelection {
>         all { ComponentSelection selection ->
>             if (selection.candidate.group == 'org.sample') {
>                 selection.reject("rejecting experimental")
>             }
>         }
>         module("org.sample:api") { ComponentSelection selection ->
>             if (selection.candidate.version == "1.1") {
>                 selection.reject("known bad version")
>             }
>         }
>     }
> }
>
> 2. component metadata rules:
>
> dependencies {
>     components {
>         eachComponent { ComponentMetadataDetails details,
> IvyModuleDescriptor ivyModule ->
>             if (details.id.group == 'my.org' && ivyModule.branch ==
> 'testing') {
>                 details.changing = true
>             }
>         }
>     }
> }
>
> Cheers!
> --
> Szczepan Faber
> Core dev@gradle; Founder@mockito
>
> ---------------------------------------------------------------------
> To unsubscribe from this list, please visit:
>
>     http://xircles.codehaus.org/manage_email
>
>
>


-- 
Darrell (Daz) DeBoer
http://www.gradleware.com

Reply via email to