Wizard: introduce ServicesManager & correctly handle disabled gradle & maven Idea plugins

This commit is contained in:
Ilya Kirillov
2019-12-12 20:22:30 +03:00
parent 9011eecfdf
commit f927fb3471
41 changed files with 361 additions and 279 deletions
@@ -4,16 +4,24 @@ import org.jetbrains.kotlin.tools.projectWizard.core.PluginsCreator
import org.jetbrains.kotlin.tools.projectWizard.core.entity.SettingReference
import org.jetbrains.kotlin.tools.projectWizard.core.entity.SettingType
import org.jetbrains.kotlin.tools.projectWizard.core.entity.reference
import org.jetbrains.kotlin.tools.projectWizard.core.service.Service
import org.jetbrains.kotlin.tools.projectWizard.core.service.WizardService
import org.jetbrains.kotlin.tools.projectWizard.core.service.ServicesManager
import org.jetbrains.kotlin.tools.projectWizard.plugins.StructurePlugin
import org.jetbrains.kotlin.tools.projectWizard.plugins.buildSystem.BuildSystemPlugin
import org.jetbrains.kotlin.tools.projectWizard.wizard.service.IdeaWizardService
import kotlin.properties.ReadWriteProperty
import kotlin.reflect.KProperty
class IdeWizard(
createPlugins: PluginsCreator,
initialServices: List<Service>
) : Wizard(createPlugins, initialServices) {
initialServices: List<WizardService>
) : Wizard(
createPlugins,
ServicesManager(initialServices) { services ->
services.firstOrNull { it is IdeaWizardService }
?: services.firstOrNull()
}
) {
private val allSettings = plugins.flatMap { it.declaredSettings }
init {
@@ -24,6 +24,7 @@ import org.jetbrains.kotlin.tools.projectWizard.phases.GenerationPhase
import org.jetbrains.kotlin.tools.projectWizard.plugins.Plugins
import org.jetbrains.kotlin.tools.projectWizard.plugins.buildSystem.BuildSystemType
import org.jetbrains.kotlin.tools.projectWizard.plugins.projectTemplates.ProjectTemplatesPlugin
import org.jetbrains.kotlin.tools.projectWizard.wizard.service.*
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.PomWizardStepComponent
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.firstStep.FirstWizardStepComponent
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.secondStep.SecondStepWizardComponent
@@ -34,7 +35,7 @@ import com.intellij.openapi.module.Module as IdeaModule
class NewProjectWizardModuleBuilder : ModuleBuilder() {
private val wizard = IdeWizard(Plugins.allPlugins, listOf(IdeaAndroidService()))
private val wizard = IdeWizard(Plugins.allPlugins, IdeaServices.PROJECT_INDEPENDENT)
companion object {
const val MODULE_BUILDER_ID = "kotlin.newProjectWizard.builder"
@@ -62,13 +63,8 @@ class NewProjectWizardModuleBuilder : ModuleBuilder() {
): List<IdeaModule>? {
val modulesModel = model ?: ModuleManager.getInstance(project).modifiableModel
val success = wizard.apply(
services = listOf(
IdeaMavenService(project),
IdeaGradleService(project),
IdeaJpsService(project, modulesModel),
IdeaFileSystemService(),
IdeaAndroidService()
),
services = IdeaServices.createScopeDependent(project, modulesModel) +
IdeaServices.PROJECT_INDEPENDENT,
phases = GenerationPhase.startingFrom(GenerationPhase.FIRST_STEP)
).onFailure { errors ->
val errorMessages = errors.joinToString(separator = "\n") { it.message }
@@ -1,91 +0,0 @@
package org.jetbrains.kotlin.tools.projectWizard.wizard
import com.intellij.openapi.actionSystem.ActionPlaces
import com.intellij.openapi.actionSystem.AnActionEvent
import com.intellij.openapi.actionSystem.CommonDataKeys
import com.intellij.openapi.actionSystem.impl.SimpleDataContext
import com.intellij.openapi.project.Project
import com.intellij.openapi.vfs.LocalFileSystem
import com.intellij.openapi.vfs.VfsUtil
import com.intellij.openapi.vfs.VirtualFile
import org.jetbrains.android.sdk.AndroidSdkData
import org.jetbrains.idea.maven.project.MavenProjectsManager
import org.jetbrains.kotlin.idea.util.application.runWriteAction
import org.jetbrains.kotlin.tools.projectWizard.core.TaskResult
import org.jetbrains.kotlin.tools.projectWizard.core.safe
import org.jetbrains.kotlin.tools.projectWizard.core.service.*
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.ModuleIR
import org.jetbrains.plugins.gradle.action.ImportProjectFromScriptAction
import java.nio.file.Path
class IdeaFileSystemService : FileSystemService {
override fun createDirectory(path: Path): TaskResult<Unit> = safe {
runWriteAction<Unit> {
VfsUtil.createDirectoryIfMissing(path.toString())
}
}
override fun createFile(path: Path, text: String): TaskResult<Unit> = safe {
runWriteAction {
val directoryPath = path.parent
val directory = VfsUtil.createDirectoryIfMissing(directoryPath.toFile().toString())!!
val virtualFile = directory.createChildData(this, path.fileName.toString())
VfsUtil.saveText(virtualFile, text)
}
}
}
class IdeaGradleService(private val project: Project) : GradleService {
// We have to call action directly as there is no common way
// to import Gradle project in all IDEAs from 183 to 193
override fun importProject(
path: Path,
modulesIrs: List<ModuleIR>
): TaskResult<Unit> = safe {
val virtualFile = LocalFileSystem.getInstance().findFileByPath(path.toString())!!
val dataContext = SimpleDataContext.getSimpleContext(
mapOf(
CommonDataKeys.PROJECT.name to project,
CommonDataKeys.VIRTUAL_FILE.name to virtualFile
),
null
)
val action = ImportProjectFromScriptAction()
val event = AnActionEvent.createFromAnAction(action, null, ActionPlaces.UNKNOWN, dataContext)
action.actionPerformed(event)
}
}
class IdeaMavenService(private val project: Project) : MavenService {
override fun importProject(
path: Path,
modulesIrs: List<ModuleIR>
): TaskResult<Unit> = safe {
val mavenProjectManager = MavenProjectsManager.getInstance(project)
val rootFile = LocalFileSystem.getInstance().findFileByPath(path.toString())!!
mavenProjectManager.addManagedFilesOrUnignore(rootFile.findAllPomFiles())
}
private fun VirtualFile.findAllPomFiles(): List<VirtualFile> {
val result = mutableListOf<VirtualFile>()
fun VirtualFile.find() {
when {
!isDirectory && name == "pom.xml" -> result += this
isDirectory -> children.forEach(VirtualFile::find)
}
}
find()
return result
}
}
class IdeaAndroidService : AndroidService {
override fun isValidAndroidSdk(path: Path): Boolean =
//todo use android plugin for that?
AndroidServiceImpl().isValidAndroidSdk(path)
}
@@ -0,0 +1,19 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.tools.projectWizard.wizard.service
import com.intellij.ide.plugins.PluginManagerCore
import org.jetbrains.kotlin.tools.projectWizard.core.service.BuildSystemAvailabilityWizardService
import org.jetbrains.kotlin.tools.projectWizard.plugins.buildSystem.BuildSystemType
import org.jetbrains.kotlin.tools.projectWizard.plugins.buildSystem.isGradle
class IdeaBuildSystemAvailabilityWizardService : BuildSystemAvailabilityWizardService, IdeaWizardService {
override fun isAvailable(buildSystemType: BuildSystemType): Boolean = when {
buildSystemType.isGradle -> !PluginManagerCore.isDisabled("org.jetbrains.plugins.gradle")
buildSystemType == BuildSystemType.Maven -> !PluginManagerCore.isDisabled("org.jetbrains.idea.maven")
else -> true
}
}
@@ -0,0 +1,31 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.tools.projectWizard.wizard.service
import com.intellij.openapi.vfs.VfsUtil
import org.jetbrains.kotlin.idea.util.application.runWriteAction
import org.jetbrains.kotlin.tools.projectWizard.core.TaskResult
import org.jetbrains.kotlin.tools.projectWizard.core.safe
import org.jetbrains.kotlin.tools.projectWizard.core.service.FileSystemWizardService
import java.nio.file.Path
class IdeaFileSystemWizardService : FileSystemWizardService, IdeaWizardService {
override fun createDirectory(path: Path): TaskResult<Unit> = safe {
runWriteAction<Unit> {
VfsUtil.createDirectoryIfMissing(path.toString())
}
}
override fun createFile(path: Path, text: String): TaskResult<Unit> = safe {
runWriteAction {
val directoryPath = path.parent
val directory =
VfsUtil.createDirectoryIfMissing(directoryPath.toFile().toString())!!
val virtualFile = directory.createChildData(this, path.fileName.toString())
VfsUtil.saveText(virtualFile, text)
}
}
}
@@ -0,0 +1,51 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.tools.projectWizard.wizard.service
import com.intellij.openapi.actionSystem.ActionPlaces
import com.intellij.openapi.actionSystem.AnActionEvent
import com.intellij.openapi.actionSystem.CommonDataKeys
import com.intellij.openapi.actionSystem.impl.SimpleDataContext
import com.intellij.openapi.project.Project
import com.intellij.openapi.vfs.LocalFileSystem
import org.jetbrains.kotlin.tools.projectWizard.core.TaskResult
import org.jetbrains.kotlin.tools.projectWizard.core.safe
import org.jetbrains.kotlin.tools.projectWizard.core.service.ProjectImportingWizardService
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.ModuleIR
import org.jetbrains.kotlin.tools.projectWizard.plugins.buildSystem.BuildSystemType
import org.jetbrains.kotlin.tools.projectWizard.plugins.buildSystem.isGradle
import org.jetbrains.plugins.gradle.action.ImportProjectFromScriptAction
import java.nio.file.Path
class IdeaGradleWizardService(private val project: Project) : ProjectImportingWizardService,
IdeaWizardService {
override fun isSuitableFor(buildSystemType: BuildSystemType): Boolean =
buildSystemType.isGradle
// We have to call action directly as there is no common way
// to import Gradle project in all IDEAs from 183 to 193
override fun importProject(
path: Path,
modulesIrs: List<ModuleIR>
): TaskResult<Unit> = safe {
val virtualFile = LocalFileSystem.getInstance().findFileByPath(path.toString())!!
val dataContext = SimpleDataContext.getSimpleContext(
mapOf(
CommonDataKeys.PROJECT.name to project,
CommonDataKeys.VIRTUAL_FILE.name to virtualFile
),
null
)
val action = ImportProjectFromScriptAction()
val event = AnActionEvent.createFromAnAction(
action,
null,
ActionPlaces.UNKNOWN,
dataContext
)
action.actionPerformed(event)
}
}
@@ -1,4 +1,9 @@
package org.jetbrains.kotlin.tools.projectWizard.wizard
/*
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.tools.projectWizard.wizard.service
import com.intellij.codeInsight.daemon.impl.quickfix.OrderEntryFix
import com.intellij.jarRepository.JarRepositoryManager
@@ -9,7 +14,6 @@ import com.intellij.openapi.roots.DependencyScope
import com.intellij.openapi.roots.ModuleRootManager
import com.intellij.openapi.roots.ModuleRootModificationUtil
import com.intellij.openapi.roots.OrderRootType
import com.intellij.openapi.vfs.LocalFileSystem
import com.intellij.openapi.vfs.VfsUtil
import com.intellij.util.PathUtil
import org.jetbrains.idea.maven.utils.library.RepositoryLibraryProperties
@@ -19,19 +23,24 @@ import org.jetbrains.kotlin.config.TestResourceKotlinRootType
import org.jetbrains.kotlin.config.TestSourceKotlinRootType
import org.jetbrains.kotlin.idea.util.application.runWriteAction
import org.jetbrains.kotlin.tools.projectWizard.core.*
import org.jetbrains.kotlin.tools.projectWizard.core.service.JpsService
import org.jetbrains.kotlin.tools.projectWizard.core.service.ProjectImportingWizardService
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.*
import org.jetbrains.kotlin.tools.projectWizard.library.MavenArtifact
import org.jetbrains.kotlin.tools.projectWizard.plugins.buildSystem.BuildSystemType
import org.jetbrains.kotlin.tools.projectWizard.settings.buildsystem.SourcesetType
import java.nio.file.Path
import com.intellij.openapi.module.Module as IdeaModule
class IdeaJpsService(
class IdeaJpsWizardService(
private val project: Project,
private val modulesModel: ModifiableModuleModel
) : JpsService {
) : ProjectImportingWizardService, IdeaWizardService {
override fun isSuitableFor(buildSystemType: BuildSystemType): Boolean =
buildSystemType == BuildSystemType.Jps
override fun importProject(path: Path, modulesIrs: List<ModuleIR>): TaskResult<Unit> = runWriteAction {
ProjectImporter(project, modulesModel, path, modulesIrs).import()
ProjectImporter(project, modulesModel, path, modulesIrs)
.import()
}
}
@@ -47,7 +56,6 @@ private class ProjectImporter(
fun import() = modulesIrs.mapSequence { convertModule(it) } andThen
safe { modulesModel.commit() }
private fun convertModule(moduleIr: ModuleIR): TaskResult<IdeaModule> {
val module = modulesModel.newModule(
(moduleIr.path / "${moduleIr.name}.iml").toString(),
@@ -0,0 +1,47 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.tools.projectWizard.wizard.service
import com.intellij.openapi.project.Project
import com.intellij.openapi.vfs.LocalFileSystem
import com.intellij.openapi.vfs.VirtualFile
import org.jetbrains.idea.maven.project.MavenProjectsManager
import org.jetbrains.kotlin.tools.projectWizard.core.TaskResult
import org.jetbrains.kotlin.tools.projectWizard.core.safe
import org.jetbrains.kotlin.tools.projectWizard.core.service.ProjectImportingWizardService
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.ModuleIR
import org.jetbrains.kotlin.tools.projectWizard.plugins.buildSystem.BuildSystemType
import java.nio.file.Path
class IdeaMavenWizardService(private val project: Project) : ProjectImportingWizardService,
IdeaWizardService {
override fun isSuitableFor(buildSystemType: BuildSystemType): Boolean =
buildSystemType == BuildSystemType.Maven
override fun importProject(
path: Path,
modulesIrs: List<ModuleIR>
): TaskResult<Unit> = safe {
val mavenProjectManager = MavenProjectsManager.getInstance(project)
val rootFile = LocalFileSystem.getInstance().findFileByPath(path.toString())!!
mavenProjectManager.addManagedFilesOrUnignore(rootFile.findAllPomFiles())
}
private fun VirtualFile.findAllPomFiles(): List<VirtualFile> {
val result = mutableListOf<VirtualFile>()
fun VirtualFile.find() {
when {
!isDirectory && name == "pom.xml" -> result += this
isDirectory -> children.forEach(VirtualFile::find)
}
}
find()
return result
}
}
@@ -0,0 +1,27 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.tools.projectWizard.wizard.service
import com.intellij.openapi.module.ModifiableModuleModel
import com.intellij.openapi.project.Project
import org.jetbrains.kotlin.tools.projectWizard.core.service.WizardService
interface IdeaWizardService : WizardService
object IdeaServices {
val PROJECT_INDEPENDENT: List<IdeaWizardService> = listOf(
IdeaFileSystemWizardService(),
IdeaBuildSystemAvailabilityWizardService()
)
fun createScopeDependent(project: Project, model: ModifiableModuleModel) = listOf(
IdeaGradleWizardService(project),
IdeaMavenWizardService(project),
IdeaJpsWizardService(project, model)
)
}
@@ -22,8 +22,9 @@ import javax.swing.JList
class DropDownComponent<T : DisplayableSettingItem>(
private val valuesReadingContext: ValuesReadingContext,
initialValues: List<T> = emptyList(),
private val initialValues: List<T> = emptyList(),
labelText: String? = null,
private val filter: (T) -> Boolean = { true },
private val validator: SettingValidator<T> = settingValidator { ValidationResult.OK },
private val iconProvider: (T) -> Icon? = { null },
private val onAnyValueUpdate: (T) -> Unit = {}
@@ -42,7 +43,7 @@ class DropDownComponent<T : DisplayableSettingItem>(
}
@Suppress("UNCHECKED_CAST")
private val comboBox = ComboBox<T>(initialValues.toTypedArray<DisplayableSettingItem>() as Array<T>).apply {
private val comboBox = ComboBox<T>().apply {
renderer = object : ColoredListCellRenderer<T>() {
override fun customizeCellRenderer(
list: JList<out T>,
@@ -76,13 +77,23 @@ class DropDownComponent<T : DisplayableSettingItem>(
}
}
fun updateValues(newValues: List<T>) = withoutActionFiring {
val oldValue = comboBox.selectedItem
@Suppress("UNCHECKED_CAST")
comboBox.model = DefaultComboBoxModel(newValues.toTypedArray<DisplayableSettingItem>() as Array<T>)
override fun onInit() {
super.onInit()
updateValues(initialValues)
}
if (newValues.isNotEmpty() && oldValue !in newValues) {
value = newValues.first()
fun updateValues(newValues: List<T>) {
val newValuesFiltered = newValues.filter(filter)
val oldValue = comboBox.selectedItem
withoutActionFiring {
@Suppress("UNCHECKED_CAST")
comboBox.model = DefaultComboBoxModel(newValuesFiltered.toTypedArray<DisplayableSettingItem>() as Array<T>)
}
if (oldValue !in newValuesFiltered) {
newValuesFiltered.firstOrNull()?.let { newValue ->
value = newValuesFiltered.first()
}
}
}
@@ -106,13 +117,6 @@ class DropDownComponent<T : DisplayableSettingItem>(
}
}
init {
initialValues.firstOrNull()?.let { first ->
value = first
validate(first)
}
}
fun validate(value: T = this.value) {
validationIndicator.validationState = validator.validate(valuesReadingContext, value)
}
@@ -3,6 +3,7 @@ package org.jetbrains.kotlin.tools.projectWizard.wizard.ui.firstStep
import com.intellij.icons.AllIcons
import icons.GradleIcons
import icons.MavenIcons
import icons.OpenapiIcons
import org.jetbrains.kotlin.tools.projectWizard.core.entity.DropDownSettingType
import org.jetbrains.kotlin.tools.projectWizard.core.entity.SettingReference
import org.jetbrains.kotlin.tools.projectWizard.core.ValuesReadingContext
@@ -18,7 +19,7 @@ import java.awt.BorderLayout
class BuildSystemTypeSettingComponent(
valuesReadingContext: ValuesReadingContext
private val valuesReadingContext: ValuesReadingContext
) : SettingComponent<BuildSystemType, DropDownSettingType<BuildSystemType>>(
BuildSystemPlugin::type.reference,
valuesReadingContext
@@ -28,6 +29,7 @@ class BuildSystemTypeSettingComponent(
valuesReadingContext,
setting.type.values,
labelText = "Build System",
filter = { value -> setting.type.filter(valuesReadingContext, reference, value) },
validator = setting.validator,
iconProvider = BuildSystemType::icon,
onAnyValueUpdate = { value = it }
@@ -51,6 +53,6 @@ private val BuildSystemType.icon
get() = when (this) {
BuildSystemType.GradleKotlinDsl -> GradleIcons.Gradle
BuildSystemType.GradleGroovyDsl -> GradleIcons.Gradle
BuildSystemType.Maven -> MavenIcons.MavenLogo
BuildSystemType.Maven -> OpenapiIcons.RepositoryLibraryLogo
BuildSystemType.Jps -> AllIcons.Nodes.Module
}
@@ -100,7 +100,7 @@ class VersionSettingComponent(
class DropdownSettingComponent(
reference: SettingReference<DisplayableSettingItem, DropDownSettingType<DisplayableSettingItem>>,
valuesReadingContext: ValuesReadingContext
private val valuesReadingContext: ValuesReadingContext
) : DefaultSettingComponent<DisplayableSettingItem, DropDownSettingType<DisplayableSettingItem>>(
reference,
valuesReadingContext
@@ -108,22 +108,13 @@ class DropdownSettingComponent(
private val dropDownComponent = DropDownComponent(
valuesReadingContext,
setting.type.values,
filter = { value -> setting.type.filter(valuesReadingContext, reference, value) },
labelText = setting.title,
onAnyValueUpdate = { newValue ->
value = newValue
}
).asSubComponent()
override fun onInit() {
super.onInit()
val valuesFiltered = setting.type.values.filter { setting.type.filter(reference, it) }
dropDownComponent.updateValues(valuesFiltered)
if (valuesFiltered.isNotEmpty()) {
value = valuesFiltered.first()
}
}
override val validationIndicator: ValidationIndicator? = null
override val component: JComponent = dropDownComponent.component
}
@@ -5,8 +5,7 @@ import org.jetbrains.kotlin.tools.projectWizard.core.*
import org.jetbrains.kotlin.tools.projectWizard.core.entity.PipelineTask
import org.jetbrains.kotlin.tools.projectWizard.core.entity.PluginSettingReference
import org.jetbrains.kotlin.tools.projectWizard.core.entity.reference
import org.jetbrains.kotlin.tools.projectWizard.core.service.AndroidServiceImpl
import org.jetbrains.kotlin.tools.projectWizard.core.service.Service
import org.jetbrains.kotlin.tools.projectWizard.core.service.*
import org.jetbrains.kotlin.tools.projectWizard.phases.GenerationPhase
import org.jetbrains.kotlin.tools.projectWizard.plugins.StructurePlugin
import org.jetbrains.kotlin.tools.projectWizard.plugins.templates.TemplatesPlugin
@@ -16,9 +15,14 @@ class YamlWizard(
private val yaml: String,
private val path: String,
createPlugins: (Context) -> List<Plugin>
) : Wizard(createPlugins, listOf(AndroidServiceImpl())) {
) : Wizard(
createPlugins,
ServicesManager(Services.IDEA_INDEPENDENT_SERVICES) { services ->
services.firstOrNull { it is IdeaIndependentWizardService }
}
) {
override fun apply(
services: List<Service>,
services: List<WizardService>,
phases: Set<GenerationPhase>,
onTaskExecuting: (PipelineTask) -> Unit
): TaskResult<Unit> = computeM {
@@ -38,5 +42,5 @@ class YamlWizard(
get() = pluginSettings.mapNotNull { setting ->
val defaultValue = setting.defaultValue ?: return@mapNotNull null
PluginSettingReference(setting) to defaultValue
} .toMap()
}.toMap()
}
@@ -5,7 +5,6 @@
package org.jetbrains.kotlin.tools.projectWizard.cli
import com.intellij.testFramework.UsefulTestCase
import org.jetbrains.kotlin.tools.projectWizard.core.ExceptionError
import org.jetbrains.kotlin.tools.projectWizard.core.div
import org.jetbrains.kotlin.tools.projectWizard.core.onFailure
@@ -20,7 +19,6 @@ import java.nio.file.Path
import java.nio.file.Paths
abstract class AbstractBuildFileGenerationTest : AbstractPluginBasedTest() {
fun doTest(directoryPath: String) {
val directory = Paths.get(directoryPath)
val testData = init(directory)
@@ -41,7 +39,7 @@ abstract class AbstractBuildFileGenerationTest : AbstractPluginBasedTest() {
buildSystem.yaml
val tempDir = Files.createTempDirectory(null)
val wizard = YamlWizard(yaml, tempDir.toString(), testData.createPlugins)
val result = wizard.apply(Services.osServices, GenerationPhase.ALL)
val result = wizard.apply(Services.IDEA_INDEPENDENT_SERVICES, GenerationPhase.ALL)
result.onFailure { errors ->
errors.forEach { error ->
if (error is ExceptionError) {
@@ -3,7 +3,6 @@ package org.jetbrains.kotlin.tools.projectWizard.core
import org.jetbrains.kotlin.tools.projectWizard.core.entity.*
import org.jetbrains.kotlin.tools.projectWizard.phases.GenerationPhase
import kotlin.reflect.KClass
import kotlin.reflect.KProperty1
import kotlin.reflect.full.isSubclassOf
import kotlin.reflect.full.memberProperties
@@ -3,11 +3,12 @@ package org.jetbrains.kotlin.tools.projectWizard.core
import org.jetbrains.kotlin.tools.projectWizard.core.entity.PropertyReference
import org.jetbrains.kotlin.tools.projectWizard.core.entity.Task1
import org.jetbrains.kotlin.tools.projectWizard.core.entity.Task1Reference
import org.jetbrains.kotlin.tools.projectWizard.core.service.Service
import kotlin.reflect.KClass
import kotlin.reflect.full.isSubclassOf
import org.jetbrains.kotlin.tools.projectWizard.core.service.ServicesManager
class TaskRunningContext(context: Context, services: List<Service>) : ValuesReadingContext(context, services) {
class TaskRunningContext(
context: Context,
servicesManager: ServicesManager
) : ValuesReadingContext(context, servicesManager) {
fun <A, B : Any> Task1Reference<A, B>.execute(value: A): TaskResult<B> {
@Suppress("UNCHECKED_CAST")
val task = context.taskContext.getEntity(this) as Task1<A, B>
@@ -30,4 +31,3 @@ class TaskRunningContext(context: Context, services: List<Service>) : ValuesRead
values: List<T>
): TaskResult<Unit> = update { oldValues -> success(oldValues + values) }
}
@@ -1,19 +1,17 @@
package org.jetbrains.kotlin.tools.projectWizard.core
import org.jetbrains.kotlin.tools.projectWizard.core.entity.*
import org.jetbrains.kotlin.tools.projectWizard.core.service.Service
import org.jetbrains.kotlin.tools.projectWizard.core.service.WizardService
import org.jetbrains.kotlin.tools.projectWizard.core.service.ServicesManager
import kotlin.reflect.KClass
import kotlin.reflect.KProperty1
import kotlin.reflect.full.isSubclassOf
import kotlin.reflect.jvm.jvmName
@Suppress("UNCHECKED_CAST")
open class ValuesReadingContext(val context: Context, private val services: List<Service>) {
inline fun <reified S : Service> service() = serviceByClass(S::class)
open class ValuesReadingContext(val context: Context, private val servicesManager: ServicesManager) {
inline fun <reified S : WizardService> service(noinline filter: (S) -> Boolean = { true }) = serviceByClass(S::class, filter)
@Suppress("UNCHECKED_CAST")
fun <S : Service> serviceByClass(klass: KClass<S>) =
services.firstOrNull { it::class.isSubclassOf(klass) } as? S ?: error("No service ${klass.jvmName}")
fun <S : WizardService> serviceByClass(klass: KClass<S>, filter: (S) -> Boolean = { true }) =
servicesManager.serviceByClass(klass, filter)
inline val <reified T : Any> PropertyReference<T>.propertyValue: T
get() = context.propertyContext[this] as T
@@ -277,7 +277,7 @@ class DropDownSettingType<V : DisplayableSettingItem>(
}
}
typealias DropDownSettingTypeFilter<V> = (SettingReference<V, DropDownSettingType<V>>, V) -> Boolean
typealias DropDownSettingTypeFilter<V> = ValuesReadingContext.(SettingReference<V, DropDownSettingType<V>>, V) -> Boolean
class ValueSettingType<V : Any>(
@@ -2,11 +2,11 @@ package org.jetbrains.kotlin.tools.projectWizard.core.service
import java.nio.file.Path
interface AndroidService : Service {
interface AndroidWizardService : WizardService {
fun isValidAndroidSdk(path: Path): Boolean
}
class AndroidServiceImpl : AndroidService {
class AndroidWizardServiceImpl : AndroidWizardService, IdeaIndependentWizardService {
//TODO use some heuristics
override fun isValidAndroidSdk(path: Path): Boolean = true
}
@@ -0,0 +1,16 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.tools.projectWizard.core.service
import org.jetbrains.kotlin.tools.projectWizard.plugins.buildSystem.BuildSystemType
interface BuildSystemAvailabilityWizardService : WizardService {
fun isAvailable(buildSystemType: BuildSystemType): Boolean
}
class BuildSystemAvailabilityWizardServiceImpl : BuildSystemAvailabilityWizardService, IdeaIndependentWizardService {
override fun isAvailable(buildSystemType: BuildSystemType) = true
}
@@ -1,12 +0,0 @@
package org.jetbrains.kotlin.tools.projectWizard.core.service
import org.jetbrains.kotlin.tools.projectWizard.core.TaskResult
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.ModuleIR
import java.nio.file.Path
interface BuildSystemService : Service {
fun importProject(
path: Path,
modulesIrs: List<ModuleIR>
): TaskResult<Unit>
}
@@ -0,0 +1,7 @@
package org.jetbrains.kotlin.tools.projectWizard.core.service
import org.jetbrains.kotlin.tools.projectWizard.plugins.buildSystem.BuildSystemType
interface BuildSystemWizardService : WizardService {
fun isSuitableFor(buildSystemType: BuildSystemType): Boolean
}
@@ -1,29 +1,22 @@
package org.jetbrains.kotlin.tools.projectWizard.core.service
import org.jetbrains.kotlin.tools.projectWizard.core.TaskResult
import org.jetbrains.kotlin.tools.projectWizard.core.UNIT_SUCCESS
import org.jetbrains.kotlin.tools.projectWizard.core.computeM
import org.jetbrains.kotlin.tools.projectWizard.core.safe
import java.nio.file.Files
import java.nio.file.Path
interface FileSystemService : Service {
interface FileSystemWizardService : WizardService {
fun createFile(path: Path, text: String): TaskResult<Unit>
fun createDirectory(path: Path): TaskResult<Unit>
object DUMMY : FileSystemService {
override fun createFile(path: Path, text: String): TaskResult<Unit> = UNIT_SUCCESS
override fun createDirectory(path: Path): TaskResult<Unit> = UNIT_SUCCESS
}
}
class OsFileSystemService : FileSystemService {
class OsFileSystemWizardService : FileSystemWizardService, IdeaIndependentWizardService {
override fun createFile(path: Path, text: String) = computeM {
createDirectory(path.parent).ensure()
safe { Files.createFile(path.normalize()).toFile().writeText(text) }
}
override fun createDirectory(path: Path) = safe {
@Suppress("NAME_SHADOWING") val path = path.normalize()
if (Files.notExists(path)) {
@@ -1,14 +0,0 @@
package org.jetbrains.kotlin.tools.projectWizard.core.service
import org.jetbrains.kotlin.tools.projectWizard.core.UNIT_SUCCESS
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.ModuleIR
import java.nio.file.Path
interface GradleService : BuildSystemService
class OsGradleIntegration : GradleService {
override fun importProject(
path: Path,
modulesIrs: List<ModuleIR>
) = UNIT_SUCCESS
}
@@ -1,14 +0,0 @@
package org.jetbrains.kotlin.tools.projectWizard.core.service
import org.jetbrains.kotlin.tools.projectWizard.core.UNIT_SUCCESS
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.ModuleIR
import java.nio.file.Path
interface JpsService : BuildSystemService
class OsJpsService : JpsService {
override fun importProject(
path: Path,
modulesIrs: List<ModuleIR>
) = UNIT_SUCCESS
}
@@ -1,14 +0,0 @@
package org.jetbrains.kotlin.tools.projectWizard.core.service
import org.jetbrains.kotlin.tools.projectWizard.core.UNIT_SUCCESS
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.ModuleIR
import java.nio.file.Path
interface MavenService : BuildSystemService
class OsMavenService : MavenService {
override fun importProject(
path: Path,
modulesIrs: List<ModuleIR>
) = UNIT_SUCCESS
}
@@ -0,0 +1,16 @@
package org.jetbrains.kotlin.tools.projectWizard.core.service
import org.jetbrains.kotlin.tools.projectWizard.core.TaskResult
import org.jetbrains.kotlin.tools.projectWizard.core.UNIT_SUCCESS
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.ModuleIR
import org.jetbrains.kotlin.tools.projectWizard.plugins.buildSystem.BuildSystemType
import java.nio.file.Path
interface ProjectImportingWizardService : BuildSystemWizardService {
fun importProject(path: Path, modulesIrs: List<ModuleIR>): TaskResult<Unit>
}
class ProjectImportingWizardServiceImpl : ProjectImportingWizardService, IdeaIndependentWizardService {
override fun isSuitableFor(buildSystemType: BuildSystemType): Boolean = true
override fun importProject(path: Path, modulesIrs: List<ModuleIR>) = UNIT_SUCCESS
}
@@ -1,13 +0,0 @@
package org.jetbrains.kotlin.tools.projectWizard.core.service
interface Service
object Services {
val osServices = listOf(
OsGradleIntegration(),
OsMavenService(),
OsFileSystemService(),
OsJpsService(),
AndroidServiceImpl()
)
}
@@ -0,0 +1,20 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.tools.projectWizard.core.service
import kotlin.reflect.KClass
import kotlin.reflect.full.isSubclassOf
class ServicesManager(private val services: List<WizardService>, private val serviceSelector: (List<WizardService>) -> WizardService?) {
@Suppress("UNCHECKED_CAST")
fun <S : WizardService> serviceByClass(klass: KClass<S>, filter: (S) -> Boolean): S? =
services.filter { service ->
service::class.isSubclassOf(klass) && filter(service as S)
}.let(serviceSelector) as? S
fun withServices(services: List<WizardService>) =
ServicesManager(this.services + services, serviceSelector)
}
@@ -0,0 +1,15 @@
package org.jetbrains.kotlin.tools.projectWizard.core.service
interface WizardService
interface IdeaIndependentWizardService : WizardService
object Services {
val IDEA_INDEPENDENT_SERVICES: List<IdeaIndependentWizardService> = listOf(
ProjectImportingWizardServiceImpl(),
OsFileSystemWizardService(),
AndroidWizardServiceImpl(),
BuildSystemAvailabilityWizardServiceImpl()
)
}
@@ -3,7 +3,7 @@ package org.jetbrains.kotlin.tools.projectWizard.moduleConfigurators
import org.jetbrains.kotlin.tools.projectWizard.core.*
import org.jetbrains.kotlin.tools.projectWizard.core.entity.ModuleConfiguratorSetting
import org.jetbrains.kotlin.tools.projectWizard.core.entity.ValidationResult
import org.jetbrains.kotlin.tools.projectWizard.core.service.AndroidService
import org.jetbrains.kotlin.tools.projectWizard.core.service.AndroidWizardService
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.*
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.gradle.AndroidConfigIR
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.gradle.BuildScriptDependencyIR
@@ -14,7 +14,6 @@ import org.jetbrains.kotlin.tools.projectWizard.phases.GenerationPhase
import org.jetbrains.kotlin.tools.projectWizard.plugins.buildSystem.gradle.GradlePlugin
import org.jetbrains.kotlin.tools.projectWizard.plugins.kotlin.ModuleConfigurationData
import org.jetbrains.kotlin.tools.projectWizard.plugins.kotlin.ModuleType
import org.jetbrains.kotlin.tools.projectWizard.plugins.pomIR
import org.jetbrains.kotlin.tools.projectWizard.plugins.templates.TemplatesPlugin
import org.jetbrains.kotlin.tools.projectWizard.settings.JavaPackage
import org.jetbrains.kotlin.tools.projectWizard.settings.buildsystem.DefaultRepository
@@ -38,7 +37,7 @@ object AndroidSinglePlatformModuleConfigurator : ModuleConfiguratorWithSettings(
validate { path ->
ValidationResult.create(
service<AndroidService>().isValidAndroidSdk(
service<AndroidWizardService>()!!.isValidAndroidSdk(
path
),
"Path should point to valid Android SDK location"
@@ -5,7 +5,7 @@ import org.jetbrains.kotlin.tools.projectWizard.core.Plugin
import org.jetbrains.kotlin.tools.projectWizard.core.TaskRunningContext
import org.jetbrains.kotlin.tools.projectWizard.core.entity.reference
import org.jetbrains.kotlin.tools.projectWizard.core.pathParser
import org.jetbrains.kotlin.tools.projectWizard.core.service.FileSystemService
import org.jetbrains.kotlin.tools.projectWizard.core.service.FileSystemWizardService
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.PomIR
import org.jetbrains.kotlin.tools.projectWizard.phases.GenerationPhase
import org.jetbrains.kotlin.tools.projectWizard.settings.version.Version
@@ -31,7 +31,7 @@ class StructurePlugin(context: Context) : Plugin(context) {
val createProjectDir by pipelineTask(GenerationPhase.PROJECT_GENERATION) {
withAction {
service<FileSystemService>().createDirectory(StructurePlugin::projectPath.reference.settingValue)
service<FileSystemWizardService>()!!.createDirectory(StructurePlugin::projectPath.reference.settingValue)
}
}
}
@@ -3,8 +3,9 @@ package org.jetbrains.kotlin.tools.projectWizard.plugins.buildSystem
import org.jetbrains.kotlin.tools.projectWizard.core.*
import org.jetbrains.kotlin.tools.projectWizard.core.entity.ValidationResult
import org.jetbrains.kotlin.tools.projectWizard.core.entity.reference
import org.jetbrains.kotlin.tools.projectWizard.core.service.BuildSystemService
import org.jetbrains.kotlin.tools.projectWizard.core.service.FileSystemService
import org.jetbrains.kotlin.tools.projectWizard.core.service.BuildSystemAvailabilityWizardService
import org.jetbrains.kotlin.tools.projectWizard.core.service.FileSystemWizardService
import org.jetbrains.kotlin.tools.projectWizard.core.service.ProjectImportingWizardService
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.BuildFileIR
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.MultiplatformModulesStructureIR
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.render
@@ -16,13 +17,17 @@ import org.jetbrains.kotlin.tools.projectWizard.plugins.printer.BuildFilePrinter
import org.jetbrains.kotlin.tools.projectWizard.plugins.printer.printBuildFile
import org.jetbrains.kotlin.tools.projectWizard.plugins.projectPath
import org.jetbrains.kotlin.tools.projectWizard.settings.DisplayableSettingItem
import kotlin.reflect.KClass
abstract class BuildSystemPlugin(context: Context) : Plugin(context) {
val type by enumSetting<BuildSystemType>("Build System", GenerationPhase.FIRST_STEP) {
filter = { _, type ->
val service = service<BuildSystemAvailabilityWizardService>()!!
service.isAvailable(type)
}
validate { buildSystemType ->
if (!buildSystemType.isGradle
&& KotlinPlugin::projectKind.settingValue() == ProjectKind.Multiplatform
&& KotlinPlugin::projectKind.reference.notRequiredSettingValue == ProjectKind.Multiplatform
) {
ValidationResult.ValidationError("Multiplatform project cannot be generated using ${buildSystemType.text}")
} else ValidationResult.OK
@@ -36,7 +41,7 @@ abstract class BuildSystemPlugin(context: Context) : Plugin(context) {
val createModules by pipelineTask(GenerationPhase.PROJECT_GENERATION) {
runAfter(StructurePlugin::createProjectDir)
withAction {
val fileSystem = service<FileSystemService>()
val fileSystem = service<FileSystemWizardService>()!!
val data = BuildSystemPlugin::buildSystemData.propertyValue.first { it.type == buildSystemType }
val buildFileData = data.buildFileData ?: return@withAction UNIT_SUCCESS
BuildSystemPlugin::buildFiles.propertyValue.mapSequenceIgnore { buildFile ->
@@ -52,7 +57,7 @@ abstract class BuildSystemPlugin(context: Context) : Plugin(context) {
runAfter(BuildSystemPlugin::createModules)
withAction {
val data = BuildSystemPlugin::buildSystemData.propertyValue.first { it.type == buildSystemType }
serviceByClass(data.buildSystemServiceClass)
service<ProjectImportingWizardService> { service -> service.isSuitableFor(data.type) }!!
.importProject(StructurePlugin::projectPath.reference.settingValue, allModules)
}
}
@@ -61,14 +66,13 @@ abstract class BuildSystemPlugin(context: Context) : Plugin(context) {
runBefore(BuildSystemPlugin::createModules)
activityChecker = Checker.ALWAYS_AVAILABLE
withAction {
BuildSystemPlugin::buildSystemData.update { Success(it + data) }
BuildSystemPlugin::buildSystemData.addValues(data)
}
}
}
data class BuildSystemData(
val type: BuildSystemType,
val buildSystemServiceClass: KClass<out BuildSystemService>,
val buildFileData: BuildFileData?
)
@@ -1,7 +1,6 @@
package org.jetbrains.kotlin.tools.projectWizard.plugins.buildSystem
import org.jetbrains.kotlin.tools.projectWizard.core.Context
import org.jetbrains.kotlin.tools.projectWizard.core.service.JpsService
class JpsPlugin(context: Context) : BuildSystemPlugin(context) {
override val title: String = "IDEA"
@@ -9,7 +8,6 @@ class JpsPlugin(context: Context) : BuildSystemPlugin(context) {
val addBuildSystemData by addBuildSystemData(
BuildSystemData(
type = BuildSystemType.Jps,
buildSystemServiceClass = JpsService::class,
buildFileData = null
)
)
@@ -4,7 +4,6 @@ import org.jetbrains.kotlin.tools.projectWizard.core.Context
import org.jetbrains.kotlin.tools.projectWizard.core.asSuccess
import org.jetbrains.kotlin.tools.projectWizard.core.checker
import org.jetbrains.kotlin.tools.projectWizard.core.entity.reference
import org.jetbrains.kotlin.tools.projectWizard.core.service.MavenService
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.RootFileModuleStructureIR
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.gradle.ModulesDependencyMavenIR
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.withIrs
@@ -42,7 +41,6 @@ class MavenPlugin(context: Context) : BuildSystemPlugin(context) {
val addBuildSystemData by addBuildSystemData(
BuildSystemData(
type = BuildSystemType.Maven,
buildSystemServiceClass = MavenService::class,
buildFileData = BuildFileData(
createPrinter = { MavenPrinter() },
buildFileName = "pom.xml"
@@ -1,15 +1,10 @@
package org.jetbrains.kotlin.tools.projectWizard.plugins.buildSystem.gradle
import org.jetbrains.kotlin.tools.projectWizard.core.Context
import org.jetbrains.kotlin.tools.projectWizard.core.checker
import org.jetbrains.kotlin.tools.projectWizard.core.service.GradleService
import org.jetbrains.kotlin.tools.projectWizard.core.service.MavenService
import org.jetbrains.kotlin.tools.projectWizard.plugins.buildSystem.BuildFileData
import org.jetbrains.kotlin.tools.projectWizard.plugins.buildSystem.BuildSystemData
import org.jetbrains.kotlin.tools.projectWizard.plugins.buildSystem.BuildSystemPlugin
import org.jetbrains.kotlin.tools.projectWizard.plugins.buildSystem.BuildSystemType
import org.jetbrains.kotlin.tools.projectWizard.plugins.printer.GradlePrinter
import org.jetbrains.kotlin.tools.projectWizard.plugins.printer.MavenPrinter
class GroovyDslPlugin(context: Context) : GradlePlugin(context) {
override val title: String = "Gradle (Groovy DSL)"
@@ -17,7 +12,6 @@ class GroovyDslPlugin(context: Context) : GradlePlugin(context) {
val addBuildSystemData by addBuildSystemData(
BuildSystemData(
type = BuildSystemType.GradleGroovyDsl,
buildSystemServiceClass = GradleService::class,
buildFileData = BuildFileData(
createPrinter = { GradlePrinter(GradlePrinter.GradleDsl.GROOVY) },
buildFileName = "build.gradle"
@@ -1,11 +1,8 @@
package org.jetbrains.kotlin.tools.projectWizard.plugins.buildSystem.gradle
import org.jetbrains.kotlin.tools.projectWizard.core.Context
import org.jetbrains.kotlin.tools.projectWizard.core.checker
import org.jetbrains.kotlin.tools.projectWizard.core.service.GradleService
import org.jetbrains.kotlin.tools.projectWizard.plugins.buildSystem.BuildFileData
import org.jetbrains.kotlin.tools.projectWizard.plugins.buildSystem.BuildSystemData
import org.jetbrains.kotlin.tools.projectWizard.plugins.buildSystem.BuildSystemPlugin
import org.jetbrains.kotlin.tools.projectWizard.plugins.buildSystem.BuildSystemType
import org.jetbrains.kotlin.tools.projectWizard.plugins.printer.GradlePrinter
@@ -15,7 +12,6 @@ class KotlinDslPlugin(context: Context) : GradlePlugin(context) {
val addBuildSystemData by addBuildSystemData(
BuildSystemData(
type = BuildSystemType.GradleKotlinDsl,
buildSystemServiceClass = GradleService::class,
buildFileData = BuildFileData(
createPrinter = { GradlePrinter(GradlePrinter.GradleDsl.KOTLIN) },
buildFileName = "build.gradle.kts"
@@ -2,7 +2,7 @@ package org.jetbrains.kotlin.tools.projectWizard.plugins.kotlin
import org.jetbrains.kotlin.tools.projectWizard.core.*
import org.jetbrains.kotlin.tools.projectWizard.core.entity.*
import org.jetbrains.kotlin.tools.projectWizard.core.service.FileSystemService
import org.jetbrains.kotlin.tools.projectWizard.core.service.FileSystemWizardService
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.*
import org.jetbrains.kotlin.tools.projectWizard.phases.GenerationPhase
import org.jetbrains.kotlin.tools.projectWizard.plugins.StructurePlugin
@@ -82,9 +82,10 @@ class KotlinPlugin(context: Context) : Plugin(context) {
val createSourcesetDirectories by pipelineTask(GenerationPhase.PROJECT_GENERATION) {
runAfter(KotlinPlugin::createModules)
withAction {
fun Path.createKotlinAndResourceDirectories() =
service<FileSystemService>().createDirectory(this / Defaults.KOTLIN_DIR) andThen
service<FileSystemService>().createDirectory(this / Defaults.RESOURCES_DIR)
fun Path.createKotlinAndResourceDirectories() = with(service<FileSystemWizardService>()!!) {
createDirectory(this@createKotlinAndResourceDirectories / Defaults.KOTLIN_DIR) andThen
createDirectory(this@createKotlinAndResourceDirectories / Defaults.RESOURCES_DIR)
}
forEachModule { moduleIR ->
when (moduleIR) {
@@ -4,11 +4,10 @@ import org.jetbrains.kotlin.tools.projectWizard.Identificator
import org.jetbrains.kotlin.tools.projectWizard.SettingsOwner
import org.jetbrains.kotlin.tools.projectWizard.core.*
import org.jetbrains.kotlin.tools.projectWizard.core.entity.*
import org.jetbrains.kotlin.tools.projectWizard.core.service.FileSystemService
import org.jetbrains.kotlin.tools.projectWizard.core.service.FileSystemWizardService
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.BuildSystemIR
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.DependencyIR
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.SourcesetIR
import org.jetbrains.kotlin.tools.projectWizard.moduleConfigurators.ModuleConfigurator
import org.jetbrains.kotlin.tools.projectWizard.phases.GenerationPhase
import org.jetbrains.kotlin.tools.projectWizard.plugins.StructurePlugin
import org.jetbrains.kotlin.tools.projectWizard.plugins.kotlin.ModuleType
@@ -79,7 +78,7 @@ abstract class Template : SettingsOwner {
templateEngine: TemplateEngine,
sourceset: SourcesetIR
): TaskResult<TemplateApplicationResult> {
val fileSystemService = service<FileSystemService>()
val fileSystemService = service<FileSystemWizardService>()!!
val allSettings = createDefaultSettings() + settingsAsMap(sourceset.original)
@@ -8,7 +8,7 @@ import org.apache.velocity.runtime.log.LogChute
import org.jetbrains.kotlin.tools.projectWizard.core.TaskResult
import org.jetbrains.kotlin.tools.projectWizard.core.TaskRunningContext
import org.jetbrains.kotlin.tools.projectWizard.core.div
import org.jetbrains.kotlin.tools.projectWizard.core.service.FileSystemService
import org.jetbrains.kotlin.tools.projectWizard.core.service.FileSystemWizardService
import java.io.StringWriter
@@ -17,7 +17,7 @@ interface TemplateEngine {
fun TaskRunningContext.writeTemplate(template: FileTemplate): TaskResult<Unit> {
val text = renderTemplate(template.descriptor, template.data)
return service<FileSystemService>().createFile(template.rootPath / template.descriptor.relativePath, text)
return service<FileSystemWizardService>()!!.createFile(template.rootPath / template.descriptor.relativePath, text)
}
}
@@ -2,12 +2,13 @@ package org.jetbrains.kotlin.tools.projectWizard.wizard
import org.jetbrains.kotlin.tools.projectWizard.core.*
import org.jetbrains.kotlin.tools.projectWizard.core.entity.*
import org.jetbrains.kotlin.tools.projectWizard.core.service.Service
import org.jetbrains.kotlin.tools.projectWizard.core.service.WizardService
import org.jetbrains.kotlin.tools.projectWizard.core.service.ServicesManager
import org.jetbrains.kotlin.tools.projectWizard.phases.GenerationPhase
abstract class Wizard(createPlugins: PluginsCreator, initialServices: List<Service>) {
abstract class Wizard(createPlugins: PluginsCreator, val servicesManager: ServicesManager) {
val context = Context(createPlugins, EventManager())
val valuesReadingContext = ValuesReadingContext(context, initialServices)
val valuesReadingContext = ValuesReadingContext(context, servicesManager)
protected val plugins = context.plugins
protected val pluginSettings = plugins.flatMap { it.declaredSettings }.distinctBy { it.path }
@@ -28,12 +29,12 @@ abstract class Wizard(createPlugins: PluginsCreator, initialServices: List<Servi
}.fold(ValidationResult.OK, ValidationResult::and).toResult()
open fun apply(
services: List<Service>,
services: List<WizardService>,
phases: Set<GenerationPhase>,
onTaskExecuting: (PipelineTask) -> Unit = {}
): TaskResult<Unit> = computeM {
context.checkAllRequiredSettingPresent(phases).ensure()
val taskRunningContext = TaskRunningContext(context, services)
val taskRunningContext = TaskRunningContext(context, servicesManager.withServices(services))
taskRunningContext.validate(phases).ensure()
val (tasksSorted) = context.sortTasks().map { tasks ->
tasks.groupBy { it.phase }.toList().sortedBy { it.first }.flatMap { it.second }