I’m aware that this is a rather broad search for ideas, not an isolated, concrete question that can be quickly answered with a simple do this or that.
I have a multi-project build that produces a set of (related) products (client application, server installation package, additional tools and modules). Each product comes in multiple, varying distributions, e.g. * platform independent zip * Linux tar ball with bundled JRE * Windows installer * Mac application bundle * Java Webstart client web application
The different distributions of one product have, of course, largely the same content, but not always the same directory layout. I built a gradle plugin to define these distributions in a (more or less) declarative way, based on nested 'CopySpec’s.
My task now is to build a variation of this product set that is branded for one customer. The branding changes * images and texts in the distributions * icons and property files that are classpath resources, packed in jar files * archive / installer file names and (contained) base directories
I’m looking now for any ideas how to implement such a branding (ideally in a way so that other brandings could follow) in that gradle build, so that the existing distribution definitions (which are unfortunately rather large and complex) can be reused as much as possible. We have this implemented in ant, by unpacking jars and distributions and replacing single files, but the whole ant build, and esp. this part, is so confusing and error prone that I# seeking for a better approach to handle this.
If there’s any detail I should share here to make it easier to answer, please tell me.
It’s very hard to answer the question because it’s so general, but your situation seems very complex.
The only advice I can offer is to make liberal use of copyspecs, but you seem to be doing that already.
did you find a nice solution for these variations of building and packaging depending on the customer for whom you actually execute the build?
I have the same problem and I’m thinking about defining different tasks just calling ‘build’ for each customer, and then do some conditionalized things elsewhere depending on which task is on the build graph. Or is there a nicer solution?
Actually I didn’t get to implement a “nice” solution. As we have only one customer who has a branded distribution, I resorted to a bit of copy/paste. What I did:
- put all classpath resources that can be branded in separate jar files(*) * keep references to several 'CopySpec’s (each for a set of related files) * make sure that resources that can be branded are defined in isolated ‘CopySpec’ * defined corresponding CopySpecs and resource jar tasks for the branding (I use a separate subproject with java resource source sets for that) * copied the tasks that create the relevant archives/installers (that customer is only interested in some modules/platforms) * in these copies, change the references to the branded 'CopySpec’s and jar tasks * hook these branded installer tasks into the project lifecycle (as dependencies of lifecycle tasks)
This works for us, as we have only one, but extensive branding. For a greater number of brandings I’d try to model these with a declarative build script block, and a domain object container. The complexity in my case was: I already did that for platform and distribution formats, and had to combine these two axes. That certainly is possible to model, but it was not worth the effort in my case.
(*) the one resource that could not be isolated was a splash screen for a swing application, which needs to be in the same jar as the main class (for Java 6+ splash screen support). I re-packaged the original bootstrap jar with the branded image for that.
Hi Rainer, thanks for your respose (which unfortunately did not make things clearer to me; which may be just my problem…)
you might have a look at my trial: http://forums.gradle.org/gradle/topics/multiproject_producing_multiple_artefacts_depending_on_customer_specific_configurations