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


Reply via email to