[workspace model] skip project-level libraries with duplicating names (IDEA-249398)

It may happen that multiple Gradle projects are imported in parallel and they may add the same project-level library. We need to skip such duplicating entries before committing to avoid exceptions.

GitOrigin-RevId: 156ec2d12a3634cdb594dac21743f9722baf95f4
This commit is contained in:
Nikolay Chashnikov
2021-01-26 18:26:59 +00:00
committed by intellij-monorepo-bot
parent d73946984e
commit 56fd3bae51
2 changed files with 27 additions and 1 deletions
@@ -104,7 +104,16 @@ internal class ProjectModifiableLibraryTableBridgeImpl(
override fun prepareForCommit() {
assertModelIsLive()
modelIsCommittedOrDisposed = true
myAddedLibraries.forEach { library -> library.clearTargetBuilder() }
val storage = WorkspaceModel.getInstance(project).entityStorage.current
myAddedLibraries.forEach { library ->
if (storage.resolve(library.libraryId) != null) {
// it may happen that actual library table already has a library with such name (e.g. when multiple projects are imported in parallel)
// in such case we need to skip the new library to avoid exceptions.
diff.removeEntity(diff.libraryMap.getEntities(library).first())
Disposer.dispose(library)
}
library.clearTargetBuilder()
}
}
override fun getLibraryIterator(): Iterator<Library> = librariesArray.iterator()
@@ -1,12 +1,15 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.openapi.roots
import com.intellij.openapi.application.runWriteActionAndWait
import com.intellij.openapi.extensions.ExtensionPointName
import com.intellij.openapi.roots.impl.libraries.LibraryEx
import com.intellij.openapi.roots.libraries.CustomLibraryTableDescription
import com.intellij.openapi.roots.libraries.LibraryTable
import com.intellij.openapi.roots.libraries.LibraryTablesRegistrar
import org.assertj.core.api.Assertions
import org.junit.Before
import org.junit.Test
class ProjectLibraryTableTest : LibraryTableTestCase() {
override val libraryTable: LibraryTable
@@ -15,6 +18,20 @@ class ProjectLibraryTableTest : LibraryTableTestCase() {
override fun createLibrary(name: String, setup: (LibraryEx.ModifiableModelEx) -> Unit): LibraryEx {
return projectModel.addProjectLevelLibrary(name, setup)
}
@Test
fun `do not add library with existing name`() {
val a = createLibrary("a")
val model1 = libraryTable.modifiableModel
val b = createLibrary("b", model1)
val model2 = libraryTable.modifiableModel
createLibrary("b", model2)
runWriteActionAndWait {
model1.commit()
model2.commit()
}
Assertions.assertThat(libraryTable.libraries).containsExactlyInAnyOrder(a, b)
}
}
class ApplicationLibraryTableTest : LibraryTableTestCase() {