On 18/03/2013, at 18:39, Adam Murdoch <[email protected]> wrote:

> 
> On 12/03/2013, at 3:50 AM, Peter Niederwieser <[email protected]> wrote:
> 
>> Hi all,
>> 
>> it recently came up in one of my code reviews that plugin classes should
>> live under `org.gradle.api.$function.plugins`, task classes under
>> `org.gradle.api.$function.tasks`, and all other classes under
>> `org.gradle.api.$function`. I'd like to question the use of the `plugins`
>> and `tasks` subpackages. In my mind, the function should be dominant, and
>> the `plugins` and `tasks` subpackages are often just unnecessary baggage
>> (may contain just a single class, require extra imports, etc.). They also
>> encourage to group only/primarily by plugins and tasks, rather than by
>> function, which I think is the wrong axis of separation. (For an example,
>> see the `plugins` subproject.) Hence, I propose that only
>> `org.gradle.api.$function` should be mandatory, with the further package
>> structure (if any) left to the plugin author. (We'd probably still have to
>> use `internal` for non-public packages.)
>> 
>> We already have a couple of plugin subprojects that don't have `plugins` and
>> `tasks` subpackages, but I was asked to bring this up here for
>> clarification.
> 
> In general, our plugins are made up of the following parts:
> 
> 1. The plugin implementation class.
> 2. An extension and related classes.
> 3. A bunch of model classes.
> 4. A bunch of task implementation and related classes.
> 5. Internal classes.
> 
> Except for #1, some or all of these may be empty or may contain a single 
> class.
> 
> I've made a distinction between extension and model here. The model, if 
> present, describes things (publications, native libraries, source sets, etc). 
> The extension is just a bunch of settings (report directory, etc). Either may 
> be attached to the project via the extensions container.
> 
> We need to come up with some mechanism to enforce the following constraints:
> 
> 1. The public API of model classes may refer only to other model classes. 
> That is, the model must be independent of the how.
> 2. The public API of task classes may refer only to model classes. That is, 
> the tasks must be independent of wiring and must act only on the model.
> 3. The public API of extension classes may refer only to model classes. That 
> is, the plugin settings must be independent of the how.
> 4. The public API of plugin classes may refer only to model, task or 
> extension classes. That is, the plugin does the wiring.
> 
> The current plan to implement this is:
> 
> - model classes in org.gradle.${function}
> - task classes in org.gradle.${function}.tasks
> - plugin and extension classes in org.gradle.${function}.plugins
> - internal stuff in org.gradle.${function}.internal
> 
> This is combined with the classycle package cycle check to do the 
> enforcement. Note that ${function} may be a hierarchy, not just a single 
> element.
> 
> There are other ways to implement this, of course. I'm open to suggestions 
> (somewhat). I'm very keen that at least the following groups are separated:
> 
> - model classes
> - plugin, extension, tasks classes
> - internal classes
> 
> I'm not interested in leaving this unspecified and up to the plugin author.

This logical separation makes sense, no contest there. 

What are you hoping to achieve by forcing this separation? That is, what 
features and automation capabilities?

If being able to physically separate these groups is a requirement, then 
packages would be the cheapest way to do it.


