Starting with a DSL here seems risky to me. I’d start with a Java builder API that supports the kind of composition Adam is talking about and then work back to something more sugary if necessary, or provide the sugar as wrappers over the builder API for common cases. On 8 September 2014 at 9:53:48 am, Adam Murdoch (adam.murd...@gradleware.com) wrote:
On 7 Sep 2014, at 4:03 am, johnrengelman <john.r.engel...@gmail.com> wrote: I was thinking about this and I was wondering if it would make more sense to push the backing type further up the DSL. So instead of specifying the type at the credential method, you would specify it at the repository declaration: repositories { maven(S3Maven) { bucket = 'mybucket' credentials { accessKey = 'key' secretKey = 'secret' } } } This way, then the DSL can be evaluated for the proper methods and types for that specific backing implementation. So in this case, the normal maven {} and ivy {} methods would use a default http/https a implementation. Thoughts? It’s certainly an option. This idea of being able to statically declare certain things about something in the model (a repository, for example) has been surfacing a bit recently. I reckon there’s something in it. There are a few implications of a DSL like the above. You could think of a repository definition as made up of a few things: - The layout, or naming scheme for finding things. - The meta-data scheme or schemes, eg pom, ivy, no meta-data, etc. - The transport, or how to access the things in the repository. - The credentials These things are somewhat independent, so that you should be able to specify pretty much any combination of these things. Not every combination makes sense, at least out of the box. But most (or many) do. We want to make these things extensible, so that I can define my own implementations of one of them, but reuse some of the other pieces. For example, I want to be able to define a new transport that I can combine with (say) Maven layout and meta-data schemes and (say) x509 cert credentials. Or add a custom authentication scheme to the HTTPS transports and use it to access my Ivy repository. We also want to be able to reuse the credentials and transports for things other then accessing repositories. For example, in the wrapper/tooling api to fetch the Gradle runtime, or in the copy tasks to access remote resources, or in the new plugin DSL, etc. One issue with something like using a `S3Maven` type is that it binds together the transport, credentials, format and meta-data scheme into a single static thing. This isn’t necessarily a problem. The reality is that there are some very common combinations that make sense together and I, as the build script author, shouldn’t have to define all the pieces each time I point my build at some repository. So, if using `S3Maven` were a convenience for assembling 3 or 4 pieces together, but there were some way to compose a repository definition from the smaller pieces, then this would be a reasonable approach. One tweak would be to let you mix in a few different types for a repository definition: repositories { maven(Maven, S3) { assert delegate instanceof Maven assert delegate instanceof S3 // transport specific properties to specify the target bucket = ‘…’ credentials { assert delegate instanceof AwcCredentials accessKey = ‘…' secretKey = ‘...' } // layout scheme specific properties uniqueSnapshots = false } } This way, you can compose repository layout and transport. We might also push things in the other direction. The static repository type could also imply not just the possible types of properties you can provide for the repo, but also some canned values. For example, we might have types like `MavenCentral`, `MavenLocal`, `JCenter`, `GradlePlugins` and so on, that imply not just the layout and transport, but also the URL where the repo is, and other settings. You might also be able to define your own types: `MyOrgPlugins`, `MyOrgReleases` etc. There are a couple of other issues, given a definition like this: repositories { someName(Maven, Http) { url = ‘http://some-server' } } Firstly, the transport can almost always be inferred from the url, which I have to specify as well as the transport type. So, in some ways it would be good to be able to do this: repositories { someName(Maven) { url = ‘http://some-server' // implied from the URL assert delegate instanceof HttpRepository // http transport specific properties ... } } Another issue is that the name is often meaningless, at least to the build author. It would be nice to have a DSL where I didn’t need to give the thing a name if I don't care: repositories { repo(Maven, MyCustomTransport) { url = ‘…' } repo(MavenCentral) } // They still have a name - it is assigned some default value repositories.all { assert it.name != null } There are many ways we could structure a DSL: repositories { repo(<types>) { // keyword could be ‘add’ or ‘define' instead of ‘repo' <settings> } } repositories { <name>(<types>) { <settings> } } repositories { repo(<types-or-identity-settings>) { <settings> } repo(Maven, url: ‘http://..', name: ‘somename’) { // also implicitly an Http repo, inferred from the URL } repo(Maven, Http) { url = ‘...' } } repositories { repo { <types-and-identity-settings> <other-settings> } repo { type = MavenCentral } repo { type = Maven url = ‘s3:…’ // Also implicitly an S3 repo credentials { accessKey = ‘…’; } } repo { type = Maven, Http name = ‘someName url = ‘...' } } There will be heaps more options, too, I imagine. — John On Sat, Sep 6, 2014 at 12:21 PM, adrianbk [via Gradle] <[hidden email]> wrote: I took an initial stab at starting with the DSL: credentials(AwsCredentials){ ... } My fork is here: https://github.com/adrianbk/gradle/tree/maven-aws-s3 I was wondering if one of the devs could take a look? A couple of things feel a bit nasty and wanted to get some pointers. If you take a look at RepositoryCredentialsDslIntegrationTest the scenario 'passwordTyped' fails because I can't specify specific enough 'public void credentials(..)' methods in AbstractAuthenticationSupportedRepository to support different implementations of RepositoryCredentials. It feels a bit like a hack to get around how the ConfigureUtil/delegate stuff works. Wondering if there is a better approach or an example of how to use configuration closures with specific types in DSL's. If you reply to this email, your message will be added to the discussion below: http://gradle.1045684.n5.nabble.com/Contribution-request-add-support-for-SFtp-and-SSH-for-publishing-and-resolving-tp5712306p5713126.html To start a new topic under gradle-dev, email [hidden email] To unsubscribe from gradle-dev, click here. NAML View this message in context: Re: Contribution request: add support for SFtp and SSH for publishing and resolving Sent from the gradle-dev mailing list archive at Nabble.com. -- Adam Murdoch Gradle Co-founder http://www.gradle.org CTO Gradleware Inc. - Gradle Training, Support, Consulting http://www.gradleware.com