On 05/09/2012, at 2:17 PM, Adam Murdoch wrote: > > On 05/09/2012, at 1:06 PM, Adam Murdoch wrote: > >> >> On 05/09/2012, at 10:18 AM, Adam Murdoch wrote: >> >>> >>> On 05/09/2012, at 6:55 AM, Hans Dockter wrote: >>> >>>> >>>> >>>> On Tuesday, September 4, 2012, Adam Murdoch wrote: >>>> Hi, >>>> >>>> One question we need to answer soon is how variants should be mapped to >>>> Ivy and Maven repositories. Have a look at the dependency model spec for a >>>> definition of variant: >>>> https://github.com/gradle/gradle/blob/master/design-docs/dependency-model.md#variant >>>> >>>> We want to define some conventions (or a standard in the cases where >>>> there's no obvious convention), and build some plugins that can do useful >>>> stuff based on these. As always, the infrastructure needs to be flexible >>>> to some degree, so you can choose to use some other convention (but the >>>> further you go from our convention, the more work you have to do). >>>> >>>> Some concrete examples we're interested in: >>>> * I want to publish Groovy 1.8 and Groovy 2.0 variants of my Groovy >>>> library. >>>> * I want to publish x86 and amd64 variants of my native library. >>>> * I want to publish minified and non-minified variants of my Javascript >>>> library. >>>> >>>> There's another dimension that we're not interested in here (it's a >>>> separate discussion), and that is packaging: >>>> * I want to publish my Groovy library as both a jar and as a distribution. >>>> * I want to publish both a jar and a war from my Java project. >>>> >>>> There are a few basic options for mapping component variants to a >>>> repository: >>>> >>>> 1. Publish every variant as a single module. So, for my native library, >>>> Gradle would publish module 'my-org:my-lib' that contains both the x86 and >>>> amd64 binaries, the header archive, maybe source and API documentation >>>> archives, plus meta-data for both variants. >>>> >>>> For a maven repository, this might look like: >>>> >>>> my-org/my-lib/1.2 >>>> pom.xml >>>> my-lib-1.2-x86.so >>>> my-lib-1.2-amd64.so >>>> my-lib-1.2-cpp-headers.zip >>>> my-lib-1.2-source.zip >>>> my-lib-1.2-doxygen.zip >>>> >>>> For an ivy repository, it would look more or less the same. The artefacts >>>> might have different names - e.g. my-lib-x86-1.2.so instead of >>>> my-lib-1.2-x86.so. >>>> >>>> 2. Publish every variant as a separate module. So, for my native library, >>>> Gradle would publish module 'my-org:my-lib-x86' that contains the x86 >>>> binaries, and 'my-org:my-lib-amd64' for the amd64 binaries. Variant >>>> independent archives would go in both places. >>>> >>>> For a maven repository, this might look like: >>>> >>>> my-org/my-lib-x86/1.2 >>>> pom.xml >>>> my-lib-1.2.so >>>> my-lib-1.2-cpp-headers.zip >>>> my-lib-1.2-source.zip >>>> my-lib-1.2-doxygen.zip >>>> >>>> 3. Publish each variant as a separate module, plus publish a >>>> variant-independent module. For my native library, Gradle would publish >>>> 'my-org:my-lib-x86' for the x86 binaries and meta-data, >>>> 'my-org:my-lib-amd64' for the amd64 binaries and meta-data, and >>>> 'my-org:my-lib' for the headers, source, documentation and meta-data about >>>> the available variants. >>>> >>>> For a maven repository, this might look like: >>>> >>>> my-org/my-lib-x86/1.2 >>>> pom.xml >>>> my-lib-1.2.so >>>> >>>> my-org/my-lib/1.2 >>>> pom.xml >>>> my-lib-1.2-cpp-headers.zip >>>> my-lib-1.2-source.zip >>>> my-lib-1.2-doxygen.zip >>>> >>>> Option 1. has some downsides >>>> * Often, the meta-data for each variant is different. For example, my >>>> Groovy 1.8 variant depends on groovy:1.8, and my Groovy 2.0 variant >>>> depends on groovy:2.0. Or, in native space, my windows variants need >>>> library a, and my linux variants need completely different library b. For >>>> this option, there's a single descriptor that we have to jam everything >>>> into. >>>> >>>> Which is impossible with Maven. Though I think the non Java world is not >>>> strongly bound to Maven. So why not have it in one descriptor in the case >>>> of Ivy. If we would model our own descriptor, how would we do it? Having >>>> one descriptor provides one place to get all the Metadata you need. >>> >>> I'm tending towards separate meta-data files for each variant. >> >> Which, of course, doesn't necessarily mean separate modules. So, let's add a >> few more options: >> >> Option 4. Publish all variants as a single module and include Gradle >> specific meta-data: >> >> my-org/my-lib/1.2 >> pom.xml >> my-lib-1.2-component.xml (for example. This is the component meta-data) >> my-lib-1.2-windows-x86.xml (for example. This is the variant meta-data) >> my-lib-1.2-windows-x86.dll >> my-lib-1.2-windows-x86.lib >> my-lib-1.2-linux-amd64.xml (for example, This is the variant meta-data) >> my-lib-1.2-linux-amd64.so >> my-lib-1.2-cpp-headers.zip >> my-lib-1.2-sources.zip >> >> The pom.xml would be mostly empty. The module would be unusable from >> anything other than Gradle. >> >> Option 5. Publish all variants as a single module and choose one as the >> 'default' to be used by other build tools: >> >> my-org/my-lib/1.2 >> pom.xml >> my-lib-1.2-component.xml >> my-lib-1.2-groovy18.xml >> my-lib-1.2.jar (the Groovy 1.8 variant) >> my-lib-1.2-groovy20.xml >> my-lib-1.2-groovy20.jar >> my-lib-1.2-sources.zip >> >> The pom.xml would contain meta-data for the Groovy 1.8 variant. You can't >> (easily) use the Groovy 2.0 variant from anything other than Gradle. >> >> Option 6. Publish all variants as a single module. When publishing jvm-based >> libraries to a Maven repository, also publish each variant in a separate >> Maven-usable module: >> >> my-org/my-lib/1.2 >> pom.xml (mostly empty) >> my-lib-1.2-component.xml >> my-lib-1.2-groovy18.xml >> my-lib-1.2-groovy18.jar >> my-lib-1.2-groovy20.xml >> my-lib-1.2-groovy20.jar >> my-lib-1.2-sources.zip >> >> my-org/my-lib-groovy18/1.2 >> pom.xml (Groovy 1.8 variant meta-data) >> my-lib-1.2.jar >> my-lib-1.2-sources.zip >> >> my-org/my-lib-groovy20/1.2 >> pom.xml (Groovy 2.0 variant meta-data) >> my-lib-1.2.jar >> my-lib-1.2-sources.zip >> >> This is a combo of option 3 and option 4, and it feels a bit better than >> either. Some extra duplication, though, but this would be relatively easy to >> make tweakable. This could be the default wiring, and you can use the DSL to >> add or remove artefacts from each of the modules as you choose. >> >> Or, option 4 could be the default wiring, and you can use the DSL to ask for >> a maven-usable wiring to be added over the top. > > Another thing to consider is how we resolve a dependency against these > mappings. > > The idea is that you should keep dependency declarations independent of both > variant and packaging. So: > > dependencies { > compile 'my-org:my-lib:1.2' > } >
Then there's what goes in the published meta data. Given the above dependency declaration: * My Groovy 1.8 variant meta-data should declare a runtime dependency on groovy:1.8.+ and my-lib:1.2 * My Groovy 2.0 variant meta-data should declare a runtime dependency on groovy:2.0.+ and my-lib:1.2 * My 'maven-usable' pom.xml for the Groovy 1.8 variant should declare a runtime dependency on groovy:1.8.+ and my-lib-groovy18:1.2. -- Adam Murdoch Gradle Co-founder http://www.gradle.org VP of Engineering, Gradleware Inc. - Gradle Training, Support, Consulting http://www.gradleware.com
