This is the continuation of a synchronous conversation I had with Adam, that
I'm putting on the dev list for anyone who is interested.
We went from having a generic Publish task, to targeting more focussed tasks
like IvyPublish. I'm now questioning why we want to do this.
Pros:
1. Additional type safety (Use IvyPublication and IvyArtifactRepository instead
of Publication and ArtifactRepository in the getters/setters)
2. Opens up the potential for Ivy specific configuration options to be used
during publication that don't belong on Publication or ArtifactRepository
Cons:
1. Initially, besides the stronger types there would be no difference with a
generic Publish in terms of impl
2. Closes the door (in a sense) on being able to publish Ivy publications to
non “ivy” repositories that you can publish an Ivy type thing to (e.g. github)
Some background…
The types in play are:
- Publication
- NormalizedPublication
- ArtifactRepository
- Publisher
Publication is the public user facing, DSL/lifecycle optimised type. It can
produce a NormalisedPublication which is expressed in the native terms of the
publication format. It's also realised in that all of the dependencies have
been satisfied (i.e. the artifacts to publish have been created). A Publication
advertises the type of NormalisedPublication it produces ahead of time.
An ArtifactRepository can provide a Publisher for a given NormalizedPublication
type. This is a runtime thing, so an ArtifactRepository can handle zero or more
different types of NormalizedPublication.
So a Publish operation as it stands is a wiring of a Publication and an
ArtifactRepository. Given a Publication and an ArtifactRepository we can tell
if they are compatible without needing to realise the Publication in theory,
but because these values (of the Publish task) may be convention mapped and we
don't know when they have been finalised we cannot do this check until
execution time. So you could go through your entire build and then be about to
publish, only to have it fail through misconfiguration (which is not new, you
could easily have the URL to publish to wrong for example).
So it starts to look like strongly typed Publish task variants such as
IvyPublish are better. But given that we don't have compile time type safety,
it's not that big of a difference. Convention mapping introduces the same late
checking problem. Given that we don't have a case for any Ivy specific
configuration on an IvyPublish task, I'm leaning away from this and leaning
towards a generic Publish.
One of the things we wanted to explore was reconfiguring publication somehow,
so something like:
publishing {
publications {
ivy1 { }
ivy2 { }
maven1 { }
}
repositories {
ivy { name = "releases" }
ivy { name = "snapshots" }
maven { name = "legacy" }
github { name = "github" }
}
}
We could still create a matrix of publish tasks in a compatible way (bad impl,
but illustrative hopefully)…
tasks.addRule("publish rule") { String taskName ->
publishing.publications.each { p ->
publishing.repositories.each { r ->
if (taskName == "publish${p.name.capitalize()}To{$r.name.capitalize()}") {
if (r.createPublisher(p.normalizedPublicationType) != null) { //
compatibility check
project.task(taskName, type: Publish) {
publication p
repository r
}
}
}
}
}
./gradlew publishIvy1ToReleases
./gradlew publishMaven1ToLegacy
./gradlew publishIvy1ToGithub
./gradlew publishMaven1ToGithub
The point being that we don't really need strong types to give good diagnostics
I think.
I guess the fundamental question is, what exactly is the Publish task?
--
Luke Daley
Principal Engineer, Gradleware
http://gradleware.com
---------------------------------------------------------------------
To unsubscribe from this list, please visit:
http://xircles.codehaus.org/manage_email