Hi Adam,

The one tweak I'd like to see on top of your refinement is that the github repo limit itself to resolving dependencies with a group of com.github.somegithubid. I'll take a look at creating a patch to add the github() repository resolver.

Cheers,
Merlyn

On Jul 2, 2011, at 12:53 AM, Adam Murdoch wrote:


On 02/07/2011, at 1:19 AM, Merlyn Albery-Speyer wrote:

Hi all,

I'd like to make it easier for third party plugins to be integrated into Gradle builds. Right now plugins either need to insist on an internet connection in order to apply a script, or the contents of that script needs to be inlined. "apply plugin: 'xxx'" is so much cleaner than bulky build script dependencies configurations with funky GitHub Ivy resolvers. Getting plugins added to maven central is enough of an obstacle that no-one does it. So, these are the motivating pain points for me.

This is the kind of DSL change I'm considering:

apply plugin: 'pluginname', githubid: 'githubid', version: '1.0'

The key here being that as a side-effect of the apply that it adds an IvyResolver that will resolve to a URL pattern like this: "http://cloud.github.com/downloads/[organisation]/[module]/[module]- [revision].[ext]" But only for an exact match on the dependency: organisation "githubid", module "pluginname", and version "1.0". The other side effect of course being an implicit: "buildscript { dependencies { classpath 'githubid:pluginname:1.0' } }".
What do you think? Would this be in line with the plans for Gradle?

Pretty much, but with some tweaks.

I think there are 2 really good ideas here:
* A convenience, and convention, for resolving dependencies from github. * Inlining the dependency declaration for a plugin into the apply statement, so you don't need the buildscript { } boilerplate.

I think we should separate the two, so that they can be used independently of each other (and, of course, together).

I can see how you might want to resolve any type of dependencies from github, not just plugins. In fact, doing this turns github into an interesting alternative to maven central for the distribution of binaries, with much more control for the binary author. This suggests to me a new type of repository in the DSL:

repositories {
    github()
}

I can also see how you might want to resolve a plugin from any repository, not just github. Being able to inline the dependency declaration into the apply statement is something we've discussed before. The plan is to have the apply statement handle dependency coordinates. You would be able to do any of the following:

1. apply group: 'mygroup', name: 'myplugin-project', version: '1.0', plugin: 'myplugin'
2. apply group: 'mygroup', plugin: 'myplugin', version: '1.0'
3. apply plugin: 'myplugin'

Option 1. would resolve 'mygroup:myplugin-project:1.0' using buildscript.repositories, then scan the resolved artifacts (but probably not their dependencies) for a plugin with id 'myplugin', which it would then load and apply.

Option 2. would use the plugin id as the dependency project name, and resolve 'mygroup:myplugin:1.0' using buildscript.repositories.

Option 3. would work as it currently does now. That is, it scans the build script classpath for a plugin with id 'myplugin'

What this means is that instead of:

buildscript {
    repositories {  someRepo() }
    dependencies { classpath 'mygroup:myplugin:1.0' }
}

apply plugin: 'myplugin'

You would do:

buildscript {
    repositories { someRepo() }
}

apply group: 'mygroup', plugin: 'myplugin', version: '1.0'

We could simplify this further by using project.repositories instead of project.buildscript.repositories for resolution, or by having project.buildscript.repositories default to project.repositories:

repositories { github() }

apply group: 'mygroup', plugin: 'myplugin', version: '1.0'.

There is (at least) one complication to this approach. At the moment, a plugin can contribute static types to a build script classpath. That is, when I declare some dependencies in buildscript { dependencies { classpath ... }}}, then the types packaged in these jars are visible in my build script. This means, for example, I can use the task types to declare task instances:

task someCustom(type: SomeCustomTaskType)

I think it will be extremely difficult to get this to work with arbitrary apply statements scattered throughout the build script. The main problem is that in order to figure out the script classpath, you need to first execute the script.

Some possible solutions:

1. Only allow apply statements at fixed locations in the script, so we can do some AST analysis to figure out what the classpath should be.

2. Don't try to solve the problem. I think we want to move the DSL in this direction anyway, where the DSL uses properties and factory methods to declare things, rather than using static types.

I'd be tempted to go with option 2, plus the associated bits and pieces to make it easy to handle not having access to plugin types in the script.


--
Adam Murdoch
Gradle Co-founder
http://www.gradle.org
VP of Engineering, Gradleware Inc. - Gradle Training, Support, Consulting
http://www.gradleware.com


Reply via email to