IJPL-156336 Allow ProjectBuilders to configure a project when it's attached as module

GitOrigin-RevId: 5e70b4d732b6d6dfffbad2fda18369ca2b71ddaf
This commit is contained in:
Dmitry Avdeev
2024-06-10 11:43:19 +02:00
committed by intellij-monorepo-bot
parent 673383c3da
commit aad9ec0741
12 changed files with 87 additions and 15 deletions

View File

@@ -10,7 +10,6 @@ import com.intellij.ide.impl.ProjectUtil.isSameProject
import com.intellij.ide.impl.ProjectUtil.updateLastProjectLocation
import com.intellij.ide.projectWizard.NewProjectWizardCollector
import com.intellij.ide.util.newProjectWizard.AbstractProjectWizard
import com.intellij.internal.statistic.service.fus.collectors.FUCounterUsageLogger
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.application.ModalityState
import com.intellij.openapi.command.CommandProcessor
@@ -33,6 +32,7 @@ import com.intellij.openapi.vfs.VfsUtilCore
import com.intellij.openapi.wm.ToolWindowId
import com.intellij.openapi.wm.ToolWindowManager
import com.intellij.platform.ide.progress.ModalTaskOwner
import com.intellij.projectImport.ProjectOpenedCallback
import com.intellij.ui.AppUIUtil
import com.intellij.ui.IdeUICustomization
import com.intellij.util.TimeoutUtil
@@ -172,15 +172,20 @@ object NewProjectUtil {
if (newProject !== projectToClose) {
updateLastProjectLocation(projectFile)
var options = build().withProject(newProject)
val fileName = projectFile.fileName
if (fileName != null) {
options = options.withProjectName(fileName.toString())
val moduleConfigurator = projectBuilder.createModuleConfigurator()
val options = OpenProjectTask {
project = newProject
projectName = projectFile.fileName.toString()
callback = ProjectOpenedCallback { _, module ->
ApplicationManager.getApplication().invokeLater {
moduleConfigurator?.accept(module)
}
}
}
TrustedPaths.getInstance().setProjectPathTrusted(projectDir, true)
runBlockingModalWithRawProgressReporter(
owner = ModalTaskOwner.guess(),
title = IdeUICustomization.getInstance().projectMessage("progress.title.project.loading.name", fileName.toString()),
title = IdeUICustomization.getInstance().projectMessage("progress.title.project.loading.name", options.projectName),
) {
ProjectManagerEx.getInstanceEx().openProjectAsync(projectStoreBaseDir = projectDir, options = options)
}

View File

@@ -309,6 +309,7 @@ a:com.intellij.ide.util.projectWizard.ProjectBuilder
- commit(com.intellij.openapi.project.Project):java.util.List
- commit(com.intellij.openapi.project.Project,com.intellij.openapi.module.ModifiableModuleModel):java.util.List
- a:commit(com.intellij.openapi.project.Project,com.intellij.openapi.module.ModifiableModuleModel,com.intellij.openapi.roots.ui.configuration.ModulesProvider):java.util.List
- createModuleConfigurator():java.util.function.Consumer
- createProject(java.lang.String,java.lang.String):com.intellij.openapi.project.Project
- isOpenProjectSettingsAfter():Z
- isSuitableSdkType(com.intellij.openapi.projectRoots.SdkTypeId):Z

View File

@@ -12,6 +12,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
import java.util.function.Consumer;
public abstract class ProjectBuilder {
public boolean isUpdate() {
@@ -45,4 +46,12 @@ public abstract class ProjectBuilder {
public @Nullable Project createProject(String name, String path) {
return ProjectManager.getInstance().createProject(name, path);
}
/**
* Configure project when it's added to workspace as module.
*/
@Nullable
public Consumer<Module> createModuleConfigurator() {
return null;
}
}

View File

@@ -19013,6 +19013,7 @@ f:com.intellij.ide.util.projectWizard.WebTemplateProjectWizardStep
- com.intellij.ide.wizard.AbstractNewProjectWizardStep
- com.intellij.ide.util.projectWizard.WebTemplateProjectWizardData
- <init>(com.intellij.ide.wizard.NewProjectWizardBaseStep,com.intellij.ide.util.projectWizard.WebProjectTemplate):V
- createModuleConfigurator():java.util.function.Consumer
- f:getParent():com.intellij.ide.wizard.NewProjectWizardBaseStep
- getPeer():com.intellij.openapi.util.NotNullLazyValue
- f:getTemplate():com.intellij.ide.util.projectWizard.WebProjectTemplate
@@ -20835,6 +20836,7 @@ c:com.intellij.openapi.module.WebModuleBuilder
- <init>(com.intellij.ide.util.projectWizard.WebProjectTemplate):V
- <init>(com.intellij.ide.util.projectWizard.WebProjectTemplate,com.intellij.openapi.util.NotNullLazyValue):V
- commitModule(com.intellij.openapi.project.Project,com.intellij.openapi.module.ModifiableModuleModel):com.intellij.openapi.module.Module
- createModuleConfigurator():java.util.function.Consumer
- getGroupName():java.lang.String
- getModuleType():com.intellij.openapi.module.ModuleType
- getNodeIcon():javax.swing.Icon

View File

@@ -3,6 +3,7 @@ package com.intellij.ide.util.projectWizard
import com.intellij.ide.wizard.AbstractNewProjectWizardStep
import com.intellij.ide.wizard.NewProjectWizardBaseStep
import com.intellij.openapi.module.Module
import com.intellij.openapi.module.WebModuleBuilder
import com.intellij.openapi.project.Project
import com.intellij.openapi.util.NotNullLazyValue
@@ -10,6 +11,7 @@ import com.intellij.platform.ProjectGeneratorPeer
import com.intellij.ui.JBColor
import com.intellij.ui.dsl.builder.AlignX
import com.intellij.ui.dsl.builder.Panel
import java.util.function.Consumer
import javax.swing.JLabel
class WebTemplateProjectWizardStep<T>(
@@ -39,13 +41,21 @@ class WebTemplateProjectWizardStep<T>(
}
override fun setupProject(project: Project) {
val builder = WebModuleBuilder(template, peer)
builder.moduleFilePath = "${parent.path}/${parent.name}"
builder.contentEntryPath = "${parent.path}/${parent.name}"
builder.name = parent.name
builder.commitModule(project, null)
webModuleBuilder().commitModule(project, null)
}
private fun webModuleBuilder(): WebModuleBuilder<T> {
return WebModuleBuilder(template, peer).apply {
moduleFilePath = "${parent.path}/${parent.name}"
contentEntryPath = "${parent.path}/${parent.name}"
name = parent.name
}
}
override fun createModuleConfigurator(): Consumer<Module>? {
return webModuleBuilder().createModuleConfigurator()
}
init {
data.putUserData(WebTemplateProjectWizardData.KEY, this)
}

View File

@@ -2,6 +2,7 @@
package com.intellij.ide.workspace
import com.intellij.lang.LangBundle
import com.intellij.openapi.module.ModuleManager
import com.intellij.openapi.project.Project
import com.intellij.project.stateStore
import com.intellij.projectImport.ProjectAttachProcessor
@@ -16,7 +17,13 @@ internal class WorkspaceAttachProcessor : ProjectAttachProcessor() {
return false
}
getCoroutineScope(project).launch {
val modules = ModuleManager.getInstance(project).modules.toSet()
linkToWorkspace(project, projectDir.pathString)
if (callback != null) {
ModuleManager.getInstance(project).modules.subtract(modules).firstOrNull()?.let {
module -> callback.projectOpened(project, module)
}
}
}
return true
}

View File

@@ -20,6 +20,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.util.function.Consumer;
/**
* @author Dmitry Avdeev
@@ -80,19 +81,30 @@ public class WebModuleBuilder<T> extends ModuleBuilder {
public @Nullable Module commitModule(@NotNull Project project, @Nullable ModifiableModuleModel model) {
Module module = super.commitModule(project, model);
if (module != null && myTemplate != null) {
doGenerate(myTemplate, module);
VirtualFile dir = getModuleDir(module);
myTemplate.generateProject(module.getProject(), dir, myGeneratorPeerLazyValue.getValue().getSettings(), module);
}
return module;
}
private void doGenerate(@NotNull WebProjectTemplate<T> template, @NotNull Module module) {
@Override
public @Nullable Consumer<Module> createModuleConfigurator() {
return module -> {
if (myTemplate != null) {
VirtualFile dir = getModuleDir(module);
myTemplate.configureModule(module, dir, myGeneratorPeerLazyValue.getValue().getSettings());
}
};
}
private static @NotNull VirtualFile getModuleDir(@NotNull Module module) {
ModuleRootManager moduleRootManager = ModuleRootManager.getInstance(module);
VirtualFile dir = ProjectUtil.guessModuleDir(module);
if (dir == null) {
dir = ArrayUtil.getFirstElement(moduleRootManager.getContentRoots());
}
assert dir != null : module.getProject();
template.generateProject(module.getProject(), dir, myGeneratorPeerLazyValue.getValue().getSettings(), module);
return dir;
}
@Override

View File

@@ -10576,6 +10576,7 @@ a:com.intellij.ide.wizard.AbstractNewProjectWizardBuilder
- <init>():V
- cleanup():V
- commitModule(com.intellij.openapi.project.Project,com.intellij.openapi.module.ModifiableModuleModel):com.intellij.openapi.module.Module
- createModuleConfigurator():java.util.function.Consumer
- pa:createStep(com.intellij.ide.util.projectWizard.WizardContext):com.intellij.ide.wizard.NewProjectWizardStep
- f:getCustomOptionsStep(com.intellij.ide.util.projectWizard.WizardContext,com.intellij.openapi.Disposable):com.intellij.ide.util.projectWizard.ModuleWizardStep
- getDescription():java.lang.String
@@ -10732,6 +10733,7 @@ f:com.intellij.ide.wizard.NewProjectWizardChainStep
- com.intellij.ide.wizard.AbstractNewProjectWizardStep
- sf:Companion:com.intellij.ide.wizard.NewProjectWizardChainStep$Companion
- <init>(com.intellij.ide.wizard.NewProjectWizardStep):V
- createModuleConfigurator():java.util.function.Consumer
- f:nextStep(kotlin.jvm.functions.Function1):com.intellij.ide.wizard.NewProjectWizardChainStep
- setupProject(com.intellij.openapi.project.Project):V
- setupUI(com.intellij.ui.dsl.builder.Panel):V
@@ -10768,6 +10770,7 @@ com.intellij.ide.wizard.NewProjectWizardStep
- sf:GENERATE_ONBOARDING_TIPS_NAME:java.lang.String
- sf:GIT_PROPERTY_NAME:java.lang.String
- sf:GROUP_ID_PROPERTY_NAME:java.lang.String
- createModuleConfigurator():java.util.function.Consumer
- a:getContext():com.intellij.ide.util.projectWizard.WizardContext
- a:getData():com.intellij.openapi.util.UserDataHolder
- a:getKeywords():com.intellij.ide.wizard.NewProjectWizardStep$Keywords
@@ -23270,6 +23273,7 @@ a:com.intellij.platform.DirectoryProjectConfigurator$AsyncDirectoryProjectConfig
- f:configureProject(com.intellij.openapi.project.Project,com.intellij.openapi.vfs.VirtualFile,com.intellij.openapi.util.Ref,Z):V
- f:isEdtRequired():Z
com.intellij.platform.DirectoryProjectGenerator
- configureModule(com.intellij.openapi.module.Module,com.intellij.openapi.vfs.VirtualFile,java.lang.Object):V
- createLazyPeer():com.intellij.openapi.util.NotNullLazyValue
- createPeer():com.intellij.platform.ProjectGeneratorPeer
- a:generateProject(com.intellij.openapi.project.Project,com.intellij.openapi.vfs.VirtualFile,java.lang.Object,com.intellij.openapi.module.Module):V

View File

@@ -13,6 +13,7 @@ import com.intellij.openapi.module.ModuleManager
import com.intellij.openapi.module.ModuleType
import com.intellij.openapi.project.Project
import com.intellij.platform.backend.observation.trackActivityBlocking
import java.util.function.Consumer
import javax.swing.Icon
abstract class AbstractNewProjectWizardBuilder : ModuleBuilder() {
@@ -49,6 +50,10 @@ abstract class AbstractNewProjectWizardBuilder : ModuleBuilder() {
}
}
override fun createModuleConfigurator(): Consumer<Module>? {
return panel!!.step.createModuleConfigurator()
}
override fun cleanup() {
panel = null
}

View File

@@ -1,8 +1,10 @@
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.ide.wizard
import com.intellij.openapi.module.Module
import com.intellij.openapi.project.Project
import com.intellij.ui.dsl.builder.Panel
import java.util.function.Consumer
/**
@@ -45,6 +47,10 @@ class NewProjectWizardChainStep<S : NewProjectWizardStep> : AbstractNewProjectWi
}
}
override fun createModuleConfigurator(): Consumer<Module>? {
return steps.firstNotNullOfOrNull { it.createModuleConfigurator() }
}
companion object {
fun <S : NewProjectWizardStep, NS : NewProjectWizardStep> S.nextStep(create: (S) -> NS): NewProjectWizardChainStep<NS> {

View File

@@ -3,11 +3,13 @@ package com.intellij.ide.wizard
import com.intellij.ide.util.projectWizard.WizardContext
import com.intellij.openapi.module.ModifiableModuleModel
import com.intellij.openapi.module.Module
import com.intellij.openapi.observable.properties.PropertyGraph
import com.intellij.openapi.project.Project
import com.intellij.openapi.util.Key
import com.intellij.openapi.util.UserDataHolder
import com.intellij.ui.dsl.builder.Panel
import java.util.function.Consumer
/**
* Defines vertical step in new project wizard. It is step which
@@ -84,6 +86,8 @@ interface NewProjectWizardStep {
*/
fun setupProject(project: Project) {}
fun createModuleConfigurator(): Consumer<Module>? = null
/**
* See related doc for [NewProjectWizardStep.keywords].
*/

View File

@@ -62,6 +62,13 @@ public interface DirectoryProjectGenerator<T> {
@NotNull T settings,
@NotNull Module module);
/**
* Configure project when it's added to workspace as module.
*/
default void configureModule(@NotNull Module module,
@NotNull VirtualFile baseDir,
@NotNull T settings) { }
@NotNull
ValidationResult validate(@NotNull String baseDirPath);
}