One IntelliJ project for each module in a multimodule build

I’m on a team that’s standardized on IntelliJ. We’re working on a legacy codebase with dozens of projects. There is no single “delivery” project; instead, many of the projects are libraries by other projects, and many of the projects are deliverables. No single project includes every other project (or even a majority of the projects) as its dependencies.

Due to the huge amount of code, we don’t have a single massive IntelliJ project. Instead, every module has its own project file that loads that module plus all its dependencies.

In case that wasn’t clear, here’s an example. Suppose our projects (modules) look like the following: A depends on no other projects B depends on A C depends on A D depends on B E depends on C

Each module would have a project file (IPR) loading the following: A: Just A B: A and B C: A and C D: A, B, and D E: A, C, and E

If I’m working on E, then I load E’s project file. I can see E and all its dependencies but not any of the projects I don’t care about.

As far as I can tell, with Gradle, the Idea plugin only supports generating a single massive IPR in the “master” directory which loads up every single module. Is there any way to generate the kind of structure that we use?

The IDEA plugin on its own isn’t flexible enough to accomplish what you want. For example, it will only create an IDEA project file for the build’s root project. What you can do though is to use tasks like GenerateIdeaProject and GenerateIdeaModule directly, without or alongside the plugin. This should allow you to solve your problem, even though it will probably take some effort.

Please also let the JetBrains folks know about your requirements for IDEA’s Gradle integration, which is currently being developed for IDEA 11.

I’ve looked at the IdeaPlugin source, and it doesn’t look like I can just copy bits of it into my own script. I’ll need to think about that some more …

Meanwhile, I posted on the IDEA feature request asking about this kind of support. The response I got is as follows: > I’m not sure about that. Basically, we make a call to gradle api against the project file you specify at the GUI. Have you tried to perform such ‘per-module import’?

We also need this kind of support for our projects. Our development is new code, but we have a similar structure. Several common modules that are used in multiple projects and several separate high-level projects.

In addition to the per-module IPR, we also need a single IPR that loads all modules (like the current plugin does). This is useful when making changes to a common module to see everywhere it’s used. For example when re-factoring a public API. (Public in that it’s used many places within our codebase, but not public external to the code base.)

Adding support to the idea plugin to do per module IPRs would be extremely beneficial!

Looking at the gradle idea plugin code it shouldn’t be hard to improve the plugin’s capabilities here.

Take a look at https://github.com/gradle/gradle/blob/master/subprojects/ide/src/main/groovy/org/gradle/plugins/ide/idea/IdeaPlugin.groovy around line 114. that’s where the isRoot check is done.

A nice extension would be to add 2 new fields to ideaPlugin. One is a simple boolean ‘perModuleIPR’, if true it generates an IPR for every module. The other field could be a list of project names. If the current project name is contained in the list of project names generate the IPR.

Can you elaborate on why you need this?

As I said in the post we have several common modules and multiple separate projects. What I should have added is each separate project is really a separately deployed application maintained by a different group of developers. We need per module & an all inclusive IPR to serve distinct users. FYI - Everything is in a single repository.

Some users need to load the all inclusive IPR because they make changes and refactorings to the common modules. They need an easy way to make sure all usages get updated. But the codebase is so large working in IJ against everything is slow.

Other users only develop specific applications. It’s much easier and faster for them to only load their own project (and dependent modules). It speeds everything up significantly and simplifies their working environment too.

In the end, I decided to ditch the built-in IPR generator - both for this issue and because the newer .idea project structure works much better than the older IPR file (it works much better in source control, and it supports dynamic reloads of project settings without fully reopening the project). It wasn’t too hard to write a simple task that would dump the list of dependent modules into .idea/modules.xml.

Do you still use the GenerateIdeaModule tasks to generate the module information?

Yes, I let the Idea plugin generate the iml files for me (though I heavily tweak both the model and the resulting XML).