Does Gradle create intermediate directories on publish to Ivy?

I just set up a simple uploadArchives task for publication to our internal Ivy repo via WebDav:

group = 'com.example'
version = 'latest'
    uploadArchives {
 repositories {
  ivy {
   credentials {
    username ivyUsername
    password ivyPassword
   }
   url "http://hostname/repo"
  }
 }
}

When I run the task, Gradle returns the following error:

* What went wrong:
Execution failed for task ':smCommon:uploadArchives'.
> Could not publish configuration ':smCommon:archives'.
   > java.io.IOException: Could not PUT 'http://hostname/repo/com.example/myproject/latest/myproject-latest.jar'. Received status code 409 from server: Conflict

The explanation for this per WebDav docs is, “A collection cannot be made at the Request-URI until one or more intermediate collections have been created.” And this is true: the full path for this artifact does not yet exist. Only “http://hostname/repo/com.example” exists.

I worked around this by logging on to my Ivy server and manually creating “/myproject/latest” in the repo, after which re-running the Gradle script successfully uploads the file.

Is this a bug, or is there something I’m doing incorrectly?

Which Gradle version?

I’m using 1.0.

No, Gradle publishing is not WebDav aware, and assumes that the HTTP server will handle creating any required directories on PUT.

I wouldn’t say this is a bug, but a feature (WebDav) that is not yet supported.

Thanks, Daz, that leads me to two questions:

  1. If not via WebDAV, what is the default method Gradle expects to use to publish?

  2. I searched the Gradle issues list and didn’t see this feature. Is this something that needs to be logged as a feature request?

Ryan

When using the ivy {} resolver, Gradle expects that the HTTP Server will create intermediate directories in response to a PUT request. Granted, this might be an unreasonable assumption, so I’ve created a feature request for Gradle to support creating these: Gradle-2392.

In the meantime, I think your best bet is to directly configure an Ivy DependencyResolver. The best docs for how to do this are in the integration tests here.