From 0819bde3684480c19ebf5d76903b819a307678fb Mon Sep 17 00:00:00 2001 From: Nikolay Chashnikov Date: Fri, 4 Sep 2020 22:51:44 +0300 Subject: [PATCH] [workspace model] support loading module groups (IDEA-250171) GitOrigin-RevId: 443a1fed3d6c6185b6e3af1c3084434827bfa24a --- .../module-in-group/.idea/modules.xml | 8 ++++++++ .../module-in-group/foo/foo.iml | 7 +++++++ .../configurationStore/LoadProjectTest.kt | 10 ++++++++++ .../configurationStore/SaveProjectTest.kt | 13 +++++++++++++ ...ExternalModuleImlFileEntitiesSerializer.kt | 4 ++-- .../serialization/JpsProjectEntitiesLoader.kt | 3 +-- .../JpsProjectSerializersImpl.kt | 12 ++++++------ .../ModuleImlFileEntitiesSerializer.kt | 19 +++++++++++-------- .../jpsFormatEntitiesSerialization.kt | 4 ++-- .../impl/jps/serialization/jpsTestUtils.kt | 2 +- 10 files changed, 61 insertions(+), 21 deletions(-) create mode 100644 java/java-tests/testData/configurationStore/module-in-group/.idea/modules.xml create mode 100644 java/java-tests/testData/configurationStore/module-in-group/foo/foo.iml diff --git a/java/java-tests/testData/configurationStore/module-in-group/.idea/modules.xml b/java/java-tests/testData/configurationStore/module-in-group/.idea/modules.xml new file mode 100644 index 000000000000..29c93685eefd --- /dev/null +++ b/java/java-tests/testData/configurationStore/module-in-group/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/java/java-tests/testData/configurationStore/module-in-group/foo/foo.iml b/java/java-tests/testData/configurationStore/module-in-group/foo/foo.iml new file mode 100644 index 000000000000..70ec6cce375a --- /dev/null +++ b/java/java-tests/testData/configurationStore/module-in-group/foo/foo.iml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/java/configurationStore/LoadProjectTest.kt b/java/java-tests/testSrc/com/intellij/java/configurationStore/LoadProjectTest.kt index 4e7a87d3216e..88e97ed58f3d 100644 --- a/java/java-tests/testSrc/com/intellij/java/configurationStore/LoadProjectTest.kt +++ b/java/java-tests/testSrc/com/intellij/java/configurationStore/LoadProjectTest.kt @@ -57,6 +57,16 @@ class LoadProjectTest : LoadProjectBase() { } } + @Test + fun `load module with group`() { + loadProjectAndCheckResults("module-in-group") { project -> + val module = ModuleManager.getInstance(project).modules.single() + assertThat(module.name).isEqualTo("foo") + assertThat(module.moduleTypeName).isEqualTo("EMPTY_MODULE") + assertThat(ModuleManager.getInstance(project).getModuleGroupPath(module)).containsExactly("group") + } + } + @Test fun `load detached module`() { loadProjectAndCheckResults("detached-module") { project -> diff --git a/java/java-tests/testSrc/com/intellij/java/configurationStore/SaveProjectTest.kt b/java/java-tests/testSrc/com/intellij/java/configurationStore/SaveProjectTest.kt index e422538f1294..82410410d0d8 100644 --- a/java/java-tests/testSrc/com/intellij/java/configurationStore/SaveProjectTest.kt +++ b/java/java-tests/testSrc/com/intellij/java/configurationStore/SaveProjectTest.kt @@ -43,6 +43,19 @@ class SaveProjectTest { projectModel.baseProjectDir.root.assertMatches(directoryContentOf(testDataRoot.resolve("single-module"))) } + @Test + fun `save module with group`() = runBlocking { + val module = projectModel.createModule("foo") + runWriteActionAndWait { + val model = projectModel.moduleManager.modifiableModel + model.setModuleGroupPath(module, arrayOf("group")) + model.commit() + } + + saveProjectState() + projectModel.baseProjectDir.root.assertMatches(directoryContentOf(testDataRoot.resolve("module-in-group"))) + } + @Test fun `save detached module`() = runBlocking { projectModel.createModule("foo") diff --git a/platform/workspaceModel/ide/src/com/intellij/workspaceModel/ide/impl/jps/serialization/ExternalModuleImlFileEntitiesSerializer.kt b/platform/workspaceModel/ide/src/com/intellij/workspaceModel/ide/impl/jps/serialization/ExternalModuleImlFileEntitiesSerializer.kt index d17f6bdf041c..0685f8b5475d 100644 --- a/platform/workspaceModel/ide/src/com/intellij/workspaceModel/ide/impl/jps/serialization/ExternalModuleImlFileEntitiesSerializer.kt +++ b/platform/workspaceModel/ide/src/com/intellij/workspaceModel/ide/impl/jps/serialization/ExternalModuleImlFileEntitiesSerializer.kt @@ -109,7 +109,7 @@ internal class ExternalModuleListSerializer(private val externalStorageRoot: Vir return "${entity.name}.xml" } - override fun createSerializer(internalSource: JpsFileEntitySource, fileUrl: VirtualFileUrl): JpsFileEntitiesSerializer { + override fun createSerializer(internalSource: JpsFileEntitySource, fileUrl: VirtualFileUrl, moduleGroup: String?): JpsFileEntitiesSerializer { val fileName = PathUtil.getFileName(fileUrl.url) val actualFileUrl = if (PathUtil.getFileExtension(fileName) == "iml") { externalStorageRoot.append("modules/${fileName.substringBeforeLast('.')}.xml") @@ -118,6 +118,6 @@ internal class ExternalModuleListSerializer(private val externalStorageRoot: Vir fileUrl } val filePath = JpsPathUtil.urlToPath(fileUrl.filePath) - return ExternalModuleImlFileEntitiesSerializer(ModulePath(filePath, null), actualFileUrl, internalSource) + return ExternalModuleImlFileEntitiesSerializer(ModulePath(filePath, moduleGroup), actualFileUrl, internalSource) } } \ No newline at end of file diff --git a/platform/workspaceModel/ide/src/com/intellij/workspaceModel/ide/impl/jps/serialization/JpsProjectEntitiesLoader.kt b/platform/workspaceModel/ide/src/com/intellij/workspaceModel/ide/impl/jps/serialization/JpsProjectEntitiesLoader.kt index 56f6b30fb82c..e06510536cfc 100644 --- a/platform/workspaceModel/ide/src/com/intellij/workspaceModel/ide/impl/jps/serialization/JpsProjectEntitiesLoader.kt +++ b/platform/workspaceModel/ide/src/com/intellij/workspaceModel/ide/impl/jps/serialization/JpsProjectEntitiesLoader.kt @@ -14,7 +14,6 @@ import com.intellij.workspaceModel.storage.* import com.intellij.workspaceModel.storage.bridgeEntities.LibraryTableId import org.jdom.Element import org.jetbrains.annotations.TestOnly -import java.io.File import java.nio.file.Path object JpsProjectEntitiesLoader { @@ -52,7 +51,7 @@ object JpsProjectEntitiesLoader { builder: WorkspaceEntityStorageBuilder, virtualFileManager: VirtualFileUrlManager) { val reader = CachingJpsFileContentReader(configLocation.baseDirectoryUrlString) - val serializer = ModuleListSerializerImpl.createModuleEntitiesSerializer(moduleFile.toVirtualFileUrl(virtualFileManager), source) + val serializer = ModuleListSerializerImpl.createModuleEntitiesSerializer(moduleFile.toVirtualFileUrl(virtualFileManager), null, source) serializer.loadEntities(builder, reader, virtualFileManager) } diff --git a/platform/workspaceModel/ide/src/com/intellij/workspaceModel/ide/impl/jps/serialization/JpsProjectSerializersImpl.kt b/platform/workspaceModel/ide/src/com/intellij/workspaceModel/ide/impl/jps/serialization/JpsProjectSerializersImpl.kt index 2c772acbd0d1..f0d4957af1d5 100644 --- a/platform/workspaceModel/ide/src/com/intellij/workspaceModel/ide/impl/jps/serialization/JpsProjectSerializersImpl.kt +++ b/platform/workspaceModel/ide/src/com/intellij/workspaceModel/ide/impl/jps/serialization/JpsProjectSerializersImpl.kt @@ -52,10 +52,10 @@ class JpsProjectSerializersImpl(directorySerializersFactories: List> = moduleSerializers.getKeysByValue(serializerFactory) ?: emptyList() val oldFileUrls = oldSerializers.mapTo(HashSet()) { it.fileUrl } - val newFileUrlsSet = newFileUrls.toSet() + val newFileUrlsSet = newFileUrls.mapTo(HashSet()) { it.first } val obsoleteSerializersForFactory = oldSerializers.filter { it.fileUrl !in newFileUrlsSet } obsoleteSerializersForFactory.forEach { moduleSerializers.remove(it, serializerFactory) } - val newFileSerializersForFactory = newFileUrls.filter { it !in oldFileUrls }.map { - serializerFactory.createSerializer(createFileInDirectorySource(it.parent!!, it.file!!.name), it) + val newFileSerializersForFactory = newFileUrls.filter { it.first !in oldFileUrls }.map { + serializerFactory.createSerializer(createFileInDirectorySource(it.first.parent!!, it.first.file!!.name), it.first, it.second) } newFileSerializersForFactory.associateWithTo(moduleSerializers) { serializerFactory } obsoleteSerializers.addAll(obsoleteSerializersForFactory) @@ -309,7 +309,7 @@ class JpsProjectSerializersImpl(directorySerializersFactories: List if (moduleListSerializer.entitySourceFilter(source)) { - val newSerializer = moduleListSerializer.createSerializer(internalSource, virtualFileManager.fromUrl(url)) + val newSerializer = moduleListSerializer.createSerializer(internalSource, virtualFileManager.fromUrl(url), null) fileSerializersByUrl.put(url, newSerializer) moduleSerializers[newSerializer] = moduleListSerializer affectedFileFactories.add(moduleListSerializer) diff --git a/platform/workspaceModel/ide/src/com/intellij/workspaceModel/ide/impl/jps/serialization/ModuleImlFileEntitiesSerializer.kt b/platform/workspaceModel/ide/src/com/intellij/workspaceModel/ide/impl/jps/serialization/ModuleImlFileEntitiesSerializer.kt index d7aac72e1b6e..e4be1747257a 100644 --- a/platform/workspaceModel/ide/src/com/intellij/workspaceModel/ide/impl/jps/serialization/ModuleImlFileEntitiesSerializer.kt +++ b/platform/workspaceModel/ide/src/com/intellij/workspaceModel/ide/impl/jps/serialization/ModuleImlFileEntitiesSerializer.kt @@ -8,7 +8,6 @@ import com.intellij.openapi.module.impl.ModulePath import com.intellij.openapi.project.ExternalStorageConfigurationManager import com.intellij.openapi.roots.ExternalProjectSystemRegistry import com.intellij.openapi.util.JDOMUtil -import com.intellij.openapi.vfs.VfsUtil import com.intellij.util.isEmpty import com.intellij.workspaceModel.ide.JpsFileEntitySource import com.intellij.workspaceModel.ide.JpsImportedEntitySource @@ -61,7 +60,7 @@ internal open class ModuleImlFileEntitiesSerializer(internal val modulePath: Mod val moduleEntity = loadModuleEntity(reader, builder, virtualFileManager) if (moduleEntity != null) createFacetSerializer().loadFacetEntities(builder, moduleEntity, reader) } else { - val externalSerializer = externalModuleListSerializer?.createSerializer(internalEntitySource, fileUrl) as ModuleImlFileEntitiesSerializer? + val externalSerializer = externalModuleListSerializer?.createSerializer(internalEntitySource, fileUrl, modulePath.group) as ModuleImlFileEntitiesSerializer? val moduleEntity = externalSerializer?.loadModuleEntity(reader, builder, virtualFileManager) ?: loadModuleEntity(reader, builder, virtualFileManager) if (moduleEntity != null) { @@ -83,6 +82,10 @@ internal open class ModuleImlFileEntitiesSerializer(internal val modulePath: Mod val (externalSystemOptions, externalSystemId) = readExternalSystemOptions(reader, moduleOptions) val entitySource = createEntitySource(externalSystemId) val moduleEntity = builder.addModuleEntity(modulePath.moduleName, listOf(ModuleDependencyItem.ModuleSourceDependency), entitySource) + val moduleGroup = modulePath.group + if (moduleGroup != null) { + builder.addModuleGroupPathEntity(moduleGroup.split('/'), moduleEntity, entitySource) + } val moduleType = moduleOptions["type"] if (moduleType != null) { @@ -560,10 +563,11 @@ internal open class ModuleListSerializerImpl(override val fileUrl: String, : JpsModuleListSerializer { companion object { internal fun createModuleEntitiesSerializer(fileUrl: VirtualFileUrl, + moduleGroup: String?, source: JpsFileEntitySource, externalModuleListSerializer: JpsModuleListSerializer? = null, externalStorageConfigurationManager: ExternalStorageConfigurationManager? = null) = - ModuleImlFileEntitiesSerializer(ModulePath(JpsPathUtil.urlToPath(fileUrl.filePath), null), fileUrl, source, + ModuleImlFileEntitiesSerializer(ModulePath(JpsPathUtil.urlToPath(fileUrl.filePath), moduleGroup), fileUrl, source, externalModuleListSerializer, externalStorageConfigurationManager) } @@ -581,15 +585,14 @@ internal open class ModuleListSerializerImpl(override val fileUrl: String, return "${entity.name}.iml" } - override fun createSerializer(internalSource: JpsFileEntitySource, fileUrl: VirtualFileUrl): JpsFileEntitiesSerializer { - return createModuleEntitiesSerializer(fileUrl, internalSource, externalModuleListSerializer, externalStorageConfigurationManager) + override fun createSerializer(internalSource: JpsFileEntitySource, fileUrl: VirtualFileUrl, moduleGroup: String?): JpsFileEntitiesSerializer { + return createModuleEntitiesSerializer(fileUrl, moduleGroup, internalSource, externalModuleListSerializer, externalStorageConfigurationManager) } - override fun loadFileList(reader: JpsFileContentReader, virtualFileManager: VirtualFileUrlManager): List { + override fun loadFileList(reader: JpsFileContentReader, virtualFileManager: VirtualFileUrlManager): List> { val moduleManagerTag = reader.loadComponent(fileUrl, componentName) ?: return emptyList() return ModuleManagerImpl.getPathsToModuleFiles(moduleManagerTag).map { - //todo load module groups - Paths.get(it.path).toVirtualFileUrl(virtualFileManager) + Paths.get(it.path).toVirtualFileUrl(virtualFileManager) to it.group } } diff --git a/platform/workspaceModel/ide/src/com/intellij/workspaceModel/ide/impl/jps/serialization/jpsFormatEntitiesSerialization.kt b/platform/workspaceModel/ide/src/com/intellij/workspaceModel/ide/impl/jps/serialization/jpsFormatEntitiesSerialization.kt index 3c19bc93000f..cb171c21cdb6 100644 --- a/platform/workspaceModel/ide/src/com/intellij/workspaceModel/ide/impl/jps/serialization/jpsFormatEntitiesSerialization.kt +++ b/platform/workspaceModel/ide/src/com/intellij/workspaceModel/ide/impl/jps/serialization/jpsFormatEntitiesSerialization.kt @@ -70,8 +70,8 @@ interface JpsModuleListSerializer { val entitySourceFilter: (EntitySource) -> Boolean get() = { true } - fun loadFileList(reader: JpsFileContentReader, virtualFileManager: VirtualFileUrlManager): List - fun createSerializer(internalSource: JpsFileEntitySource, fileUrl: VirtualFileUrl): JpsFileEntitiesSerializer + fun loadFileList(reader: JpsFileContentReader, virtualFileManager: VirtualFileUrlManager): List> + fun createSerializer(internalSource: JpsFileEntitySource, fileUrl: VirtualFileUrl, moduleGroup: String?): JpsFileEntitiesSerializer fun saveEntitiesList(entities: Sequence, writer: JpsFileContentWriter) fun getFileName(entity: ModuleEntity): String diff --git a/platform/workspaceModel/ide/tests/testSrc/com/intellij/workspaceModel/ide/impl/jps/serialization/jpsTestUtils.kt b/platform/workspaceModel/ide/tests/testSrc/com/intellij/workspaceModel/ide/impl/jps/serialization/jpsTestUtils.kt index 7845ea2de890..ae9e0d4899fe 100644 --- a/platform/workspaceModel/ide/tests/testSrc/com/intellij/workspaceModel/ide/impl/jps/serialization/jpsTestUtils.kt +++ b/platform/workspaceModel/ide/tests/testSrc/com/intellij/workspaceModel/ide/impl/jps/serialization/jpsTestUtils.kt @@ -184,7 +184,7 @@ fun JpsProjectSerializersImpl.checkConsistency(projectBaseDirUrl: String, storag assertEquals(url, fileSerializer.fileUrl) val fileSerializers = moduleSerializers.getKeysByValue(fileSerializer) ?: emptyList() val urlsFromFactory = fileSerializer.loadFileList(CachingJpsFileContentReader(projectBaseDirUrl), virtualFileManager) - assertEquals(urlsFromFactory.map { it.url }.sorted(), fileSerializers.map { getNonNullActualFileUrl(it.internalEntitySource) }.sorted()) + assertEquals(urlsFromFactory.map { it.first.url }.sorted(), fileSerializers.map { getNonNullActualFileUrl(it.internalEntitySource) }.sorted()) } fileSerializersByUrl.keys.associateWith { fileSerializersByUrl.getValues(it) }.forEach { (url, serializers) ->