From fa02045c104ac2319b67d4b1116ede9a8c582dfd Mon Sep 17 00:00:00 2001 From: "Vladislav.Soroka" Date: Wed, 22 Jan 2014 16:49:46 +0400 Subject: [PATCH] External system: respect scopes for module level library dependencies --- .../external-system-impl.iml | 1 + .../manage/LibraryDependencyDataService.java | 42 ++++++++++++------- .../project/ExternalProjectServiceTest.groovy | 40 ++++++++++++++++++ 3 files changed, 68 insertions(+), 15 deletions(-) diff --git a/platform/external-system-impl/external-system-impl.iml b/platform/external-system-impl/external-system-impl.iml index 7743115c2571..6fce2f65a630 100644 --- a/platform/external-system-impl/external-system-impl.iml +++ b/platform/external-system-impl/external-system-impl.iml @@ -19,6 +19,7 @@ + diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/manage/LibraryDependencyDataService.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/manage/LibraryDependencyDataService.java index 05c1d727c87b..f8fc059b59b4 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/manage/LibraryDependencyDataService.java +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/manage/LibraryDependencyDataService.java @@ -125,7 +125,7 @@ public class LibraryDependencyDataService extends AbstractDependencyDataService< if (!libraryData.isUnresolved()) { Set paths = ContainerUtilRt.newHashSet(); for (String path : libraryData.getPaths(LibraryPathType.BINARY)) { - paths.add(ExternalSystemApiUtil.toCanonicalPath(path)); + paths.add(ExternalSystemApiUtil.toCanonicalPath(path) + dependencyData.getScope().name()); } moduleLibrariesToImport.put(paths, dependencyData); toImport.add(dependencyData); @@ -162,16 +162,19 @@ public class LibraryDependencyDataService extends AbstractDependencyDataService< @NotNull LibraryTable libraryTable, @NotNull Module module) { - for (LibraryDependencyData dependencyData : toImport) { - LibraryData libraryData = dependencyData.getTarget(); - String libraryName = libraryData.getInternalName(); + for (final LibraryDependencyData dependencyData : toImport) { + final LibraryData libraryData = dependencyData.getTarget(); + final String libraryName = libraryData.getInternalName(); switch (dependencyData.getLevel()) { case MODULE: - @SuppressWarnings("ConstantConditions") Library moduleLib = moduleLibraryTable.createLibrary(libraryName); - Library.ModifiableModel libModel = moduleLib.getModifiableModel(); + final Library moduleLib = moduleLibraryTable.createLibrary(libraryName); + final Library.ModifiableModel libModel = moduleLib.getModifiableModel(); try { Map> files = myLibraryManager.prepareLibraryFiles(libraryData); myLibraryManager.registerPaths(files, libModel, libraryName); + LibraryOrderEntry orderEntry = moduleRootModel.findLibraryOrderEntry(moduleLib); + assert orderEntry != null; + setLibraryScope(orderEntry, moduleLib, module, dependencyData); } finally { libModel.commit(); @@ -184,17 +187,24 @@ public class LibraryDependencyDataService extends AbstractDependencyDataService< continue; } LibraryOrderEntry orderEntry = moduleRootModel.addLibraryEntry(projectLib); - LOG.info(String.format("Adding library dependency '%s' to module '%s'", projectLib.getName(), module.getName())); - orderEntry.setExported(dependencyData.isExported()); - orderEntry.setScope(dependencyData.getScope()); - LOG.info(String.format( - "Configuring library dependency '%s' of module '%s' to be%s exported and have scope %s", - projectLib.getName(), module.getName(), dependencyData.isExported() ? " not" : "", dependencyData.getScope() - )); + setLibraryScope(orderEntry, projectLib, module, dependencyData); } } } + private static void setLibraryScope(@NotNull LibraryOrderEntry orderEntry, + @NotNull Library lib, + @NotNull Module module, + @NotNull LibraryDependencyData dependencyData) { + LOG.info(String.format("Adding library dependency '%s' to module '%s'", lib.getName(), module.getName())); + orderEntry.setExported(dependencyData.isExported()); + orderEntry.setScope(dependencyData.getScope()); + LOG.info(String.format( + "Configuring library dependency '%s' of module '%s' to be%s exported and have scope %s", + lib.getName(), module.getName(), dependencyData.isExported() ? " not" : "", dependencyData.getScope() + )); + } + private static void filterUpToDateAndRemoveObsolete(@NotNull Map, LibraryDependencyData> moduleLibrariesToImport, @NotNull Map projectLibrariesToImport, @NotNull Set toImport, @@ -204,20 +214,22 @@ public class LibraryDependencyDataService extends AbstractDependencyDataService< Set moduleLibraryKey = ContainerUtilRt.newHashSet(); for (OrderEntry entry : moduleRootModel.getOrderEntries()) { if (entry instanceof ModuleLibraryOrderEntryImpl) { - Library library = ((ModuleLibraryOrderEntryImpl)entry).getLibrary(); + ModuleLibraryOrderEntryImpl moduleLibraryOrderEntry = (ModuleLibraryOrderEntryImpl)entry; + Library library = moduleLibraryOrderEntry.getLibrary(); if (library == null) { LOG.warn("Skipping module-level library entry because it doesn't have backing Library object. Entry: " + entry); continue; } moduleLibraryKey.clear(); for (VirtualFile file : library.getFiles(OrderRootType.CLASSES)) { - moduleLibraryKey.add(ExternalSystemApiUtil.getLocalFileSystemPath(file)); + moduleLibraryKey.add(ExternalSystemApiUtil.getLocalFileSystemPath(file) + moduleLibraryOrderEntry.getScope().name()); } LibraryDependencyData existing = moduleLibrariesToImport.remove(moduleLibraryKey); if (existing == null) { moduleRootModel.removeOrderEntry(entry); } else { + toImport.remove(existing); } } diff --git a/platform/external-system-impl/testSrc/com/intellij/openapi/externalSystem/service/project/ExternalProjectServiceTest.groovy b/platform/external-system-impl/testSrc/com/intellij/openapi/externalSystem/service/project/ExternalProjectServiceTest.groovy index cdbd81190895..60e4c1d10002 100644 --- a/platform/external-system-impl/testSrc/com/intellij/openapi/externalSystem/service/project/ExternalProjectServiceTest.groovy +++ b/platform/external-system-impl/testSrc/com/intellij/openapi/externalSystem/service/project/ExternalProjectServiceTest.groovy @@ -24,6 +24,7 @@ import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil import com.intellij.openapi.roots.LibraryOrderEntry import com.intellij.openapi.roots.ModuleSourceOrderEntry import com.intellij.openapi.roots.OrderEntry +import com.intellij.openapi.roots.OrderRootType import static com.intellij.openapi.externalSystem.model.project.ExternalSystemSourceType.* /** @@ -99,4 +100,43 @@ public class ExternalProjectServiceTest extends AbstractExternalSystemTest { } ExternalSystemTestUtil.assertMapsEqual(['source': 4, 'excluded': 2], folders) } + + void 'test library dependency with sources path added on subsequent refresh'() { + applyProjectState([ + buildExternalProjectInfo { + project { + module('module') { + lib('lib1', level: 'module', bin: ["bin_path"]) } } }, + buildExternalProjectInfo { + project { + module('module') { + lib('lib1', level: 'module', bin: ["bin_path"], src: ["source_path"]) } } } + ]) + + def helper = ServiceManager.getService(ProjectStructureHelper.class) + def module = helper.findIdeModule('module', project) + assertNotNull(module) + + def facade = ServiceManager.getService(PlatformFacade.class) + def entries = facade.getOrderEntries(module) + def dependencies = [:].withDefault { 0 } + entries.each { OrderEntry entry -> + if (entry instanceof LibraryOrderEntry) { + def name = (entry as LibraryOrderEntry).libraryName + dependencies[name]++ + if ("Test_external_system_id: lib1".equals(name)) { + def classesUrls = entry.getUrls(OrderRootType.CLASSES) + assertEquals(1, classesUrls.length) + assertTrue(classesUrls[0].endsWith("bin_path")) + def sourceUrls = entry.getUrls(OrderRootType.SOURCES) + assertEquals(1, sourceUrls.length) + assertTrue(sourceUrls[0].endsWith("source_path")) + } + else { + fail() + } + } + } + ExternalSystemTestUtil.assertMapsEqual(['Test_external_system_id: lib1': 1], dependencies) + } }