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




Reply via email to