User: rednesto
Date: 06 Aug 24 19:05
Revision: 896f3b5228c24f6f2412b5084d0cdf8679da3fb2
Summary:
Extract creator template processing to a separate class
TeamCity URL: https://ci.mcdev.io/viewModification.html?tab=vcsModificationFiles&modId=9572&personal=false
Index: src/main/kotlin/creator/custom/CreatorTemplateProcessor.kt
===================================================================
--- src/main/kotlin/creator/custom/CreatorTemplateProcessor.kt (revision 896f3b5228c24f6f2412b5084d0cdf8679da3fb2)
+++ src/main/kotlin/creator/custom/CreatorTemplateProcessor.kt (revision 896f3b5228c24f6f2412b5084d0cdf8679da3fb2)
@@ -0,0 +1,355 @@
+/*
+ * Minecraft Development for IntelliJ
+ *
+ * https://mcdev.io/
+ *
+ * Copyright (C) 2024 minecraft-dev
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation, version 3.0 only.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see .
+ */
+
+package com.demonwav.mcdev.creator.custom
+
+import com.demonwav.mcdev.asset.MCDevBundle
+import com.demonwav.mcdev.asset.MCDevBundle.invoke
+import com.demonwav.mcdev.creator.custom.finalizers.CreatorFinalizer
+import com.demonwav.mcdev.creator.custom.providers.EmptyLoadedTemplate
+import com.demonwav.mcdev.creator.custom.providers.LoadedTemplate
+import com.demonwav.mcdev.creator.custom.types.CreatorProperty
+import com.demonwav.mcdev.creator.custom.types.CreatorPropertyFactory
+import com.demonwav.mcdev.creator.custom.types.ExternalCreatorProperty
+import com.demonwav.mcdev.util.toTypedArray
+import com.demonwav.mcdev.util.virtualFileOrError
+import com.intellij.codeInsight.CodeInsightSettings
+import com.intellij.codeInsight.actions.ReformatCodeProcessor
+import com.intellij.ide.projectView.ProjectView
+import com.intellij.ide.util.projectWizard.WizardContext
+import com.intellij.openapi.application.WriteAction
+import com.intellij.openapi.diagnostic.Attachment
+import com.intellij.openapi.diagnostic.ControlFlowException
+import com.intellij.openapi.diagnostic.thisLogger
+import com.intellij.openapi.fileEditor.FileEditorManager
+import com.intellij.openapi.module.ModuleManager
+import com.intellij.openapi.module.ModuleTypeId
+import com.intellij.openapi.observable.properties.GraphProperty
+import com.intellij.openapi.observable.properties.PropertyGraph
+import com.intellij.openapi.project.Project
+import com.intellij.openapi.roots.ModuleRootManager
+import com.intellij.openapi.ui.DialogPanel
+import com.intellij.openapi.vfs.LocalFileSystem
+import com.intellij.openapi.vfs.VirtualFile
+import com.intellij.openapi.vfs.refreshAndFindVirtualFile
+import com.intellij.psi.PsiManager
+import com.intellij.ui.JBColor
+import com.intellij.ui.dsl.builder.Panel
+import com.intellij.ui.dsl.builder.panel
+import com.intellij.util.application
+import java.nio.file.Path
+import java.util.function.Consumer
+import kotlin.collections.mapNotNull
+import kotlin.collections.orEmpty
+import kotlin.collections.set
+import kotlin.io.path.createDirectories
+import kotlin.io.path.writeText
+
+interface ExternalTemplatePropertyProvider {
+
+ val projectNameProperty: GraphProperty
+
+ val useGit: Boolean
+}
+
+/**
+ * Handles all the logic involved in making the creator UI and generating the project files.
+ */
+class CreatorTemplateProcessor(
+ propertyGraph: PropertyGraph,
+ wizardContext: WizardContext,
+ private val externalPropertyProvider: ExternalTemplatePropertyProvider
+) {
+
+ var hasTemplateErrors: Boolean = true
+ private set
+
+ private var properties: MutableMap> = mutableMapOf()
+ private var context: CreatorContext = CreatorContext(propertyGraph, properties, wizardContext)
+
+ fun createOptionsPanel(template: LoadedTemplate): DialogPanel? {
+ properties = mutableMapOf()
+ context = context.copy(properties = properties)
+
+ if (!template.isValid) {
+ return null
+ }
+
+ val projectNameProperty = externalPropertyProvider.projectNameProperty
+ properties["PROJECT_NAME"] = ExternalCreatorProperty(
+ context = context,
+ graphProperty = projectNameProperty,
+ valueType = String::class.java
+ )
+
+ return panel {
+ val reporter = TemplateValidationReporterImpl()
+ val uiFactories = setupTemplate(template, reporter)
+ if (uiFactories.isEmpty() && !reporter.hasErrors) {
+ row {
+ label(MCDevBundle("creator.ui.warn.no_properties"))
+ .component.foreground = JBColor.YELLOW
+ }
+ } else {
+ hasTemplateErrors = reporter.hasErrors
+ reporter.display(this)
+
+ if (!reporter.hasErrors) {
+ for (uiFactory in uiFactories) {
+ uiFactory.accept(this)
+ }
+ }
+ }
+ }
+ }
+
+ private fun setupTemplate(
+ template: LoadedTemplate,
+ reporter: TemplateValidationReporterImpl
+ ): List> {
+ return try {
+ val properties = template.descriptor.properties.orEmpty()
+ .mapNotNull {
+ reporter.subject = it.name
+ setupProperty(it, reporter)
+ }
+ .sortedBy { (_, order) -> order }
+ .map { it.first }
+
+ val finalizers = template.descriptor.finalizers
+ if (finalizers != null) {
+ CreatorFinalizer.validateAll(reporter, finalizers)
+ }
+
+ properties
+ } catch (t: Throwable) {
+ if (t is ControlFlowException) {
+ throw t
+ }
+
+ thisLogger().error(
+ "Unexpected error during template setup",
+ t,
+ template.label,
+ template.descriptor.toString()
+ )
+
+ emptyList()
+ } finally {
+ reporter.subject = null
+ }
+ }
+
+ private fun setupProperty(
+ descriptor: TemplatePropertyDescriptor,
+ reporter: TemplateValidationReporter
+ ): Pair, Int>? {
+ if (!descriptor.groupProperties.isNullOrEmpty()) {
+ val childrenUiFactories = descriptor.groupProperties
+ .mapNotNull { setupProperty(it, reporter) }
+ .sortedBy { (_, order) -> order }
+ .map { it.first }
+
+ val factory = Consumer { panel ->
+ val label = descriptor.translatedLabel
+ if (descriptor.collapsible == false) {
+ panel.group(label) {
+ for (childFactory in childrenUiFactories) {
+ childFactory.accept(this@group)
+ }
+ }
+ } else {
+ val group = panel.collapsibleGroup(label) {
+ for (childFactory in childrenUiFactories) {
+ childFactory.accept(this@collapsibleGroup)
+ }
+ }
+
+ group.expanded = descriptor.default as? Boolean ?: false
+ }
+ }
+
+ val order = descriptor.order ?: 0
+ return factory to order
+ }
+
+ if (descriptor.name in properties.keys) {
+ reporter.fatal("Duplicate property name ${descriptor.name}")
+ }
+
+ val prop = CreatorPropertyFactory.createFromType(descriptor.type, descriptor, context)
+ if (prop == null) {
+ reporter.fatal("Unknown template property type ${descriptor.type}")
+ }
+
+ prop.setupProperty(reporter)
+
+ properties[descriptor.name] = prop
+
+ if (descriptor.visible == false) {
+ return null
+ }
+
+ val factory = Consumer { panel -> prop.buildUi(panel) }
+ val order = descriptor.order ?: 0
+ return factory to order
+ }
+
+ fun generateFiles(project: Project, template: LoadedTemplate) {
+ if (template is EmptyLoadedTemplate) {
+ return
+ }
+
+ val projectPath = context.wizardContext.projectDirectory
+ val templateProperties = collectTemplateProperties()
+ thisLogger().debug("Template properties: $templateProperties")
+
+ val generatedFiles = mutableListOf>()
+ for (file in template.descriptor.files.orEmpty()) {
+ if (file.condition != null &&
+ !TemplateEvaluator.condition(templateProperties, file.condition).getOrElse { false }
+ ) {
+ continue
+ }
+
+ val relativeTemplate = TemplateEvaluator.template(templateProperties, file.template).getOrNull()
+ ?: continue
+ val relativeDest = TemplateEvaluator.template(templateProperties, file.destination).getOrNull()
+ ?: continue
+
+ try {
+ val templateContents = template.loadTemplateContents(relativeTemplate)
+ ?: continue
+
+ val destPath = projectPath.resolve(relativeDest).toAbsolutePath()
+ if (!destPath.startsWith(projectPath)) {
+ // We want to make sure template files aren't 'escaping' the project directory
+ continue
+ }
+
+ var fileTemplateProperties = templateProperties
+ if (file.properties != null) {
+ fileTemplateProperties = templateProperties.toMutableMap()
+ fileTemplateProperties.putAll(file.properties)
+ }
+
+ val processedContent = TemplateEvaluator.template(fileTemplateProperties, templateContents)
+ .onFailure { t ->
+ val attachment = Attachment(relativeTemplate, templateContents)
+ thisLogger().error("Failed evaluate template '$relativeTemplate'", t, attachment)
+ }
+ .getOrNull()
+ ?: continue
+
+ destPath.parent.createDirectories()
+ destPath.writeText(processedContent)
+
+ val virtualFile = destPath.refreshAndFindVirtualFile()
+ if (virtualFile != null) {
+ generatedFiles.add(file to virtualFile)
+ } else {
+ thisLogger().warn("Could not find VirtualFile for file generated at $destPath (descriptor: $file)")
+ }
+ } catch (t: Throwable) {
+ if (t is ControlFlowException) {
+ throw t
+ }
+
+ thisLogger().error("Failed to process template file $file", t)
+ }
+ }
+
+ val finalizeAction = {
+ WriteAction.runAndWait {
+ LocalFileSystem.getInstance().refresh(false)
+ // Apparently a module root is required for the reformat to work
+ setupTempRootModule(project, projectPath)
+
+ reformatFiles(project, generatedFiles)
+ openFilesInEditor(project, generatedFiles)
+ }
+
+ val finalizers = template.descriptor.finalizers
+ if (!finalizers.isNullOrEmpty()) {
+ CreatorFinalizer.executeAll(context.wizardContext, project, finalizers, templateProperties)
+ }
+ }
+ if (context.wizardContext.isCreatingNewProject) {
+ TemplateService.instance.registerFinalizerAction(project, finalizeAction)
+ } else {
+ application.executeOnPooledThread { finalizeAction() }
+ }
+ }
+
+ private fun setupTempRootModule(project: Project, projectPath: Path) {
+ val modifiableModel = ModuleManager.getInstance(project).getModifiableModel()
+ val module = modifiableModel.newNonPersistentModule("mcdev-temp-root", ModuleTypeId.JAVA_MODULE)
+ val rootsModel = ModuleRootManager.getInstance(module).modifiableModel
+ rootsModel.addContentEntry(projectPath.virtualFileOrError)
+ rootsModel.commit()
+ modifiableModel.commit()
+ }
+
+ private fun collectTemplateProperties(): MutableMap {
+ val into = mutableMapOf()
+
+ into.putAll(TemplateEvaluator.baseProperties)
+
+ into["USE_GIT"] = externalPropertyProvider.useGit
+
+ return properties.mapValuesTo(into) { (_, prop) -> prop.get() }
+ }
+
+ private fun reformatFiles(
+ project: Project,
+ files: MutableList>
+ ) {
+ val psiManager = PsiManager.getInstance(project)
+ val psiFiles = files.asSequence()
+ .filter { (desc, _) -> desc.reformat != false }
+ .mapNotNull { (_, file) -> psiManager.findFile(file) }
+
+ val processor = ReformatCodeProcessor(project, psiFiles.toTypedArray(), null, false)
+ psiFiles.forEach(processor::setDoNotKeepLineBreaks)
+
+ val insightSettings = CodeInsightSettings.getInstance()
+ val oldSecondReformat = insightSettings.ENABLE_SECOND_REFORMAT
+ insightSettings.ENABLE_SECOND_REFORMAT = true
+ try {
+ processor.run()
+ } finally {
+ insightSettings.ENABLE_SECOND_REFORMAT = oldSecondReformat
+ }
+ }
+
+ private fun openFilesInEditor(
+ project: Project,
+ files: MutableList>
+ ) {
+ val fileEditorManager = FileEditorManager.getInstance(project)
+ val projectView = ProjectView.getInstance(project)
+ for ((desc, file) in files) {
+ if (desc.openInEditor == true) {
+ fileEditorManager.openFile(file, true)
+ projectView.select(null, file, false)
+ }
+ }
+ }
+}
Index: src/main/kotlin/creator/custom/CustomPlatformStep.kt
===================================================================
--- src/main/kotlin/creator/custom/CustomPlatformStep.kt (revision fc65be86388514694b95348642ae00493b402eb6)
+++ src/main/kotlin/creator/custom/CustomPlatformStep.kt (revision 896f3b5228c24f6f2412b5084d0cdf8679da3fb2)
@@ -22,43 +22,23 @@
import com.demonwav.mcdev.MinecraftSettings
import com.demonwav.mcdev.asset.MCDevBundle
-import com.demonwav.mcdev.creator.custom.finalizers.CreatorFinalizer
import com.demonwav.mcdev.creator.custom.providers.EmptyLoadedTemplate
import com.demonwav.mcdev.creator.custom.providers.LoadedTemplate
import com.demonwav.mcdev.creator.custom.providers.TemplateProvider
-import com.demonwav.mcdev.creator.custom.types.CreatorProperty
-import com.demonwav.mcdev.creator.custom.types.CreatorPropertyFactory
-import com.demonwav.mcdev.creator.custom.types.ExternalCreatorProperty
import com.demonwav.mcdev.creator.modalityState
-import com.demonwav.mcdev.util.toTypedArray
-import com.demonwav.mcdev.util.virtualFileOrError
-import com.intellij.codeInsight.CodeInsightSettings
-import com.intellij.codeInsight.actions.ReformatCodeProcessor
-import com.intellij.ide.projectView.ProjectView
import com.intellij.ide.wizard.AbstractNewProjectWizardStep
import com.intellij.ide.wizard.GitNewProjectWizardData
import com.intellij.ide.wizard.NewProjectWizardBaseData
import com.intellij.ide.wizard.NewProjectWizardStep
-import com.intellij.openapi.application.WriteAction
-import com.intellij.openapi.diagnostic.Attachment
-import com.intellij.openapi.diagnostic.ControlFlowException
import com.intellij.openapi.diagnostic.getOrLogException
import com.intellij.openapi.diagnostic.logger
-import com.intellij.openapi.diagnostic.thisLogger
-import com.intellij.openapi.fileEditor.FileEditorManager
-import com.intellij.openapi.module.ModuleManager
-import com.intellij.openapi.module.ModuleTypeId
+import com.intellij.openapi.observable.properties.GraphProperty
import com.intellij.openapi.observable.util.transform
import com.intellij.openapi.progress.ProgressIndicator
import com.intellij.openapi.progress.ProgressManager
import com.intellij.openapi.progress.Task
import com.intellij.openapi.project.Project
-import com.intellij.openapi.roots.ModuleRootManager
-import com.intellij.openapi.vfs.LocalFileSystem
-import com.intellij.openapi.vfs.VirtualFile
import com.intellij.openapi.vfs.VirtualFileManager
-import com.intellij.openapi.vfs.refreshAndFindVirtualFile
-import com.intellij.psi.PsiManager
import com.intellij.ui.JBColor
import com.intellij.ui.dsl.builder.AlignX
import com.intellij.ui.dsl.builder.Cell
@@ -67,17 +47,11 @@
import com.intellij.ui.dsl.builder.SegmentedButton
import com.intellij.ui.dsl.builder.TopGap
import com.intellij.ui.dsl.builder.bindText
-import com.intellij.ui.dsl.builder.panel
import com.intellij.util.application
import com.intellij.util.ui.AsyncProcessIcon
-import java.nio.file.Path
-import java.util.function.Consumer
import javax.swing.JLabel
import kotlin.collections.component1
import kotlin.collections.component2
-import kotlin.collections.set
-import kotlin.io.path.createDirectories
-import kotlin.io.path.writeText
/**
* The step to select a custom template repo.
@@ -117,10 +91,15 @@
lateinit var noTemplatesAvailable: Cell
var templateLoadingIndicator: ProgressIndicator? = null
- private var hasTemplateErrors: Boolean = true
+ private val externalPropertyProvider = object : ExternalTemplatePropertyProvider {
+ override val projectNameProperty: GraphProperty
+ get() = data.getUserData(NewProjectWizardBaseData.KEY)?.nameProperty
+ ?: throw RuntimeException("Could not find wizard base data")
- private var properties = mutableMapOf>()
- private var creatorContext = CreatorContext(propertyGraph, properties, context)
+ override val useGit: Boolean
+ get() = data.getUserData(GitNewProjectWizardData.KEY)?.git == true
+ }
+ private val templateProcessor = CreatorTemplateProcessor(propertyGraph, context, externalPropertyProvider)
override fun setupUI(builder: Panel) {
lateinit var templatePropertyPlaceholder: Placeholder
@@ -166,7 +145,7 @@
segmentedButton(emptyList(), LoadedTemplate::label, LoadedTemplate::tooltip)
.bind(selectedTemplateProperty)
.validation {
- addApplyRule("", condition = ::hasTemplateErrors)
+ addApplyRule("", condition = templateProcessor::hasTemplateErrors)
}
}.visibleIf(
availableTemplatesProperty.transform { it.size > 1 }
@@ -191,7 +170,7 @@
}
selectedTemplateProperty.afterChange { template ->
- createOptionsPanelInBackground(template, templatePropertyPlaceholder)
+ templatePropertyPlaceholder.component = templateProcessor.createOptionsPanel(template)
}
builder.row {
@@ -310,276 +289,7 @@
ProgressManager.getInstance().runProcessWithProgressAsynchronously(task, indicator)
}
- private fun createOptionsPanelInBackground(template: LoadedTemplate, placeholder: Placeholder) {
- properties = mutableMapOf()
- creatorContext = creatorContext.copy(properties = properties)
-
- if (!template.isValid) {
- return
- }
-
- val baseData = data.getUserData(NewProjectWizardBaseData.KEY)
- ?: return thisLogger().error("Could not find wizard base data")
-
- properties["PROJECT_NAME"] = ExternalCreatorProperty(
- context = creatorContext,
- graphProperty = baseData.nameProperty,
- valueType = String::class.java
- )
-
- placeholder.component = panel {
- val reporter = TemplateValidationReporterImpl()
- val uiFactories = setupTemplate(template, reporter)
- if (uiFactories.isEmpty() && !reporter.hasErrors) {
- row {
- label(MCDevBundle("creator.ui.warn.no_properties"))
- .component.foreground = JBColor.YELLOW
- }
- } else {
- hasTemplateErrors = reporter.hasErrors
- reporter.display(this)
-
- if (!reporter.hasErrors) {
- for (uiFactory in uiFactories) {
- uiFactory.accept(this)
- }
- }
- }
- }
- }
-
- private fun setupTemplate(
- template: LoadedTemplate,
- reporter: TemplateValidationReporterImpl
- ): List> {
- return try {
- val properties = template.descriptor.properties.orEmpty()
- .mapNotNull {
- reporter.subject = it.name
- setupProperty(it, reporter)
- }
- .sortedBy { (_, order) -> order }
- .map { it.first }
-
- val finalizers = template.descriptor.finalizers
- if (finalizers != null) {
- CreatorFinalizer.validateAll(reporter, finalizers)
- }
-
- properties
- } catch (t: Throwable) {
- if (t is ControlFlowException) {
- throw t
- }
-
- thisLogger().error(
- "Unexpected error during template setup",
- t,
- template.label,
- template.descriptor.toString()
- )
-
- emptyList()
- } finally {
- reporter.subject = null
- }
- }
-
- private fun setupProperty(
- descriptor: TemplatePropertyDescriptor,
- reporter: TemplateValidationReporter
- ): Pair, Int>? {
- if (!descriptor.groupProperties.isNullOrEmpty()) {
- val childrenUiFactories = descriptor.groupProperties
- .mapNotNull { setupProperty(it, reporter) }
- .sortedBy { (_, order) -> order }
- .map { it.first }
-
- val factory = Consumer { panel ->
- val label = descriptor.translatedLabel
- if (descriptor.collapsible == false) {
- panel.group(label) {
- for (childFactory in childrenUiFactories) {
- childFactory.accept(this@group)
- }
- }
- } else {
- val group = panel.collapsibleGroup(label) {
- for (childFactory in childrenUiFactories) {
- childFactory.accept(this@collapsibleGroup)
- }
- }
-
- group.expanded = descriptor.default as? Boolean ?: false
- }
- }
-
- val order = descriptor.order ?: 0
- return factory to order
- }
-
- if (descriptor.name in properties.keys) {
- reporter.fatal("Duplicate property name ${descriptor.name}")
- }
-
- val prop = CreatorPropertyFactory.createFromType(descriptor.type, descriptor, creatorContext)
- if (prop == null) {
- reporter.fatal("Unknown template property type ${descriptor.type}")
- }
-
- prop.setupProperty(reporter)
-
- properties[descriptor.name] = prop
-
- if (descriptor.visible == false) {
- return null
- }
-
- val factory = Consumer { panel -> prop.buildUi(panel) }
- val order = descriptor.order ?: 0
- return factory to order
- }
-
override fun setupProject(project: Project) {
- val template = selectedTemplate
- if (template is EmptyLoadedTemplate) {
- return
+ templateProcessor.generateFiles(project, selectedTemplate)
- }
+ }
-
- val projectPath = context.projectDirectory
- val templateProperties = collectTemplateProperties()
- thisLogger().debug("Template properties: $templateProperties")
-
- val generatedFiles = mutableListOf>()
- for (file in template.descriptor.files.orEmpty()) {
- if (file.condition != null &&
- !TemplateEvaluator.condition(templateProperties, file.condition).getOrElse { false }
- ) {
- continue
- }
+}
-
- val relativeTemplate = TemplateEvaluator.template(templateProperties, file.template).getOrNull()
- ?: continue
- val relativeDest = TemplateEvaluator.template(templateProperties, file.destination).getOrNull()
- ?: continue
-
- try {
- val templateContents = template.loadTemplateContents(relativeTemplate)
- ?: continue
-
- val destPath = projectPath.resolve(relativeDest).toAbsolutePath()
- if (!destPath.startsWith(projectPath)) {
- // We want to make sure template files aren't 'escaping' the project directory
- continue
- }
-
- var fileTemplateProperties = templateProperties
- if (file.properties != null) {
- fileTemplateProperties = templateProperties.toMutableMap()
- fileTemplateProperties.putAll(file.properties)
- }
-
- val processedContent = TemplateEvaluator.template(fileTemplateProperties, templateContents)
- .onFailure { t ->
- val attachment = Attachment(relativeTemplate, templateContents)
- thisLogger().error("Failed evaluate template '$relativeTemplate'", t, attachment)
- }
- .getOrNull()
- ?: continue
-
- destPath.parent.createDirectories()
- destPath.writeText(processedContent)
-
- val virtualFile = destPath.refreshAndFindVirtualFile()
- if (virtualFile != null) {
- generatedFiles.add(file to virtualFile)
- } else {
- thisLogger().warn("Could not find VirtualFile for file generated at $destPath (descriptor: $file)")
- }
- } catch (t: Throwable) {
- if (t is ControlFlowException) {
- throw t
- }
-
- thisLogger().error("Failed to process template file $file", t)
- }
- }
-
- val finalizeAction = {
- WriteAction.runAndWait {
- LocalFileSystem.getInstance().refresh(false)
- // Apparently a module root is required for the reformat to work
- setupTempRootModule(project, projectPath)
-
- reformatFiles(project, generatedFiles)
- openFilesInEditor(project, generatedFiles)
- }
-
- val finalizers = selectedTemplate.descriptor.finalizers
- if (!finalizers.isNullOrEmpty()) {
- CreatorFinalizer.executeAll(context, project, finalizers, templateProperties)
- }
- }
- if (context.isCreatingNewProject) {
- TemplateService.instance.registerFinalizerAction(project, finalizeAction)
- } else {
- application.executeOnPooledThread { finalizeAction() }
- }
- }
-
- private fun setupTempRootModule(project: Project, projectPath: Path) {
- val modifiableModel = ModuleManager.getInstance(project).getModifiableModel()
- val module = modifiableModel.newNonPersistentModule("mcdev-temp-root", ModuleTypeId.JAVA_MODULE)
- val rootsModel = ModuleRootManager.getInstance(module).modifiableModel
- rootsModel.addContentEntry(projectPath.virtualFileOrError)
- rootsModel.commit()
- modifiableModel.commit()
- }
-
- private fun collectTemplateProperties(): MutableMap {
- val into = mutableMapOf()
-
- into.putAll(TemplateEvaluator.baseProperties)
-
- val gitData = data.getUserData(GitNewProjectWizardData.KEY)
- into["USE_GIT"] = gitData?.git == true
-
- return properties.mapValuesTo(into) { (_, prop) -> prop.get() }
- }
-
- private fun reformatFiles(
- project: Project,
- files: MutableList>
- ) {
- val psiManager = PsiManager.getInstance(project)
- val psiFiles = files.asSequence()
- .filter { (desc, _) -> desc.reformat != false }
- .mapNotNull { (_, file) -> psiManager.findFile(file) }
-
- val processor = ReformatCodeProcessor(project, psiFiles.toTypedArray(), null, false)
- psiFiles.forEach(processor::setDoNotKeepLineBreaks)
-
- val insightSettings = CodeInsightSettings.getInstance()
- val oldSecondReformat = insightSettings.ENABLE_SECOND_REFORMAT
- insightSettings.ENABLE_SECOND_REFORMAT = true
- try {
- processor.run()
- } finally {
- insightSettings.ENABLE_SECOND_REFORMAT = oldSecondReformat
- }
- }
-
- private fun openFilesInEditor(
- project: Project,
- files: MutableList>
- ) {
- val fileEditorManager = FileEditorManager.getInstance(project)
- val projectView = ProjectView.getInstance(project)
- for ((desc, file) in files) {
- if (desc.openInEditor == true) {
- fileEditorManager.openFile(file, true)
- projectView.select(null, file, false)
- }
- }
- }
-}