Makes a lot of sense to me. How do we then go about transforming these ideas into trackable steps? Pivotal? Jira?
On 05/07/2011, at 6:57 PM, Adam Murdoch wrote: > Hi, > > We want to extend the tooling API to expose the Intellij IDEA model, similar > to the way we expose the Eclipse model. This will allow tools that want to > know about the IDEA model for a build to integrate with Gradle (the obvious, > and probably only, candidate being IDEA itself). > > At the moment, we expose several models through the tooling API. You can > separate these models into 2 groups: the Gradle model, and the Eclipse model. > The Gradle model provides the Gradle view of the build. The Eclipse model > provides the Gradle model mapped onto the Eclipse view of the world. This > Eclipse model is exactly the same one we use to generate the .classpath and > .project files when you run 'gradle eclipse'. > > I think we didn't quite get the relationship between the Gradle and Eclipse > models right with the first cut of the tooling API. Rather than just add in > the IDEA model the same way, I think we should clean this up. > > The Gradle model is represented using various subtypes of Project (for this > discussion, I'm referring to org.gradle.tooling.model.*, not > org.gradle.api.*): > > * Project provides some basic identifying information about a project. > * BuildableProject extends Project and provides information about the tasks > of the project. > * HierarchicalProject extends Project and provides information about the > project hierarchy. > > The Eclipse model is also represented using various subtypes of Project: > > * EclipseHierarchicalProject extends HierarchicalProject and provides some > basic information about an Eclipse project. > * EclipseProject extends EclipseHierarchicalProject and BuildableProject and > provides the full details of an Eclipse project. > > What this basically means is that an Eclipse project is-a Gradle project. > Which isn't correct. Often there is a one-to-one relationship between the > two, but not always. We want our Eclipse mapping to handle the case where > there are multiple Eclipse projects per Gradle project (eg to separate out, > say, integration tests, or any other source set). We probably also want our > Eclipse mapping to handle the case where there are multiple Gradle projects > mapped onto a single Eclipse project. So this means, in general, we want a > many-to-many-relationship between Gradle project and Eclipse project. > > For the time being, we probably don't need to expose this relationship in the > tooling API model, but we should separate the concepts of Eclipse project and > Gradle project. > > Another consideration is that what the tooling API calls a 'project', IDEA > calls a 'module'. The tooling API does not yet have a concept that matches an > IDEA 'project'. So, if we here to add the IDEA model the same way as the > Eclipse model, we'd add something called an IdeaModule which extends Project, > and something called an IdeaProject which does not. > > I think there are a few separate concepts here, which we might make explicit > as interfaces: > * An identifiable thing. Not sure what to call this thing, but it's what > Project currently represents. Let's call it a 'model element' for now. It has > an identity, description and some root directory. > * A source element. Has source directories, external dependencies, > inter-element dependencies, and other configuration. > * A buildable element. Has tasks, which can be executed. > * A composite element. A container of other elements. > > We can mix these together to model the various things we need: > > * Gradle project = source element, buildable element, composite element. > * Gradle build = composite element. > * Eclipse project = source element, buildable element. > * Eclipse workspace = composite element. > * IDEA module = source element, buildable element. > * IDEA project = composite element. > > So, a plan might be: > > Rename Project to ModelElement: > * Extract all the methods of Project onto a new super-interface called > ModelElement. Deprecate Project. > * Extract all the methods of BuildableProject onto a new super-interface > called BuildableModelElement. Deprecate BuildableProject. > * Extract all the methods of HierarchicalProject onto a new super-interface > called CompositeModelElement. Deprecate HierarchicalProject. > * Change ProjectConnection.getModel() and model() to work with <T extends > ModelElement>, instead of <T extends Project>. > > Then, add: > * GradleProject extends ModelElement, BuildableModelElement, > CompositeModelElement. > * IdeaProject extends ModelElement, CompositeModelElement. > * IdeaModule extends ModelElement, BuildableModelElement. > > At some point, we might also add a SourceModelElement interface. > > A variation of the above would be to deprecate BuildableProject and > HierarchicalProject and duplicate their methods onto GradleProject, > IdeaProject and IdeaModule, instead of adding BuildableModelElement and > CompositeModelElement (ie don't try to model the abstract concepts). > > > -- > Adam Murdoch > Gradle Co-founder > http://www.gradle.org > VP of Engineering, Gradleware Inc. - Gradle Training, Support, Consulting > http://www.gradleware.com > -- Luke Daley Principal Engineer, Gradleware http://gradleware.com
