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