How to (programatically) set the Scope of a Module's dependencies?

I'm struggling to do two things with the IntelliJ IDEA API:

 

1) Set the Scope of a Module's dependencies. My best attempt:

        Project project = event.getProject();
        ModuleManager moduleManager = ModuleManager.getInstance(project);
        Module[] allProjectModules = moduleManager.getModules();
        for (Module module : allProjectModules) {
            ModuleRootManager root = ModuleRootManager.getInstance(module);
            root.orderEntries().forEach(new Processor<OrderEntry>() {
                @Override
                public boolean process(OrderEntry orderEntry) {
                    // Do something here?
                    return false;
                }
            });
        }

 

2) Mark a module's directory as a "Sources Root". My best attempt:

        Project project = event.getProject();
        ModuleManager moduleManager = ModuleManager.getInstance(project);
        Module[] allProjectModules = moduleManager.getModules();
        for (Module module : allProjectModules) {
            ModuleRootManager root = ModuleRootManager.getInstance(module);
            for (VirtualFile file : root.getSourceRoots()) {
                if (file.getName().equals("desired Name")) {
                    // Do something here?
                }
            }
        }

 

Any help would be greatly appreciated.

0
5 comments

In order to modify module roots settings you need to use ModuleRootManager#getModifiableModel directly or via ModuleRootModificationUtil#updateModel.

1)

ModuleRootModificationUtil.updateModel(module, model -> {
for (OrderEntry entry : model.getOrderEntries()) {
if (entry instanceof ExportableOrderEntry && ...) {
((ExportableOrderEntry)entry).setScope(DependencyScope.TEST);
}
}
});

2) getSourceRoots() returns directories which are already marked as source roots. To add a new root, use ContentEntry#addSourceFolder. ContentEntry describes a content root, so if you need to add a source root which isn't added as a content root yet, use something like

ModuleRootModificationUtil.updateModel(module, model -> {
model.addContentEntry(dir).addSourceFolder(dir, JavaSourceRootType.SOURCE);
});

 

2

First code snippet is exactly what I was looking for, thanks!

For the second, how do I change an existing source folder? E.g., if I have a source folder that is marked as a "Test Sources Root", how can I simply mark it as a "Sources Root"?

0

Note: I tried just re-adding the source dir, like so:

            ModuleRootModificationUtil.updateModel(projectModule, model -> {
                for (VirtualFile sourceRoot : model.getSourceRoots()){
                    if (sourceRoot.getName().equals("tst")){
                        model.addContentEntry(sourceRoot).addSourceFolder(sourceRoot, JavaSourceRootType.SOURCE);
                    }
                }
            });

This seem to kind of work, but when I do this, the tst dir has the project name in brackets behind it, and it's not colored like it would be when manually setting in the editor.  E.g.,

MyProject
    > src
    > tst [MyProject]  test sources root

It is also showing up as "test sources root", rather than "sources root" (which is desired in my weird use case).

0

There is no way to change type of an existing source root. You need to remove it using ContentEntry#removeSourceFolder method, and then add a new one. Also if you already have a content root, you should find its ContentEntry using ModifiableRootModel#getContentEntries method, not add a new one. I.e. you can write something like

ModuleRootModificationUtil.updateModel(projectModule, model -> {
for (ContentEntry entry : model.getContentEntries()) {
for (SourceFolder sourceEntry : entry.getSourceFolders()){
if (sourceEntry.getFile().getName().equals("tst")){
entry.removeSourceFolder(sourceEntry);
entry.addSourceFolder(sourceEntry.getFile(), JavaSourceRootType.SOURCE);
}
}
}
});
2

This worked. Thank you very, very much.

0

Please sign in to leave a comment.