bazelbuild / intellij

IntelliJ plugin for Bazel projects
https://ij.bazel.build/
Apache License 2.0
761 stars 303 forks source link

How can I create multiple projects from a monorepo? #5754

Open ahmedyarub opened 10 months ago

ahmedyarub commented 10 months ago

So I have a huge Go monorepo and I use this plugin together with Goland. Since loading the whole monorepo is not feasible I have to keep on commenting and uncommenting lines from .bazelproject and resyncing to switch between "projects". For example this loads project a:

directories:
    src/a
    #src/b

Now if I want to switch to project b I'd have to do this and resync:

directories:
    #src/a
    src/b

Is there a better way? Btw I can contribute to this plugin so if this feature does not exist you might tell me how do you want to implement it in the plugin and I'll try to do it.

mai93 commented 10 months ago

IIUC it is advised to have multiple project view files each focusing on certain parts of the project and then you can use the one you need.

ahmedyarub commented 10 months ago

And how can I switch between them? There is only one .ijwb folder and I can't import or create more than one, right?

mai93 commented 10 months ago

That's right, I think you will need to reimport. I'm not sure if there is currently a way around resyncing to read the new contents of the project view.

ahmedyarub commented 10 months ago

That's right, I think you will need to reimport. I'm not sure if there is currently a way around resyncing to read the new contents of the project view.

So I'll need to delete the .ijwb folder and then reimport, right? I know how to add new features to the plugin so do you have any suggestion on implementing such feature in the plugin?

mai93 commented 10 months ago

There have been requests for supporting multiple instances opened from the same project with multiple .ijwb folders. In your case, you can then open different IDE windows each from a different project view and with a separate .ijwb folder. can this help with your problem?

cc @tpasternak do you have any objections to this extension?

ahmedyarub commented 10 months ago

I tried to create subfolders where each one of these has its own .ijwb folder but for some reason that didn't work. I could open the project but it couldn't find my code. The only way that I could get it to work is by having the .ijwb folder in the root folder. It looks like the workspace folder is hard-coded to be the direct parent of the .ijwb folder so we might consider adding the workspace folder somewhere to the project configuration for the plugin to find it.

tpasternak commented 9 months ago

@ahmedyarub not the best solution, but currently you can create two separate *.projectview files and import only one in the main project view. Then, switching would mean just changing the imported file path.

ahmedyarub commented 9 months ago

How does that work exactly? Are .projectview files .bazelproject files or something else? And if they are, should I be deleting the .ijwb every time that I import another project file? Can't we just have separate folders instead? os one folder that support multiple files? I can implement all of that but I just need to understand what works for you exactly.

tpasternak commented 9 months ago

You can have two projectview files anywhere you want. Let's name them "a.projectview" and "b.projectview". Then:

  1. open your main project view file (double-press shift and click "Open Project View File"
  2. add just a single line there `import /a.projectview
  3. click sync

when you want to switch it, just change the line to `import /b.projectview> and click "sync" again

ahmedyarub commented 9 months ago

Oh OK. What if I add the ability to have separate projects side by side (just like modules in IntelliJ) or a drop-down box where we can switch projects? Besides, syncing takes a looong time on my project. Is there a better alternative? Like caching the syncing results somewhere?

tpasternak commented 9 months ago

I agree this would make sense, but sounds like a large feature to me

ahmedyarub commented 9 months ago

I'll check with the Jetbrains team on the best way to do it. I already have a team working with me which can implement such a feature.

ahmedyarub commented 9 months ago

So it looks like Jetbrains is still considering creating Go target to module mapping, which means that the feature might not be implementable now which brings up another question: why do we need to resync when we remove and add targets from the .bazelproject file if these have already been analyzed before? Can't the plugin recognize that these targets have already been analyzed and just show them with all the navigation data when we uncomment them from the .bazelproject file?

mai93 commented 8 months ago

Can't the plugin recognize that these targets have already been analyzed and just show them with all the navigation data when we uncomment them from the .bazelproject file?

I do not think the mechanism to make sure that the targets have not changed and hence does not require rebuild is available.

ahmedyarub commented 6 months ago

OK so I have a much better idea to implement such feature which would also enable remote-caching of the analysis data: I'll create cache.dat.gz hashed by the target path. Whenever you add a target to the current project it will look first for the cached analysis data for that path instead for the whole project and merge it into the current project data. This would be used as a fallback mechanism for when there is no cached data for the project. Instead, it would look for the cached data of each target and if it doesn't find these it would do a normal sync. Later I would cache these files remotely and they would be retrieved according to the targets of the current project.

ahmedyarub commented 6 months ago

How to enable multiple sub-projects 1- Add enable/disable flags to the targets of the project view files (this seems to be at least partially implemented but it lacks a GUI). 2- Upon enabling a target it would be first synchronized in NO_BUILD mode. If that fails then we use FULL_SYNC. 3- When a target is added or removed we just need to alter the project cache. 4- Add an interface for enabling and disabling target 5- Add a utility method for dumping all the targets with a default enabled or disabled