So I'm battling a bit as to whether we should really be modelling these replacements at the component level (using rules as suggested) or should be designing these at a higher level, on some sort of new model concept.
Reviewing some of the old emails on this, I found this from Adam: I think it’s still an open question as to whether we use the component > (instance) meta-data rules or introduce a new type of meta data for streams > of work and how they map to modules over time. > If we decide to add this to component meta-data then we would use whatever > DSL happens to be available for defining the component meta-data, which > happens to be `dependencies.components.eachComponent`. We’d later add the > modules(_) { … } convenience DSL. So the alternative to component metadata rules will be modelling some new data structure, which we've done in the current implementation with "component module" (ComponentModuleMetadata). This doesn't quite represent a 'stream of work', but perhaps it could evolve in that way. So the big question in my mind is do we: a) Implement 'replaces/replacedBy' at the component instance level, and configure it via component metadata rules OR b) Do a bit more work to model component replacements in the context of a 'stream of work' and clearly separate the DSL from the metadata rules. On Wed, Sep 24, 2014 at 10:41 AM, Szczepan Faber <szcze...@gmail.com> wrote: > Awesome feedback! Let's skype on it today. > > On Wed, Sep 24, 2014 at 5:50 PM, Daz DeBoer > <darrell.deb...@gradleware.com> wrote: > > 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 > > > > -- > 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