> 
> For reference, here's what we currently use. It's all over the place:
> 
> - Announce:
>       - org.gradle.api.announce (model, extension, plugin)
> - Build announcements:
>       - org.gradle.api.announce (plugin)
> - Antlr:
>       - org.gradle.api.plugins.antlr (model, plugin, task)
> - Checkstyle/CodeNarc/FindBugs/Pmd/JDepend:
>       - org.gradle.api.plugins.quality (extension, plugin, tasks)
> - core:
>       - org.gradle.api.tasks (tasks)
> - Native binaries:
>       - org.gradle.plugins.binaries (plugin)
>       - org.gradle.plugins.binaries.model (model)
> - C++:
>       - org.gradle.plugins.cpp (plugins, extension, model)
> - GCC:
>       - org.gradle.plugins.cpp.gcc (plugin, model)
> - Visual studio:
>       - org.gradle.plugins.cpp.msvcpp (plugin)
> - Eclipse CDT (C++)
>       - org.gradle.plugins.cpp.cdt (plugin)
>       - org.gradle.plugins.cpp.cdt.tasks (tasks)
>       - org.gradle.plugins.cpp.cdt.model (model)
> - Help:
>       - org.gradle.api.plugins (plugin)
>       - org.gradle.configuration (task)
> - Project reports:
>       - org.gradle.api.plugins (plugin, extension)
>       - org.gradle.api.tasks.diagnostics (tasks)
> - EAR:
>       - org.gradle.plugins.ear (plugin, extension, task)
>       - org.gradle.plugins.ear.descriptor (model)
> - Eclipse:
>       - org.gradle.plugins.ide.eclipse (plugin, tasks)
>       - org.gradle.plugins.ide.eclipse.model (model) 
> - IDEA:
>       - org.gradle.plugins.ide.idea (plugin, tasks)
>       - org.gradle.plugins.ide.model (model)
> - Ivy-publish:
>       - org.gradle.api.publish.ivy (model)
>       - org.gradle.api.publish.ivy.plugins (plugin)
>       - org.gradle.api.publish.ivy.tasks (tasks)
> - Jetty:
>       - org.gradle.api.plugins.jetty (plugin, extension, tasks)
> - Maven (old):
>       - org.gradle.api.plugins (plugins, extension)
>       - org.gradle.api.artifacts.maven (model)
> - Maven-publish:
>       - org.gradle.api.publish.maven (model)
>       - org.gradle.api.publish.maven.plugins (plugin)
>       - org.gradle.api.publish.maven.tasks (tasks)
> - Publish:
>       - org.gradle.api.publish (model, extension)
>       - org.gradle.api.publish.plugins (plugin)
> - Pom conversion:
>       - org.gradle.api.plugins.maven (plugin)
> - OSGi:
>       - org.gradle.api.plugins.osgi (plugin, extension, model)
> - Distribution:
>       - org.gradle.api.distribution (model)
>       - org.gradle.api.distribution.plugins (plugin)
> - Java library distribution:
>       - org.gradle.api.plugins (plugin)
> - Java:
>       - org.gradle.api.java.archives (model)
>       - org.gradle.api.tasks (model)
>       - org.gradle.api.plugins (plugin, extension)
>       - org.gradle.api.tasks.bundling (tasks)
>       - org.gradle.api.tasks.compile (tasks)
>       - org.gradle.api.tasks.javadoc (tasks)
>       - org.gradle.external.javadoc (tasks)
>       - org.gradle.api.tasks.testing (tasks)
>       - org.gradle.api.tasks.testing.junit (tasks)
>       - org.gradle.api.tasks.testing.testng (tasks)
>       - org.gradle.api.tasks.testing.logging (tasks)
> - Groovy:
>       - org.gradle.api.plugins (plugin)
>       - org.gradle.api.tasks.compile (tasks)
>       - org.gradle.api.tasks.javadoc (tasks)
> - Scala:
>       - org.gradle.api.plugins.scala (plugin)
>       - org.gradle.api.tasks (model)
>       - org.gradle.api.tasks.scala (tasks)
> - WAR:
>       - org.gradle.api.plugins (plugin, extension)
>       - org.gradle.api.tasks.bundling (tasks)
> - Application:
>       - org.gradle.api.plugins (plugin)
>       - org.gradle.api.tasks.application (tasks)
> - Reporting base:
>       - org.gradle.api.plugins (plugin)
>       - org.gradle.api.reporting (extension)
> - Build dashboard:
>       - org.gradle.api.reporting (model, task)
>       - org.gradle.api.reporting.plugins (plugin)
> - Signing:
>       - org.gradle.plugins.signing (plugin, extension, model, tasks)
>       - org.gradle.plugins.signing.signatory (model)
>       - org.gradle.plugins.signing.type (model)
>       - org.gradle.plugins.signing.type.pgp (model)
> - Sonar (old):
>       - org.gradle.api.plugins.sonar (plugin, tasks)
>       - org.gradle.api.plugins.sonar.model (model)
> - Sonar-runner:
>       - org.gradle.api.sonar.runner (plugin, extension, tasks, model)
> - Wrapper:
>       - org.gradle.api.tasks.wrapper (tasks)
> 
> 
> --
> Adam Murdoch
> Gradle Co-founder
> http://www.gradle.org
> VP of Engineering, Gradleware Inc. - Gradle Training, Support, Consulting
> http://www.gradleware.com
> 
> Join us at the Gradle Summit 2013, June 13th and 14th in Santa Clara, CA: 
> http://www.gradlesummit.com
> 

Reply via email to