On 16/08/2012, at 1:30 AM, Adam Murdoch wrote:

> Hi,
> 
> Something we've wanted to do for a long time is have some way to 
> automatically apply a plugin when you run Gradle from the command-line and/or 
> IDE. There are a number of nice usages for this:
> 
> * Running 'gradle idea' automatically applies the idea plugin and runs the 
> 'idea' task. This is useful, for example, when working with an open source 
> project whose developers don't use IDEA. Same for the eclipse plugin.
> 
> * Running 'gradle wrapper' automatically applies the wrapper plugin and runs 
> the 'wrapper' task, which sets up the wrapper to point at the current version 
> (the wrapper plugin doesn't exist yet). Or running 'gradle 
> wrapperLatestRelease' automatically applies the wrapper plugin and runs the 
> 'wrapperLatestRelease' task, which sets up the wrapper to point at whatever 
> the version at http://services.gradle.org/versions/current happens to be. 
> This is useful for managing which version your build needs, without needing 
> to have these tasks defined in your build.
> 
> * For the new bootstrap and upgrade/migration plugins, you'd be able to run 
> 'gradle bootstrap' or 'gradle checkUpgrade' or whatever, without having these 
> defined in your build. In particular, it would mean you could go to a 
> directory containing a Maven build and no Gradle stuff, run 'gradle 
> bootstrap' and you've got an initial Gradle build.
> 
> * It would allow us to move some stuff out of core and into plugins. For 
> example, the daemon management command-line options like --stop could instead 
> be a task in a plugin. And this would give as a good place to add more daemon 
> stuff (e.g. query the daemon status). Or the help tasks and reporting tasks 
> could live in a plugin. Or the profiler could live in a plugin, which would 
> allow us to offer more report formats and so on.

Off topic: Why is this option “--stop”? What is it stopping exactly? The world?

> The basic idea is that when an unrecognised task name is specified for a 
> build, Gradle will look for a plugin that provides that task, and apply the 
> plugin. Initially, we're only interested in providing this for built-in 
> plugins, but definitely want to extend this to custom plugins at some point.

I'm not convinced about the auto apply of plugins. I can see the convenience of 
it, I'm just not sure it's worth the cost. However, if it facilitates moving 
more “core” functionality into plugins then that's enough for me… though there 
might be other ways to do this.

For me, this is also pretty far down the list of priorities. I'd be more 
impressed with good tools for verifying Gradle upgrades than the fact that I 
can do it with adding anything to my buildscript.

> There are a few basic approaches to how a plugin declares which tasks it 
> provides:
> 
> 1. We maintain a hardcoded list in core.
> 2. We add a resource that we can find using ClassLoader.getResources(), 
> called, say META-INF/gradle-plugins/meta-info.properties.
> 3. We add something to the existing 
> META-INF/gradle-plugins/${plugin}.properties.
> 4. We add some annotations to the plugin implementation.
> 
> Options 1 and 2 are easy to implement. Options 3 and 4 require us to scan the 
> classpath and cache the result. But, we need to do this kind of thing anyway 
> (invalidate task outputs on implementation change, plugin-provided services, 
> declarative extensions and the like).
> 
> Options 2, 3 and 4 mean auto-apply would be available for custom plugins, 
> provided you're using a custom distribution or an init script.
> 
> Option 4 means we can include this information in the DSL reference.
> 
> We might combine options, so that you use annotations in your source and at 
> build time we generate an easy-to-find resource.
> 
> Implementation-wise, there are a bunch of issues to sort out:
> 
> * How does a user discover the full set of tasks that are available? Include 
> them in the output of 'gradle tasks'? A new report? The DSL guide? All of the 
> above? Something else?

There has to be a way for a user sitting in front of a build to determine *all* 
of the things they can do with it. I don't like the idea of magic tasks that 
there is no way I can know exist at all.

> * What do we need to expose through the tooling API?
> 
> * How do we deal with plugins that should be applied once per build (wrapper, 
> bootstrap, profile, etc) vs those that need to be applied to all projects 
> (idea, eclipse, etc)?
> 
> * How will this interact with camel case matching? Do we consider first the 
> set of declared tasks, and then second the set of implicit tasks, or do we 
> consider them all in one set?
> 
> * How will this work for build types? (and, what is a build type? :)
> 
> * How do we make this work for custom plugins?
> 
> This last question is interesting. We might use the plugin portal here, to 
> serve up meta-data about plugins. We'd hit some web service, give it (gradle 
> version, task name) and get back a list of candidates. The result would be 
> cached, of course, and we're respect the --offline flag. Doesn't help with 
> custom plugins for the enterprise, of course.

I'll think some more on it, but I'm not big on this idea. As I said, I'm just 
not sure the convenience is worth the cost.



-- 
Luke Daley
Principal Engineer, Gradleware 
http://gradleware.com

Reply via email to