I am trying to publish an ivy module based on multi project build. The build consists of three projects core, server, client where client and server depend on core. For argument’s sake let’s assume that publishing core jar on its own doesn’t make sense.
So, I would like to publish this project as a single ivy module with two configurations (client and server). The produced ivy.xml file should look something like:
I think that declaring the artifacts manually as you did in ivy_test_build.gradle should work, but you will also have to declare the dependencies, which will make it more complicated, what did not work with this build script?
Other option would be to create a module that just references those subprojects - you will have to upload all of them as well and the artifacts will still go with the subprojects, but that this matter that much? Yet another option would be to build all the artifacts in a single project (possibly with different sourcesets).
As you have rightfully pointed out, one of the problems lies in dependencies (or actually in lack of them) in ivy.xml. As you can see from the [actual ivy.xml produced by gradle] (https://gist.github.com/4145778#file_actual_ivy.xml) there are a few things which are a bit off:
‘archives’ config appears out of thin air for no apparent reason and it actually contains ivy-test-client
dependencies are completely missing - I would have to come up with yet another workaround/hack to sort them out
I had to repeat myself - I have already declared that both client and server depend on core and I had to declare that again. I have also had to hardcode the paths to aritfacts (this could be done a bit nicer with interpolation, but still noisy). If I wanted to sort out external dependencies I would probably have to repeat config dependencies again. It all seems a bit much considering that this information is already available. This is why I tried to use :client:jar and :server:jar respectively as artifacts to publish (see commented out sections in [ivy_test_build.gradle] (https://gist.github.com/4145778#file_ivy_test_build.gradle)) in hope that artifacts and dependencies might be resolved correctly, but without success.
So I am still wondering if it is possible to organise and publish the module in the way I’ve described. It is an elegant way to manage a module (see [ivy roundup projects] (http://ivyroundup.googlecode.com/svn/trunk/repo/modules.xml)) and I am a bit surprised by how difficult it seems to be to achieve. Especially considering how easy it is to do in the old ‘ant + ivy’ world. Am I missing something?
The ‘archives’ configuration appears because you apply the ‘base’ plugin, it contains just ‘ivy-test-client’ artifact due to the current implementation of the DefaultArtifactPublicationSet.
About dependencies - I think there is no repetition after all - if you describe the dependencies of the client and server in their respective build scripts and upload them to the target repository, then you do not have to declare their dependencies once again, but only reference them as project dependencies:
dependencies {
client project(’:client’)
server project(’:server’)
}
On the other hand, if you are not willing to upload the client and server modules, then you will have to re-declare all their dependencies in the grouping project as well (you can still copy the dependency definitions instead of re-declaring them). At the end, there will be no duplication on the repository that you upload to. I’m not sure this is much easier to implement in pure ‘ant + ivy’ - how can this happen if you again want to have separate :client and :server subprojects?
You got me thinking about uploading client and server projects to a repository so that I can reference them later on. Maybe I can just “upload” them to a local file system repository. But it all again starts feeling like a hack/workaround.
What I was really hoping for is some kind of first class support for what I’m trying to do. And it feels like it should be possible to do it as all the needed information is there. As I said before - it feels like I should be able to say something like
artifacts {
client ':client:jar'
server ':server:jar'
}
in [ivy_test_build.gradle] (https://gist.github.com/4145778#file_ivy_test_build.gradle) and the rest can be deduced. Can this be done? Should I raise some kind of request? I’ll be up for helping with this task if it is feasible, does not violate any gradle principles and if I can rely on a bit of guidance.
Regarding ‘ant + ivy’: publishing in this manner is trivial as you have full control over ivy.xml. I agree that the build scripts might get a bit hairy - at the moment I rely on a “base” script that allows me to add additional “projects” by just specifying their location and configuration name. There are drawbacks as I can only run commands from the base directory where the single build.xml actually lives, etc. This is one of the reasons why I am trying to move to gradle - I am hoping for a nice build scripting environment (and I have had all my expectations met thus far), but also for that niceness to follow me all the way through the publish phase.
Well in ‘ant + ivy’ world I just have one build.xml and one ivy.xml. The “subprojects” don’t have their separate builds. So I don’t need to generate the file - I have to write it and thus I can write it however I want.
Thanks for the example of single project with multiple source sets. I am aware of this option and was considering it, but it seems that with it I have to do lots of “manual code writing”. It does indeed mimic what I have to do currently in ‘ant + ivy’, but I was hoping for something a bit more elegant. I guess my expectations might have been too/unreasonably high.