On 24/07/2013, at 2:01 PM, Alex Ruiz <alr...@google.com> wrote:

> It will help us set dependencies on Studio/IDEA modules that reside outside 
> of a Studio/IDEA project.

I don't really understand what you mean here. Set dependencies where? Perhaps 
an example would help.


> Right now, we have no way to know where the source code of a module external 
> to the project is, and because of that, we have to set the dependency on its 
> compiled output, which makes debugging difficult.
> 
> 
> On Tue, Jul 23, 2013 at 7:15 PM, Adam Murdoch <adam.murd...@gradleware.com> 
> wrote:
> 
> On 23/07/2013, at 3:50 PM, Alex Ruiz <alr...@google.com> wrote:
> 
>> Another alternative that Xav and I were talking about later today is that, 
>> instead of having the single-pass multi-model resolution, we can just have a 
>> AndroidStudioModel.
>> 
>> The ToolModelBuilder for this model will do exactly what Studio is doing 
>> now: gets the IdeaProject and iterates through its children (IdeaModel), 
>> retrieving and AndroidModel if applicable.
>> 
>> The benefits for this alternative would be:
>> 
>> 1. We don't have to deal with multiple model hierarchies (e.g. GradleModel, 
>> IdeaProject which have a parent-child structure, and AndroidProject that 
>> does not know about this relationship)
>> 2. We wouldn't have to wait for Gradle 1.8 to do a single-pass multi-model 
>> resolution. We can use still use 1.6
>> 
>> I looked at the code and it looks like we can get the 
>> ToolModelBuilderRegistry (to get the IdeaProject and AndroidProject models) 
>> at any point as long we have a Project:
>> 
>> project.getServices().get(ToolingModelBuilderRegistry.class)
>> 
>> At the beginning Xav and I talked about having an IDE-agnostic model, but 
>> now it seems that having one (AndroidStudioModel) is not a bad idea :-)
>> 
>> If we decide that this is the way to go for now (we can revisit the idea of 
>> having the single-pass multi-model resolution in Gradle later on), the only 
>> change that we'll need is adding the method 'File getRootDir' to 
>> GradleProject (last item in my original e-mail.) This change seems pretty 
>> small and straightforward. Do you think it can be included in Gradle 1.7?
> 
> Possibly. What would you use it for?
> 
> 
>> 
>> Regards,
>> -Alex
>> 
>> 
>> On Mon, Jul 22, 2013 at 5:14 PM, Xavier Ducrohet <x...@google.com> wrote:
>> 
>> 
>> 
>> On Mon, Jul 22, 2013 at 4:34 PM, Adam Murdoch <adam.murd...@gradleware.com> 
>> wrote:
>> 
>> On 23/07/2013, at 5:53 AM, Alex Ruiz <alr...@google.com> wrote:
>> 
>>> x
>>> Greetings everyone,
>>> 
>>> We have, in Android Studio, a use case for retrieving multiple types of 
>>> model, in single pass, from a Gradle project using the Tooling API. The 
>>> following section explains the problem and the proposed solution. We 
>>> discussed this issue and the potential solution with Adam during Gradle 
>>> Summit back in June. Please let us know your thoughts. We plan to 
>>> contribute this change to Gradle.
>> 
>> That'd be great.
>> 
>>> 
>>> Thanks,
>>> -Alex 
>>> 
>>> Problem
>>> 
>>> Currently, importing a Gradle-based Android project takes a considerable 
>>> amount of time. The reason is that we have to make multiple calls to the 
>>> Gradle Tooling API. For a project with N Android sub-projects, we have to 
>>> make N+1 calls to Gradle. The reason is that an Android project may have a 
>>> mix of Android sub-projects and plain Java ones and we cannot get all the 
>>> Gradle models for such structure in one shot.
>>> 
>>> What we are doing now is asking for the IdeaProject at the top-level 
>>> project, then we iterate through the models of the returned IdeaProject 
>>> asking for the corresponding AndroidProject, if it doesn’t have it, we 
>>> assume is a Java project.
>>> 
>>> Solution
>>> 
>>> We are proposing is single-pass project import: a way to return all the 
>>> models we need, from the Tooling API, in one invocation:
>>> 
>>> ModelBuilder<GradleProject> builder =
>>>   connection.models(IdeaProject.class, AndroidProject.class);
>>> GradleProject project = builder.get();
>>> // ‘models’ will have instances of IdeaProject and AndroidProject.
>>> List<Object> models = project.getModels();
>>> for (GradleProject child : project.getChildren) {
>>>   // Each child will have its own models.
>>>   models = child.getModels();
>>> }
>> 
>> This is a good plan. There are a couple of things I would tweak - more on 
>> this below.
>> 
>>>  
>>> Changes to Gradle Tooling API
>>> 
>>> org.gradle.tooling.ProjectConnection:
>>> Add method ‘ModelBuilder<GradleProject> models(Class<?>...modelTypes)’. 
>>> This change will allow us to query multiple models type as shown above.
>> 
>> `GradleProject` currently bundles together a few things about a project - 
>> its place in the hierarchy, some identifying info, and the tasks of the 
>> project. This would mean that for every model query, we'd need to create and 
>> configure the tasks of each project. And this is something we'd like to 
>> avoid where possible. I think it would be better if the API did not imply 
>> anything about the tasks, and instead the tool can ask for them explicitly.
>>  
>> One solution would be to split up GradleProject into an interface that 
>> defines the structure and some basic information about each project, and 
>> into a separate model (or perhaps models) that provide additional, specific 
>> information about the project. You can then ask for this extra information 
>> as you would for any model of the project.
>> 
>> So the tasks would be part of another Model that is queried and returned as 
>> part of GradleProject#getModels()?
>>  
>> 
>> Another potential issue here is that there isn't necessarily a 1-1 
>> relationship between a Gradle project and an IDE project. There are many 
>> ways you might map a set of Gradle projects to a set of IDE projects. It 
>> just so happens that our IDE plugins current map each Gradle project to its 
>> own IDE project. But you might, for example, want to map the integration 
>> tests of each Gradle project to a separate `IntTest` IDE project. We want to 
>> allow the build some flexibility over how each Gradle project is mapped to 
>> the IDE, so we don't really want to bake a 1-1 mapping into the tooling API.
>> 
>> There are really several parallel hierarchies here - the set of Gradle 
>> projects, the set of IDEA modules + IDEA project, and the set of Eclipse 
>> projects. There is a relationship between a given Gradle project and IDEA 
>> module, and a given Gradle project and Eclipse project.
>> 
>> 
>> It seems like the issue with Integration test is always going to be a Gradle 
>> project becoming 2+ projects in the IDE and it's very specific to the 
>> plugin(s) that are applied in a project(*).
>> 
>> This means that the API of connection.models(IdeProject.class, 
>> AndroidProject.class) is probably still the right one. It just may mean that 
>> some GradleProject are present twice.
>> When you want to get the true Gradle project hierarchy, you can still do 
>> connection.getModel(GradleProject.class).
>> 
>> When calling models(), it's up to the Java plugin to return more than one 
>> project for a given Gradle project.
>> 
>> (*) I say plugins plural here because there could be a combination of plugin 
>> that changes the returned model maybe?
>> 
>> So I think there are 3 steps:
>> 
>> 1. Split GradleModel in 2+ models. The current one, minus the task, plus the 
>> model lists. And a new one for the tasks.
>> 2. Add the Connection.models() feature to the tooling API to get the model 
>> in a single pass, and possible more than one model per project (e.g. the 
>> tasks + the IDEA model for a Java project).
>> 3. Change the ToolingModelBuilder class to allow returning more than one 
>> GradleProject object from a single project
>> 
>> Is there a reason to return something different than GradleProject when 
>> querying the non actual hierarchy? The data from that interface is still 
>> relevant I think.
>> 
>> 
>> 
>>> 
>>> org.gradle.tooling.model.GradleProject:
>>> Add method ‘List<Object> getModels()’ to GradleProject. This change will 
>>> allows us to retrieve the models available from a project.
>> 
>> What would be the behaviour when a requested model is not available? It 
>> would be missing from the list?
>> 
>> I think the GradleProject would be present but its model list would be empty.
>> 
>> --
>> Adam Murdoch
>> Gradle Co-founder
>> http://www.gradle.org
>> VP of Engineering, Gradleware Inc. - Gradle Training, Support, Consulting
>> http://www.gradleware.com
>> 
>> 
>> 
>> 
>> 
> 
> 
> 
> --
> Adam Murdoch
> Gradle Co-founder
> http://www.gradle.org
> VP of Engineering, Gradleware Inc. - Gradle Training, Support, Consulting
> http://www.gradleware.com
> 
> 
> 
> 


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