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

Reply via email to