mirror of
https://gitflic.ru/project/openide/openide.git
synced 2025-12-15 02:59:33 +07:00
IDEA-352824 Support Multiple Projects for Maven and Gradle
general refactoring: dropping "new workspace" import parameter running import sequentially after project opening (fix for maven import concurrency issues) setting first imported project jdk GitOrigin-RevId: 82a8e6b86eff3fdf98dbfdc94693cedfad0000c6
This commit is contained in:
committed by
intellij-monorepo-bot
parent
675ab4a296
commit
3048214973
@@ -688,7 +688,7 @@ com.intellij.ide.workspace.ImportedProjectSettings
|
||||
- a:canImportFromFile(com.intellij.openapi.vfs.VirtualFile):Z
|
||||
- a:getSubprojectIcon():javax.swing.Icon
|
||||
- a:getSubprojects(com.intellij.openapi.project.Project):java.util.List
|
||||
- a:importFromProject(com.intellij.openapi.project.Project,Z):com.intellij.ide.workspace.ImportedProjectSettings
|
||||
- a:importFromProject(com.intellij.openapi.project.Project):com.intellij.ide.workspace.ImportedProjectSettings
|
||||
- a:removeSubprojects(java.util.List):V
|
||||
- suppressGenericImportFor(com.intellij.openapi.module.Module):Z
|
||||
*f:com.intellij.ide.workspace.SubprojectHandler$Companion
|
||||
@@ -696,7 +696,7 @@ com.intellij.ide.workspace.ImportedProjectSettings
|
||||
- f:getEP_NAME():com.intellij.openapi.extensions.ExtensionPointName
|
||||
com.intellij.ide.workspace.WorkspaceSettingsImporter
|
||||
- sf:Companion:com.intellij.ide.workspace.WorkspaceSettingsImporter$Companion
|
||||
- a:importFromProject(com.intellij.openapi.project.Project,Z):com.intellij.ide.workspace.ImportedProjectSettings
|
||||
- a:importFromProject(com.intellij.openapi.project.Project):com.intellij.ide.workspace.ImportedProjectSettings
|
||||
f:com.intellij.ide.workspace.WorkspaceSettingsImporter$Companion
|
||||
- f:getEP_NAME():com.intellij.openapi.extensions.ExtensionPointName
|
||||
f:com.intellij.navigation.NavigationItemFileStatus
|
||||
|
||||
@@ -18,7 +18,7 @@ interface SubprojectHandler {
|
||||
fun getSubprojects(project: Project): List<Subproject>
|
||||
fun canImportFromFile(file: VirtualFile): Boolean
|
||||
fun removeSubprojects(subprojects: List<Subproject>)
|
||||
fun importFromProject(project: Project, newWorkspace: Boolean): ImportedProjectSettings?
|
||||
fun importFromProject(project: Project): ImportedProjectSettings?
|
||||
|
||||
fun suppressGenericImportFor(module: Module): Boolean = false
|
||||
|
||||
@@ -30,7 +30,7 @@ interface WorkspaceSettingsImporter {
|
||||
val EP_NAME: ExtensionPointName<WorkspaceSettingsImporter> = ExtensionPointName.create("com.intellij.workspace.settingsImporter")
|
||||
}
|
||||
|
||||
fun importFromProject(project: Project, newWorkspace: Boolean): ImportedProjectSettings?
|
||||
fun importFromProject(project: Project): ImportedProjectSettings?
|
||||
}
|
||||
|
||||
interface ImportedProjectSettings {
|
||||
|
||||
@@ -5,6 +5,7 @@ import com.intellij.ide.impl.OpenProjectTask
|
||||
import com.intellij.ide.impl.TrustedPaths
|
||||
import com.intellij.openapi.actionSystem.ActionUpdateThread
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.application.EDT
|
||||
import com.intellij.openapi.components.ComponentManagerEx
|
||||
import com.intellij.openapi.progress.blockingContext
|
||||
@@ -13,9 +14,13 @@ import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.project.ProjectManager
|
||||
import com.intellij.openapi.project.ex.ProjectManagerEx
|
||||
import com.intellij.openapi.project.impl.ProjectManagerImpl
|
||||
import com.intellij.openapi.startup.StartupManager
|
||||
import com.intellij.util.concurrency.annotations.RequiresEdt
|
||||
import com.intellij.util.containers.addIfNotNull
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.cancelAndJoin
|
||||
import kotlinx.coroutines.job
|
||||
import kotlinx.coroutines.withContext
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.Path
|
||||
|
||||
@@ -38,33 +43,30 @@ internal open class CreateWorkspaceAction: BaseWorkspaceAction(false) {
|
||||
}
|
||||
|
||||
@RequiresEdt
|
||||
internal fun createWorkspace(project: Project): Boolean {
|
||||
internal fun createWorkspace(project: Project) {
|
||||
val subprojects = SubprojectHandler.getAllSubprojects(project).associateBy { it.projectPath }
|
||||
val dialog = NewWorkspaceDialog(project, subprojects.values, true)
|
||||
if (!dialog.showAndGet()) return false
|
||||
if (!dialog.showAndGet()) return
|
||||
|
||||
val settings = importSettingsFromProject(project, true)
|
||||
getCoroutineScope(project).launch {
|
||||
createAndOpenWorkspaceProject(project, dialog.projectPath, dialog.projectName) { workspace ->
|
||||
for (importedSetting in settings) {
|
||||
importedSetting.applyTo(workspace)
|
||||
}
|
||||
dialog.projectPaths.forEach { linkToWorkspace(workspace, it) }
|
||||
ApplicationManager.getApplication().executeOnPooledThread {
|
||||
val workspace = createAndOpenWorkspaceProject(project, dialog.projectPath, dialog.projectName)
|
||||
?: return@executeOnPooledThread
|
||||
StartupManager.getInstance(workspace).runAfterOpened {
|
||||
addToWorkspace(workspace, dialog.projectPaths)
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
private fun importSettingsFromProject(project: Project, newWorkspace: Boolean): List<ImportedProjectSettings> {
|
||||
private fun importSettingsFromProject(project: Project): List<ImportedProjectSettings> {
|
||||
val settings = mutableListOf<ImportedProjectSettings>()
|
||||
val handlers = SubprojectHandler.EP_NAME.extensionList
|
||||
for (handler in handlers) {
|
||||
settings.addIfNotNull(handler.importFromProject(project, newWorkspace))
|
||||
settings.addIfNotNull(handler.importFromProject(project))
|
||||
}
|
||||
|
||||
val importers = WorkspaceSettingsImporter.EP_NAME.extensionList
|
||||
for (importer in importers) {
|
||||
settings.addIfNotNull(importer.importFromProject(project, newWorkspace))
|
||||
settings.addIfNotNull(importer.importFromProject(project))
|
||||
}
|
||||
return settings
|
||||
}
|
||||
@@ -73,7 +75,7 @@ internal suspend fun linkToWorkspace(workspace: Project, projectPath: String) {
|
||||
val projectManagerImpl = blockingContext { ProjectManager.getInstance() as ProjectManagerImpl }
|
||||
val referentProject = blockingContext { projectManagerImpl.loadProject(Path.of(projectPath), false, false) }
|
||||
try {
|
||||
val settings = importSettingsFromProject(referentProject, false)
|
||||
val settings = importSettingsFromProject(referentProject)
|
||||
for (importedSettings in settings) {
|
||||
importedSettings.applyTo(workspace)
|
||||
}
|
||||
@@ -88,8 +90,7 @@ internal suspend fun linkToWorkspace(workspace: Project, projectPath: String) {
|
||||
|
||||
private fun createAndOpenWorkspaceProject(project: Project,
|
||||
workspacePath: Path,
|
||||
projectName: String?,
|
||||
initTask: suspend (workspace: Project) -> Unit) {
|
||||
projectName: String): Project? {
|
||||
val options = OpenProjectTask {
|
||||
projectToClose = project
|
||||
this.projectName = projectName
|
||||
@@ -99,11 +100,10 @@ private fun createAndOpenWorkspaceProject(project: Project,
|
||||
isRefreshVfsNeeded = true
|
||||
beforeOpen = { workspace ->
|
||||
setWorkspace(workspace)
|
||||
initTask(workspace)
|
||||
true
|
||||
}
|
||||
}
|
||||
Files.createDirectories(workspacePath)
|
||||
TrustedPaths.getInstance().setProjectPathTrusted(workspacePath, true)
|
||||
ProjectManagerEx.getInstanceEx().openProject(workspacePath, options)
|
||||
return ProjectManagerEx.getInstanceEx().openProject(workspacePath, options)
|
||||
}
|
||||
@@ -7,13 +7,8 @@ import com.intellij.openapi.projectRoots.Sdk
|
||||
import com.intellij.openapi.roots.ProjectRootManager
|
||||
|
||||
internal class DefaultWorkspaceSettingsImporter : WorkspaceSettingsImporter {
|
||||
override fun importFromProject(project: Project, newWorkspace: Boolean): ImportedProjectSettings? {
|
||||
if (newWorkspace) {
|
||||
return DefaultImportedProjectSettings(project)
|
||||
}
|
||||
else {
|
||||
return null
|
||||
}
|
||||
override fun importFromProject(project: Project): ImportedProjectSettings {
|
||||
return DefaultImportedProjectSettings(project)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,7 +25,7 @@ private class DefaultImportedProjectSettings(project: Project) : ImportedProject
|
||||
}
|
||||
|
||||
override suspend fun applyTo(workspace: Project) {
|
||||
if (projectSdk != null) {
|
||||
if (projectSdk != null && ProjectRootManager.getInstance(workspace).projectSdk == null) {
|
||||
writeAction {
|
||||
ProjectRootManager.getInstance(workspace).projectSdk = projectSdk
|
||||
}
|
||||
|
||||
@@ -11,15 +11,13 @@ import kotlin.io.path.pathString
|
||||
|
||||
internal class WorkspaceAttachProcessor : ProjectAttachProcessor() {
|
||||
override fun attachToProject(project: Project, projectDir: Path, callback: ProjectOpenedCallback?): Boolean {
|
||||
if (project.isWorkspace) {
|
||||
getCoroutineScope(project).launch {
|
||||
linkToWorkspace(project, projectDir.pathString)
|
||||
}
|
||||
return true
|
||||
if (!project.isWorkspace) {
|
||||
return false
|
||||
}
|
||||
else {
|
||||
return createWorkspace(project)
|
||||
getCoroutineScope(project).launch {
|
||||
linkToWorkspace(project, projectDir.pathString)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
override fun isEnabled(project: Project?, path: Path?): Boolean =
|
||||
|
||||
@@ -19,10 +19,10 @@ internal fun getCoroutineScope(workspace: Project) = workspace.service<MyCorouti
|
||||
internal fun getHandlers(file: VirtualFile): List<SubprojectHandler> =
|
||||
SubprojectHandler.EP_NAME.extensionList.filter { it.canImportFromFile(file) }
|
||||
|
||||
internal fun addToWorkspace(project: Project, projectPaths: List<String>) {
|
||||
getCoroutineScope(project).launch {
|
||||
internal fun addToWorkspace(workspace: Project, projectPaths: List<String>) {
|
||||
getCoroutineScope(workspace).launch {
|
||||
projectPaths.forEach { s ->
|
||||
linkToWorkspace(project, s)
|
||||
linkToWorkspace(workspace, s)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ internal class GradleSubprojectHandler : ExternalSubprojectHandler(GradleConstan
|
||||
return canOpenGradleProject(file)
|
||||
}
|
||||
|
||||
override fun importFromProject(project: Project, newWorkspace: Boolean): ImportedProjectSettings = GradleImportedProjectSettings(project)
|
||||
override fun importFromProject(project: Project): ImportedProjectSettings = GradleImportedProjectSettings(project)
|
||||
|
||||
override fun suppressGenericImportFor(module: Module): Boolean {
|
||||
return ExternalSystemModulePropertyManager.getInstance(module).getExternalSystemId() == GradleConstants.SYSTEM_ID.id
|
||||
|
||||
@@ -7,13 +7,10 @@ import com.intellij.ide.workspace.SubprojectHandler
|
||||
import com.intellij.openapi.module.Module
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.project.guessProjectDir
|
||||
import com.intellij.openapi.startup.StartupManager
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import icons.MavenIcons
|
||||
import kotlinx.coroutines.launch
|
||||
import org.jetbrains.idea.maven.project.MavenProject
|
||||
import org.jetbrains.idea.maven.project.MavenProjectsManager
|
||||
import org.jetbrains.idea.maven.utils.MavenCoroutineScopeProvider
|
||||
import org.jetbrains.idea.maven.utils.MavenUtil
|
||||
import org.jetbrains.idea.maven.wizards.MavenOpenProjectProvider
|
||||
import javax.swing.Icon
|
||||
@@ -34,7 +31,7 @@ internal class MavenSubprojectHandler : SubprojectHandler {
|
||||
MavenProjectsManager.getInstance(workspace).removeManagedFiles(files, null, null)
|
||||
}
|
||||
|
||||
override fun importFromProject(project: Project, newWorkspace: Boolean): ImportedProjectSettings {
|
||||
override fun importFromProject(project: Project): ImportedProjectSettings {
|
||||
// FIXME: does not work for new project: AbstractMavenModuleBuilder creates project in 'MavenUtil.runWhenInitialized' callback
|
||||
return MavenImportedProjectSettings(project)
|
||||
}
|
||||
@@ -48,16 +45,12 @@ internal class MavenSubprojectHandler : SubprojectHandler {
|
||||
}
|
||||
|
||||
private class MavenImportedProjectSettings(project: Project) : ImportedProjectSettings {
|
||||
val projectDir = project.guessProjectDir()
|
||||
val projectDir = requireNotNull(project.guessProjectDir())
|
||||
|
||||
override suspend fun applyTo(workspace: Project) {
|
||||
val openProjectProvider = MavenOpenProjectProvider()
|
||||
if (openProjectProvider.canOpenProject(projectDir!!)) {
|
||||
StartupManager.getInstance(workspace).runAfterOpened {
|
||||
MavenCoroutineScopeProvider.getCoroutineScope(workspace).launch {
|
||||
openProjectProvider.forceLinkToExistingProjectAsync(projectDir, workspace)
|
||||
}
|
||||
}
|
||||
if (openProjectProvider.canOpenProject(projectDir)) {
|
||||
openProjectProvider.forceLinkToExistingProjectAsync(projectDir, workspace)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user