Hi,
One issue we need to sort out with the new publication DSL is what should be
published by default, and how the user can override this.
So, for example, if I apply both the 'java' and 'war' plugins, what should be
published by default? The war and its meta-data? The war + jar + their
meta-data? Nothing? How do I change this? What happens when I then apply the
'ear' plugin?
Another question is whether we make a distinction between those publications
that should end up in a repository and those publications that should be used
locally within the same build.
So, for example, if I apply both the 'java' and 'war' plugin and I specify
(however it is I do this) that only the war should be published (to a
repository), should the jar + meta-data still be available via a project
dependency? How do I change this?
Right now, we use a series of hacks that don't really work. I think we should
take this opportunity to move away from this and fix some issues while we're
there.
Given that we want to move to a high-level model that describes components and
their relationships, I think the solution should start us down this path.
Components feel like a good solution here.
So let's say that when you apply the 'java' plugin, you're declaring that the
project produces a Java-based component of some kind. Some kind of
JavaBasedComponent instance is created and shoved in a container somewhere. And
when you apply the 'war' plugin, you're declaring that the project produces an
J2EE based web application. Some kind of J2EEWebApplication instance is created
and shoved in a container somewhere.
We have a few options as to what to publish:
1. Infer the 'main' component and publish this, as we do now. To publish an
additional component, you'd add it to the appropriate publication:
This would publish the web application as a war + meta-data, as we do now (sort
of):
apply plugin: 'java'
apply plugin: 'war'
apply plugin: 'ivy-publish'
This would publish the web application as a war + meta-data and the java
component as a jar + meta-data:
apply plugin: 'java'
apply plugin: 'war'
apply plugin: 'ivy-publish'
publishing.publications.ivy {
publish components.java // a few too many 'publish'es in there, but you get
the idea
}
2. Don't publish anything. You need to declare it, perhaps something like:
apply plugin: 'java'
apply plugin: 'war'
publishing.publications.ivy {
publish components.java
publish components.webApplication
}
3. Split the 'java' plugin into a Java language plugin that knows how to
compile and test Java based stuff, and a Java library plugin that knows how to
publish a Java library for use outside the project.
This does not publish anything:
apply plugin: 'java'
This would publish the Java library as a jar + meta-data:
apply plugin: 'java'
apply plugin: 'java-library'
This would publish the web application as a war + meta-data:
apply plugin: 'java'
apply plugin: 'war'
This would publish both the war and the jar:
apply plugin: 'java'
apply plugin: 'java-library'
apply plugin: 'war'
This would publish an application distribution and the web application as a war:
apply plugin: 'java'
apply plugin: 'application'
apply plugin: 'war'
4. Don't publish anything and add an opinionated 'publish-main-component'
plugin that works like #1 above.
I don't really like any of these options, except maybe the 'publish nothing by
default' option. Any other suggestions?
As far as what should be available via a project dependency, it feels like we
should make every component available, assuming components have some kind of
identity so that they can be referenced from another project. So, perhaps we
would add an implicit local publication for each component.
--
Adam Murdoch
Gradle Co-founder
http://www.gradle.org
VP of Engineering, Gradleware Inc. - Gradle Training, Support, Consulting
http://www.gradleware.com