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