On 04/09/2012, at 8:36 PM, Luke Daley wrote:

> 
> On 04/09/2012, at 2:29 AM, 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.
>> * The variants are not directly addressable from some other build tool.
>> * Often, the variants are not all built and published in one build. For 
>> example, my Windows variants are built on a different machine to my Linux 
>> variants. This means that the module is effectively a changing module for 
>> some period of time.
>> 
>> Option 2 addresses these, but adds some new issues:
>> * There's no meta-data for the component as a whole. For example, which 
>> variants are available? which variants are available that can be linked into 
>> a 32 bit windows debug multi-threaded executable?
>> * Variant independent artefacts are published multiple times. For example, 
>> if I have 16 different combinations of operating system, data model, debug 
>> and compiler, I end up with 16 copies of my headers and source.
>> 
>> Option 3 feels pretty good to me. It adds physical representations for each 
>> of the 3 'things' here: the 2 variants and the component itself.
>> 
>> We do have some other options for publishing to Ivy repositories. For 
>> example, we might publish a single module and add [variant] as something you 
>> can refer to in an artifact pattern, so you can do something like this:
>> 
>> my-org/my-lib/1.2
>>     ivy.xml
>>     my-lib-cpp-headers-1.2.zip
>>     my-lib-source-1.2.zip
>>     x86/
>>         my-lib-1.2.dll
>>         my-lib-1.2.lib
>>         my-lib-1.2.pdb
>>     amd64/ 
>>         ...
>> 
>> I'd rather use the same mapping for both Maven and Ivy, however.
> 
> Only thing I can add is that I agree that #3 is the way forward. Given what 
> we have to work with, it makes the most sense.
> 
> I think variants to have be able to have their own “extra” artifacts (e.g. 
> source) though. 

Absolutely. You can see that kind of implied in the example above, with the 
.lib and .pdb files for the x86 variant.


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

Reply via email to