I’m using a custom plugin that is stored in a private S3-backed ivy repository, but I’m having trouble using dynamic versions when referencing it in my gradle build script. Using a specific version works just fine with the S3-backed repository, and dynamic versions work correctly if I put the plugin in a local standard-file-based repository.
The S3 credentials that I’m using have the ability to list the contents of the bucket (tested using a separate S3 command-line tool), including the contents of the directory that gradle reports as having no versions.
> Could not find any matches for com.razerzone:library-publishing:1.0.+ as no versions of com.razerzone:library-publishing are available.
Searched in the following locations:
s3://ivy-bucket/repo/com.razerzone/library-publishing/
This is what is actually in the S3 repo:
s3cmd -c ~/s3cfg.ivy-bucket ls s3://ivy-bucket/repo/com.razerzone/library-publishing/
DIR s3://ivy-bucket/repo/com.razerzone/library-publishing/1.0.0/
DIR s3://ivy-bucket/repo/com.razerzone/library-publishing/1.0.2/
DIR s3://ivy-bucket/repo/com.razerzone/library-publishing/1.0.3/
DIR s3://ivy-bucket/repo/com.razerzone/library-publishing/1.0/
If I reference one of the versions directly via classpath 'com.razerzone:library-publishing:1.0.2' then it works correctly.
Any ideas on how I can work around this, or where in the gradle source I could start hunting to fix this?
I’ve tried it with full-access credentials and still get the same result. Later this week or early next I can try building gradle from source and adding some more logging to the S3Client.
Had a quick poke at it - interestingly the problem seems to be in the amazonS3Client.listObjects call. It’s returning no summaries at all. If I instead use the non ListObjectsRequest call (listObjects(bucketName, prefix)) then it correctly gets the objects - though it fails to determine which version to use. Continuing investigation.
Incidentally, the gradle daemon seems to have issues building subproject tasks. The following command does not result in a new gradle being built and/or installed properly on subsequent builds: ./gradlew resourcesS3:build -x resourcesS3:test -x resourcesS3:integTest install -Pgradle_installPath=/Users/gleach/gradle-source-build when the daemon is in charge. When the daemon is not enabled it works. Should probably be a new topic though, unless it’s a known bug already.
Edit:
Okay, I think I’ve found the problem.
No summaries are returned because the default ivy structure does not keep files in the module directory - it keeps version directories.
The listObjects call is returning the version directories (eg. common prefixes). This explains why it works when an explicit version is specified - because there ARE files in that directory.
No, listObjects is returning all the items in the directory, including the directories. resolveResourceNames is ignoring the the directories. This happens because resolveResourceNames is only considering object summaries - but directories are returned as common prefixes.
It’s possible to fix this use-case by pushing objectListing.getCommonPrefixes through some directory-name-extraction function similar to extractResourceName. This breaks a few tests, but this is what I used.
On the subject of extractResourceName, it seems fundamentally flawed to only consider files that have a . in the name as resources. I’m guessing that it’s legacy support and/or matching the way that other ResourceConnectors work, but shouldn’t that ignoring of files happen in the consumer of the file-listing, instead of the S3Client?
Edit: Fixed the tests and am putting together a pull request. Will update with the link to the PR later today.