On 17/08/2012, at 8:13 PM, Luke Daley wrote:

> 
> On 16/08/2012, at 9:28 PM, Adam Murdoch wrote:
> 
>> 
>> On 16/08/2012, at 8:39 PM, Luke Daley wrote:
>> 
>>> 
>>> 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.
>> 
>> This is much deeper than convenience. This is a change to Gradle's view of 
>> how build logic is structured. What we're doing is separating build logic 
>> into 2 pieces:
>> 
>> 1. Build logic that describes what the project is, what it represents.
>> 2. Build logic that provides actions over that project, the things you can 
>> do with it.
>> 
>> Currently, Gradle expects you to declare both what the project is and the 
>> full set of all things you can do with it. There are a number of problems 
>> with this:
> 
> There is also a BENEFIT in that it becomes completely self describing. This 
> shouldn't be discounted.

I think the benefit is really only in the describing what the project is. Given 
a description of a project we can infer a lot of stuff (including what you can 
do with it). Describing what you can do with it is often unnecessary, and often 
undesired, too.

You can see this already with our existing plugins. When you apply the Java 
plugin, say, you don't describe the things you can do with the build. You 
declare what it is (a Java project, with such and such dependencies). You don't 
say anything about which tasks are available.

This is exactly the same behaviour we're talking about with auto applying 
plugins. You say something about what the project is and you get some implicit 
behaviour. It really is just an implementation detail whether the tasks are 
statically created, or created by a task rule on first access, or created by 
applying a plugin on first access.

If you reason that we shouldn't be adding behaviour by auto-applying plugins, 
then you really need to apply the same reasoning to the tasks that plugins add. 
But the whole essence of Gradle is that you describe what the project is, and 
you get the behaviour for free.


> 
>> * Often, there are many things that you can do to a project that can be 
>> inferred from what it is, without needing to declare or configure anything. 
>> For example, any Gradle project can use the wrapper, or any Java project can 
>> be imported into Eclipse.
> 
> You can't take any project, though you can probably take most. This goes to 
> the point that Steve raised.
> 
>> * It forces the build author to anticipate every possible use for the 
>> project.
>> 
>> Allowing plugins (i.e. build logic) to be implicitly applied to a project 
>> based on what the project is, gives us a unified, flexible mechanism for 
>> decorating builds to add more "things you can do with it" without changing 
>> the build, or Gradle core. Or without even having a build. This is important 
>> for end users, for tooling, and for us as developers of Gradle.
>> 
>> What we're doing here is taking the declarative stuff (i.e. here's what this 
>> project is) and cranking it up so you can reuse that information in more 
>> contexts.
> 
> The only use case I've heard that I find compelling is the IDE use case,

Here are some other use cases I find compelling:

* Manage the wrapper without (manually) changing any build files.
* Enable or disable the daemon without editing the properties file.
* Bootstrap a new project, in an empty directory or in a directory with 
existing source.
* Set up a new development or CI machine.
* Bootstrap working on a new project.
* Convert a Maven build to a Gradle build.
* Upgrade a Gradle build to a new version of Gradle without changing any build 
files.
* Start, stop and query the status of the daemon.
* Generate an ad hoc profiling report, in various formats.
* Generate an ad hoc dependency report, in various formats.
* Query what tasks are available for the project.
* Query and manage project specific configuration settings.
* Manage user credentials.

These are all behaviours that we can infer from a description of what a project 
is, and so are good candidates for packaging in plugins, that can be 
automatically applied. Why should you declare any of this stuff in the build 
script? What benefit is there in declaring 'you can list the tasks that are 
available in this project', or 'you can upgrade the wrapper to the latest 
release candidate'?


> and there are caveats there:
> 
> * We want to push this responsibility to the IDEs themselves

Don't forget how we actually implement this: our IDE integration automatically 
applies the appropriate plugins. So, as we make this work better, auto-apply 
works better from the command-line, too.


> * It only works for simple projects

As I mentioned, this isn't true. For ad hoc usage (which is what we're 
interested in here), it works perfectly well.


--
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