Skip to content

Consume version catalog for included gradle build module #3086

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

agolubev
Copy link

@agolubev agolubev commented Jun 6, 2025

CommonGradleProjectResolverExtension creates and fill IdeaProject/IdeaModule models with Gradle Sync data.
It attaches BuildScriptClasspathData.VERSION_CATALOGS to IdeaProject for regular projects. However, project with included builds there is module that may have it's own catalog. So it also needs to be consumed

Android Studio heavily rely on catalog data that is available after sync (parsing settings files is slow), so also need to have this additional chunk of data too
Relates to: https://b.corp.google.com/issues/391154478

@@ -238,6 +238,11 @@ public void populateModuleExtraModels(@NotNull IdeaModule gradleModule, @NotNull
ideModule.createChild(ProjectKeys.TEST, testData);
}
}

final VersionCatalogsModel versionCatalogsModel = resolverCtx.getRootModel(VersionCatalogsModel.class);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @agolubev,
I think the idea of putting the VersionCatalogsModel into the ModuleData makes sense. Currently, VersionCatalogsModel is specified only in ProjectData and contains version catalogs of the "root" build. If you have a Module, you could access the version catalogs of the "root" build as it is implemented in VersionCatalogsLocator#getVersionCatalogsForModule. However, if the "root" build is composite, and the Module for which we want to get its version catalogs is included build, this approach is erroneous. Because an included build has its own version catalogs.

Considering that, it seems more logical to get VersionCatalogsModel from ModuleData, instead of ProjectData (as you suggest). But most probably, the exact implementation you are suggesting would work the same way as accessing version catalogs from a root build, because resolverCtx.getRootModel(VersionCatalogsModel.class) is used here. Hence, each ModuleData would have the same VersionCatalogsModel as the "root" build. This seems to be working for a non-composite build, but not for an included build. For getting catalogs for the exact Gradle build, resolverCtx.getBuildModel should be used instead.

Summary

  • If it's not important for you to support composite builds, I would suggest using the existing implementation and getting the catalogs from ProjectData (see VersionCatalogsLocator#getVersionCatalogsForModule)
  • If you need a more robust solution supporting catalogs in composite builds, I am already working on it. I will come to you with updates anyway :)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • I'm thinking that Studio side is flexible here on where to put version catalog model available from sync.
    It's probably a good idea to put this infromation somewhere as Gradle model has it and Idea/Studio side should consume it as a usefull information.
  • My understanding is that gradle sync data has regular catalog object assigned to project and catalog for includedBuild module assigned to module. Maybe it makes sense to preserve the same ownership? But it's not strong opinion here.
  • Also I can imagine that owners of some big projects (like AndoridX) can report similar issue with catalog and composite build eventually to Studio.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • It's probably a good idea to put this infromation somewhere as Gradle model has it

What information do you mean? Version catalog model of a root build is already available in ProjectData and could be consumed by the Idea / Studio side. The only problem is with the version catalogs of an included build and the subprojects of an included build. This information is available in Gradle sync data, but is not put in ProjectData or ModuleData. Hence could not be consumed by Idea or Studio, but I am working on it.

My understanding is that gradle sync data has regular catalog object assigned to project and catalog for includedBuild module assigned to module. Maybe it makes sense to preserve the same ownership?

I assume this is about where to put the version catalog model. I also don't have a strong opinion here, so I will consult with my colleague who is experienced with this DataNode structure much better than me.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hence could not be consumed by Idea or Studio, but I am working on it.

Sounds good

@agolubev
Copy link
Author

Another thought: using getBuildModel is limited because it's slow as it parses files to produce DSL model. Sometime ago we start using sync data in GradleDslVersionCatalogHandler.getVersionCatalogFiles. Method is in use by different code hilighting helpers that can be called very often. Refactoring (like renaming something in build files) also uses this method, problem is that refactoring happens in EDT. So the general vector is now using sync data as much as possible as it is very cheap.

@nbir94
Copy link

nbir94 commented Jun 11, 2025

Another thought: using getBuildModel is limited because it's slow as it parses files to produce DSL model

Just in case, when I suggested using getBuildModel, I didn't mean the code that parses a file. I was talking about ProjectResolverContext#getBuildModel, which is about the data from Gradle.

So the general vector is now using sync data as much as possible as it is very cheap.

I agree with that point. That's why I also want to rely on this data to get the version catalog locations. Now, resolving a lot of PsiElements in build scripts in Groovy causes parsing files and producing the DSL model, for each element separately. Sounds expensive :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants