On Wed, Sep 5, 2012 at 2:18 AM, Adam Murdoch <[email protected]>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. Some of
> this meta-data you don't know until you build the variant (think
> ivy-deliver type meta-data). If you had a single meta-data file for all
> variants, you'd need to update this each time you published a variant and
> merge in the version-specific stuff. Which means every meta-data file has
> to be considered as changing, which is nasty.
>
>
>
>> * The variants are not directly addressable from some other build tool.
>>
>
> Why?
>
>
> Not easily addressable, I should have said. If I map the Groovy 1.8 and
> Groovy 2.0 variants to separate modules, then in Maven I can do:
>
> <dependency>
>     <groupId>my-group</groupId>
>     <artifactId>my-lib-groovy18</artifactId>
>     <version>1.2</version>
> </dependency>
>
> Or in Ant + Ivy:
>
> <dependency org="my-group" name="my-lib-groovy18" rev="1.2"/>
>
> If I map all variants to a single module, then I need to add more stuff: a
> classifier attribute, or a configuration name, or an <artefact> element.
>

That is what I was thinking.


>
> If I wanted my Groovy library to be consumed by Maven or Ant+Ivy builds,
> it would make a lot more sense to publish it as module-per-variant than
> single-module.
>

Now that you mention it, I agree that it is 'against' the normal flow of
those build systems, in particular Maven.


>
>
>
>> * 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.
>>
>
> Makes sense.
>
>
>>
>> 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.
>>
>
> Which has also the same downside of being a changing module as in option
> 1, i.e. the metadata of the component.
>
>
> Not necessarily. You just publish the component metadata last, once all
> the variants are built. This would mark the component as ready for
> consumption.
>

OK. Makes sense.

Hans


>
>
>
>> 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.
>>
>
> I'm not sure. I'd rather not have the pom model influence what we think is
> the best design for this. I think having different mappings for Ivy if we
> think the Ivy mapping is better is fine.
>
>
> Not sure yet. Let's see what comes out of this discussion.
>
>
> --
> 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