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.


--
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