Wizard: all context operations to read/write operations

This commit is contained in:
Ilya Kirillov
2020-03-09 21:02:13 +03:00
parent 81c7cb20f3
commit 691ee7412a
94 changed files with 570 additions and 632 deletions
@@ -1,10 +1,10 @@
package org.jetbrains.kotlin.tools.projectWizard
import org.jetbrains.kotlin.tools.projectWizard.wizard.core.YamlParsingError
import org.jetbrains.kotlin.tools.projectWizard.core.*
import org.jetbrains.kotlin.tools.projectWizard.core.entity.settings.PluginSetting
import org.jetbrains.kotlin.tools.projectWizard.core.entity.settings.PluginSettingReference
import org.jetbrains.kotlin.tools.projectWizard.core.entity.settings.SettingReference
import org.jetbrains.kotlin.tools.projectWizard.wizard.core.YamlParsingError
import org.yaml.snakeyaml.Yaml
import org.yaml.snakeyaml.parser.ParserException
import java.nio.file.Path
@@ -2,8 +2,6 @@ package org.jetbrains.kotlin.tools.projectWizard.wizard
import org.jetbrains.kotlin.tools.projectWizard.YamlSettingsParser
import org.jetbrains.kotlin.tools.projectWizard.core.*
import org.jetbrains.kotlin.tools.projectWizard.core.context.ReadingContext
import org.jetbrains.kotlin.tools.projectWizard.core.context.SettingsWritingContext
import org.jetbrains.kotlin.tools.projectWizard.core.entity.PipelineTask
import org.jetbrains.kotlin.tools.projectWizard.core.entity.settings.PluginSetting
import org.jetbrains.kotlin.tools.projectWizard.core.entity.settings.SettingReference
@@ -24,16 +22,15 @@ class YamlWizard(
servicesManager: ServicesManager = CLI_SERVICES_MANAGER,
isUnitTestMode: Boolean
) : Wizard(createPlugins, servicesManager, isUnitTestMode) {
private val settingsWritingContext = SettingsWritingContext(context, servicesManager, isUnitTestMode)
override fun apply(
services: List<WizardService>,
phases: Set<GenerationPhase>,
onTaskExecuting: (PipelineTask) -> Unit
): TaskResult<Unit> = computeM {
val (settingsValuesFromYaml) = valuesReadingContext.parseYaml(yaml, pluginSettings)
val (settingsValuesFromYaml) = context.read { parseYaml(yaml, pluginSettings) }
with(settingsWritingContext) {
context.writeSettings {
settingsValuesFromYaml.forEach { (reference, value) -> reference.setValue(value) }
StructurePlugin::projectPath.reference.setValue(projectPath)
}
@@ -6,11 +6,11 @@
package org.jetbrains.kotlin.tools.projectWizard.cli
import org.jetbrains.kotlin.tools.projectWizard.core.TaskResult
import org.jetbrains.kotlin.tools.projectWizard.core.compute
import org.jetbrains.kotlin.tools.projectWizard.core.UNIT_SUCCESS
import org.jetbrains.kotlin.tools.projectWizard.core.computeM
import org.jetbrains.kotlin.tools.projectWizard.core.context.SettingsWritingContext
import org.jetbrains.kotlin.tools.projectWizard.core.entity.PipelineTask
import org.jetbrains.kotlin.tools.projectWizard.core.entity.settings.reference
import org.jetbrains.kotlin.tools.projectWizard.core.map
import org.jetbrains.kotlin.tools.projectWizard.core.service.ServicesManager
import org.jetbrains.kotlin.tools.projectWizard.core.service.WizardService
import org.jetbrains.kotlin.tools.projectWizard.phases.GenerationPhase
@@ -34,31 +34,29 @@ class ProjectTemplateBasedTestWizard(
servicesManager,
isUnitTestMode = true
) {
private val settingsWritingContext = SettingsWritingContext(context, servicesManager, isUnitTestMode = true)
override fun apply(
services: List<WizardService>,
phases: Set<GenerationPhase>,
onTaskExecuting: (PipelineTask) -> Unit
): TaskResult<Unit> =
computeM {
super.apply(services, setOf(GenerationPhase.PREPARE), onTaskExecuting).ensure()
with(settingsWritingContext) {
applyProjectTemplate(projectTemplate)
BuildSystemPlugin::type.reference.setValue(buildSystem.buildSystemType)
StructurePlugin::projectPath.reference.setValue(projectDirectory)
StructurePlugin::name.reference.setValue(projectTemplate.id)
StructurePlugin::groupId.reference.setValue(GROUP_ID)
StructurePlugin::artifactId.reference.setValue(ARTIFACT_ID)
applyAdditionalSettingsFromYaml().ensure()
}
super.apply(services, phases, onTaskExecuting)
): TaskResult<Unit> = computeM {
super.apply(services, setOf(GenerationPhase.PREPARE), onTaskExecuting).ensure()
context.writeSettings {
applyProjectTemplate(projectTemplate)
BuildSystemPlugin::type.reference.setValue(buildSystem.buildSystemType)
StructurePlugin::projectPath.reference.setValue(projectDirectory)
StructurePlugin::name.reference.setValue(projectTemplate.id)
StructurePlugin::groupId.reference.setValue(GROUP_ID)
StructurePlugin::artifactId.reference.setValue(ARTIFACT_ID)
}
applyAdditionalSettingsFromYaml().ensure()
private fun SettingsWritingContext.applyAdditionalSettingsFromYaml() = compute {
if (additionalYamlSettings != null) {
val (additionalSettings) = parseYaml(additionalYamlSettings, pluginSettings)
super.apply(services, phases, onTaskExecuting)
}
private fun applyAdditionalSettingsFromYaml() = context.writeSettings {
if (additionalYamlSettings == null) return@writeSettings UNIT_SUCCESS
parseYaml(additionalYamlSettings, pluginSettings).map { additionalSettings ->
additionalSettings.forEach { (reference, value) -> reference.setValue(value) }
}
}
@@ -1,7 +1,5 @@
package org.jetbrains.kotlin.tools.projectWizard.core
import org.jetbrains.kotlin.tools.projectWizard.core.context.ReadingContext
typealias Checker = ReadingContext.() -> Boolean
val ALWAYS_AVAILABLE_CHECKER = checker { true }
@@ -1,14 +1,95 @@
package org.jetbrains.kotlin.tools.projectWizard.core
import org.jetbrains.kotlin.tools.projectWizard.core.entity.*
import org.jetbrains.kotlin.tools.projectWizard.core.entity.settings.AnySetting
import org.jetbrains.kotlin.tools.projectWizard.core.entity.settings.SettingContext
import org.jetbrains.kotlin.tools.projectWizard.core.entity.settings.*
import org.jetbrains.kotlin.tools.projectWizard.core.service.ServicesManager
import org.jetbrains.kotlin.tools.projectWizard.core.service.SettingSavingWizardService
import org.jetbrains.kotlin.tools.projectWizard.core.service.WizardService
import org.jetbrains.kotlin.tools.projectWizard.phases.GenerationPhase
import kotlin.properties.ReadOnlyProperty
import kotlin.reflect.KClass
import kotlin.reflect.KProperty1
import kotlin.reflect.full.isSubclassOf
import kotlin.reflect.full.memberProperties
class Context(private val pluginsCreator: PluginsCreator, val eventManager: EventManager) {
class Context private constructor(
private val servicesManager: ServicesManager,
private val isUnitTestMode: Boolean,
private val settingContext: SettingContext,
private val propertyContext: PropertyContext,
private val taskContext: TaskContext
) {
private lateinit var plugins: List<Plugin>
private val settingWritingContext = SettingsWritingContext()
private val pluginSettings by lazy(LazyThreadSafetyMode.NONE) {
plugins.flatMap(Plugin::declaredSettings).distinctBy(PluginSetting<*, *>::path)
}
fun <T> read(reader: ReadingContext.() -> T): T =
settingWritingContext.reader()
fun <T> write(writer: WritingContext.() -> T): T =
settingWritingContext.writer()
fun <T> writeSettings(writer: SettingsWritingContext.() -> T): T =
settingWritingContext.writer()
constructor(
pluginsCreator: PluginsCreator,
servicesManager: ServicesManager,
isUnitTestMode: Boolean
) : this(
servicesManager,
isUnitTestMode,
SettingContext(),
PropertyContext(),
TaskContext()
) {
plugins = pluginsCreator(this).onEach(::initPlugin)
}
fun withAdditionalServices(services: List<WizardService>) =
Context(
servicesManager.withAdditionalServices(services),
isUnitTestMode,
settingContext,
propertyContext,
taskContext
).also {
it.plugins = plugins
}
fun <V : Any, T : SettingType<V>> pluginSettingDelegate(
create: (path: String) -> SettingBuilder<V, T>
): ReadOnlyProperty<Any, PluginSetting<V, T>> =
settingContext.settingDelegate(create)
fun <T : Any> propertyDelegate(
init: Property.Builder<T>.() -> Unit,
defaultValue: T
) = entityDelegate(propertyContext) { name ->
Property.Builder(name, defaultValue).apply(init).build()
}
fun pipelineTaskDelegate(
phase: GenerationPhase,
init: PipelineTask.Builder.() -> Unit
) = entityDelegate(taskContext) { name ->
PipelineTask.Builder(name, phase).apply(init).build()
}
fun <A, B : Any> task1Delegate(
init: Task1.Builder<A, B>.() -> Unit
) = entityDelegate(taskContext) { name ->
Task1.Builder<A, B>(name).apply(init).build()
}
private fun initPlugin(plugin: Plugin) {
for (entityReference in plugin::class.memberProperties) {
val type = entityReference.returnType.classifier.safeAs<KClass<*>>() ?: continue
@@ -23,32 +104,13 @@ class Context(private val pluginsCreator: PluginsCreator, val eventManager: Even
}
}
val settingContext =
SettingContext(eventManager::fireListeners)
val propertyContext = PropertyContext()
val taskContext = TaskContext()
val plugins = pluginsCreator(this).onEach(::initPlugin)
@Suppress("UNUSED_PARAMETER")
fun getUnspecifiedSettings(phases: Set<GenerationPhase>): List<AnySetting> {
val required = plugins
.flatMap { plugin ->
plugin.declaredSettings.mapNotNull { setting ->
if (setting.neededAtPhase !in phases) return@mapNotNull null
if (setting.isRequired) setting else null
}
}.toSet()
val provided = settingContext.allPluginSettings.map { it.path }.toSet()
return required.filterNot { it.path in provided }
}
private val pipelineLineTasks: List<PipelineTask>
get() = plugins
.flatMap { it.declaredTasks.filterIsInstance<PipelineTask>() }
private fun task(reference: PipelineTaskReference) =
taskContext.getEntity(reference) as? PipelineTask
?: error(reference.path)
taskContext.getEntity(reference) as? PipelineTask ?: error(reference.path)
private val dependencyList: Map<PipelineTask, List<PipelineTask>>
get() {
@@ -67,8 +129,123 @@ class Context(private val pluginsCreator: PluginsCreator, val eventManager: Even
}
}
fun copy() = Context(pluginsCreator, eventManager)
fun sortTasks(): TaskResult<List<PipelineTask>> =
TaskSorter().sort(pipelineLineTasks, dependencyList)
open inner class ReadingContext {
val plugins: List<Plugin>
get() = this@Context.plugins
val pluginSettings: List<PluginSetting<*, *>>
get() = this@Context.pluginSettings
val isUnitTestMode: Boolean
get() = this@Context.isUnitTestMode
inline fun <reified S : WizardService> service(noinline filter: (S) -> Boolean = { true }): S =
serviceByClass(S::class, filter)
fun <S : WizardService> serviceByClass(klass: KClass<S>, filter: (S) -> Boolean = { true }): S =
servicesManager.serviceByClass(klass, filter) ?: error("Service ${klass.simpleName} was not found")
@Suppress("UNCHECKED_CAST")
val <T : Any> PropertyReference<T>.propertyValue: T
get() = propertyContext[this] as T
val <V : Any, T : SettingType<V>> SettingReference<V, T>.settingValue: V
get() = settingContext[this] ?: error("No value is present for setting `$this`")
inline val <reified V : Any> KProperty1<out Plugin, PluginSetting<V, SettingType<V>>>.settingValue: V
get() = reference.settingValue
inline fun <reified V : Any> KProperty1<out Plugin, PluginSetting<V, SettingType<V>>>.settingValue(): V =
this.reference.settingValue
fun <V : Any, T : SettingType<V>> SettingReference<V, T>.settingValue(): V =
settingContext[this] ?: error("No value is present for setting `$this`")
val <V : Any, T : SettingType<V>> SettingReference<V, T>.notRequiredSettingValue: V?
get() = settingContext[this]
fun <V : Any, T : SettingType<V>> SettingReference<V, T>.notRequiredSettingValue(): V? =
settingContext[this]
val <V : Any, T : SettingType<V>> PluginSettingReference<V, T>.pluginSetting: Setting<V, T>
get() = settingContext.getPluginSetting(this)
private fun <V : Any> Setting<V, SettingType<V>>.getSavedValueForSetting(): V? {
if (!isSavable || this !is PluginSetting<*, *>) return null
val serializer = type.serializer.safeAs<SettingSerializer.Serializer<V>>() ?: return null
val savedValue = service<SettingSavingWizardService>().getSettingValue(path) ?: return null
return serializer.fromString(savedValue)
}
val <V : Any> SettingReference<V, SettingType<V>>.savedOrDefaultValue: V?
get() = setting.getSavedValueForSetting() ?: when (val defaultValue = setting.defaultValue) {
is SettingDefaultValue.Value -> defaultValue.value
is SettingDefaultValue.Dynamic<V> -> defaultValue.getter(this@ReadingContext, this)
null -> null
}
val <V : Any, T : SettingType<V>> SettingReference<V, T>.setting: Setting<V, T>
get() = with(this) { getSetting() }
}
open inner class WritingContext : ReadingContext() {
val eventManager: EventManager
get() = settingContext.eventManager
fun <A, B : Any> Task1Reference<A, B>.execute(value: A): TaskResult<B> {
@Suppress("UNCHECKED_CAST")
val task = taskContext.getEntity(this) as Task1<A, B>
return task.action(this@WritingContext, value)
}
fun <T : Any> PropertyReference<T>.update(
updater: suspend ComputeContext<*>.(T) -> TaskResult<T>
): TaskResult<Unit> = compute {
val (newValue) = updater(propertyValue)
propertyContext[this@update] = newValue
}
fun <T : Any> PropertyReference<List<T>>.addValues(
vararg values: T
): TaskResult<Unit> = update { oldValues -> success(oldValues + values) }
fun <T : Any> PropertyReference<List<T>>.addValues(
values: List<T>
): TaskResult<Unit> = update { oldValues -> success(oldValues + values) }
}
open inner class SettingsWritingContext : WritingContext() {
fun <V : Any, T : SettingType<V>> SettingReference<V, T>.setValue(newValue: V) {
settingContext[this] = newValue
}
fun <V : Any, T : SettingType<V>> SettingReference<V, T>.setSettingValueToItsDefaultIfItIsNotSetValue() {
val defaultValue = savedOrDefaultValue ?: return
if (notRequiredSettingValue == null) {
setValue(defaultValue)
}
}
}
}
fun ReadingContext.getUnspecifiedSettings(phases: Set<GenerationPhase>): List<AnySetting> {
val required = plugins
.flatMap { plugin ->
plugin.declaredSettings.mapNotNull { setting ->
if (setting.neededAtPhase !in phases) return@mapNotNull null
if (setting.isRequired) setting else null
}
}.toSet()
val provided = pluginSettings.map(PluginSetting<*, *>::path).toSet()
return required.filterNot { it.path in provided }
}
typealias ReadingContext = Context.ReadingContext
typealias WritingContext = Context.WritingContext
typealias SettingsWritingContext = Context.SettingsWritingContext
@@ -10,7 +10,6 @@ import org.jetbrains.kotlin.tools.projectWizard.settings.version.Version
import java.nio.file.Path
import kotlin.properties.ReadOnlyProperty
import kotlin.reflect.KClass
import kotlin.reflect.KProperty
import kotlin.reflect.full.isSubclassOf
import kotlin.reflect.full.memberProperties
@@ -28,17 +27,7 @@ abstract class Plugin(override val context: Context) : EntityBase(),
override fun <V : Any, T : SettingType<V>> settingDelegate(
create: (path: String) -> SettingBuilder<V, T>
): ReadOnlyProperty<Any, PluginSetting<V, T>> = object : ReadOnlyProperty<Any, PluginSetting<V, T>> {
override fun getValue(thisRef: Any, property: KProperty<*>): PluginSetting<V, T> {
@Suppress("UNCHECKED_CAST")
val reference = property as PluginSettingPropertyReference<V, T>
context.settingContext.getPluginSetting(reference)?.let { return it }
val setting =
PluginSetting(create(reference.path).buildInternal())
context.settingContext.setPluginSetting(reference, setting)
return setting
}
}
): ReadOnlyProperty<Any, PluginSetting<V, T>> = context.pluginSettingDelegate(create)
val reference = this::class
override val path = reference.path
@@ -47,7 +36,6 @@ abstract class Plugin(override val context: Context) : EntityBase(),
val declaredSettings get() = entitiesOfType<PluginSetting<*, *>>().toSet()
val declaredTasks get() = entitiesOfType<Task>()
private inline fun <reified E : Entity> entitiesOfType() =
reference.memberProperties.filter { kProperty ->
kProperty.returnType.classifier.safeAs<KClass<*>>()?.isSubclassOf(E::class) == true
@@ -56,13 +44,13 @@ abstract class Plugin(override val context: Context) : EntityBase(),
}
fun pipelineTask(phase: GenerationPhase, init: PipelineTask.Builder.() -> Unit) =
PipelineTask.delegate(context.taskContext, phase, init)
context.pipelineTaskDelegate(phase, init)
fun <A, B : Any> task1(init: Task1.Builder<A, B>.() -> Unit) =
Task1.delegate(context.taskContext, init)
context.task1Delegate(init)
fun <T : Any> property(defaultValue: T, init: Property.Builder<T>.() -> Unit = {}) =
propertyDelegate(context.propertyContext, init, defaultValue)
context.propertyDelegate(init, defaultValue)
fun <T : Any> listProperty(vararg defaultValues: T, init: Property.Builder<List<T>>.() -> Unit = {}) =
property(defaultValues.toList(), init)
@@ -168,9 +156,9 @@ abstract class Plugin(override val context: Context) : EntityBase(),
val PluginReference.withParentPlugins
get() = generateSequence(this) { klass ->
klass.supertypes.firstOrNull { supertype ->
supertype.classifier?.safeAs<KClass<Plugin>>()
?.isSubclassOf(Plugin::class) == true
}?.classifier
supertype.classifier?.safeAs<KClass<Plugin>>()
?.isSubclassOf(Plugin::class) == true
}?.classifier
?.safeAs<KClass<Plugin>>()
?.takeIf { superClass ->
superClass.simpleName != null
@@ -185,8 +173,8 @@ val PluginReference.name
val PluginReference.path
get() = withParentPlugins.mapNotNull { klass ->
klass.name.takeIf { it.isNotEmpty() }
}.toList()
klass.name.takeIf { it.isNotEmpty() }
}.toList()
.reversed()
.joinToString(".")
@@ -1,13 +1,5 @@
package org.jetbrains.kotlin.tools.projectWizard.core
import kotlin.coroutines.Continuation
import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.EmptyCoroutineContext
import kotlin.coroutines.intrinsics.COROUTINE_SUSPENDED
import kotlin.coroutines.intrinsics.createCoroutineUnintercepted
import kotlin.coroutines.intrinsics.suspendCoroutineUninterceptedOrReturn
import kotlin.coroutines.resume
sealed class TaskResult<out T : Any>
data class Success<T : Any>(val value: T) : TaskResult<T>()
@@ -1,74 +0,0 @@
/*
* Copyright 2010-2020 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.context
import org.jetbrains.kotlin.tools.projectWizard.core.Context
import org.jetbrains.kotlin.tools.projectWizard.core.Plugin
import org.jetbrains.kotlin.tools.projectWizard.core.entity.*
import org.jetbrains.kotlin.tools.projectWizard.core.entity.settings.*
import org.jetbrains.kotlin.tools.projectWizard.core.safeAs
import org.jetbrains.kotlin.tools.projectWizard.core.service.WizardService
import org.jetbrains.kotlin.tools.projectWizard.core.service.ServicesManager
import org.jetbrains.kotlin.tools.projectWizard.core.service.SettingSavingWizardService
import kotlin.reflect.KClass
import kotlin.reflect.KProperty1
open class ReadingContext(
protected val context: Context,
private val servicesManager: ServicesManager,
val isUnitTestMode: Boolean
) {
inline fun <reified S : WizardService> service(noinline filter: (S) -> Boolean = { true }): S =
serviceByClass(S::class, filter)
fun <S : WizardService> serviceByClass(klass: KClass<S>, filter: (S) -> Boolean = { true }): S =
servicesManager.serviceByClass(klass, filter) ?: error("Service ${klass.simpleName} was not found")
inline val <reified T : Any> PropertyReference<T>.propertyValue: T
get() = `access$context`.propertyContext[this] as T
inline val <reified V : Any, T : SettingType<V>> SettingReference<V, T>.settingValue: V
get() = `access$context`.settingContext[this] ?: error("No value is present for setting `$this`")
inline val <reified V : Any> KProperty1<out Plugin, PluginSetting<V, SettingType<V>>>.settingValue: V
get() = reference.settingValue
inline fun <reified V : Any> KProperty1<out Plugin, PluginSetting<V, SettingType<V>>>.settingValue(): V =
this.reference.settingValue
inline fun <reified V : Any, T : SettingType<V>> SettingReference<V, T>.settingValue(): V =
`access$context`.settingContext[this] ?: error("No value is present for setting `$this`")
val <V : Any, T : SettingType<V>> SettingReference<V, T>.notRequiredSettingValue: V?
get() = context.settingContext[this]
fun <V : Any, T : SettingType<V>> SettingReference<V, T>.notRequiredSettingValue(): V? =
context.settingContext[this]
val <V : Any, T : SettingType<V>> PluginSettingReference<V, T>.pluginSetting: Setting<V, T>
get() = context.settingContext.getPluginSetting(this)
private fun <V : Any> Setting<V, SettingType<V>>.getSavedValueForSetting(): V? {
if (!isSavable || this !is PluginSetting<*, *>) return null
val serializer = type.serializer.safeAs<SettingSerializer.Serializer<V>>() ?: return null
val savedValue = service<SettingSavingWizardService>().getSettingValue(path) ?: return null
return serializer.fromString(savedValue)
}
val <V : Any> SettingReference<V, SettingType<V>>.savedOrDefaultValue: V?
get() = setting.getSavedValueForSetting() ?: when (val defaultValue = setting.defaultValue) {
is SettingDefaultValue.Value -> defaultValue.value
is SettingDefaultValue.Dynamic<V> -> defaultValue.getter(this@ReadingContext, this)
null -> null
}
val <V : Any, T : SettingType<V>> SettingReference<V, T>.setting: Setting<V, T>
get() = with(this) { getSetting() }
@PublishedApi
internal val `access$context`: Context
get() = context
}
@@ -1,31 +0,0 @@
/*
* Copyright 2010-2020 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.context
import org.jetbrains.kotlin.tools.projectWizard.core.Context
import org.jetbrains.kotlin.tools.projectWizard.core.entity.settings.SettingReference
import org.jetbrains.kotlin.tools.projectWizard.core.entity.settings.SettingType
import org.jetbrains.kotlin.tools.projectWizard.core.service.ServicesManager
open class SettingsWritingContext(context: Context, servicesManager: ServicesManager, isUnitTestMode: Boolean) :
WritingContext(
context,
servicesManager,
isUnitTestMode
) {
fun <V : Any, T : SettingType<V>> SettingReference<V, T>.setValue(newValue: V) {
context.settingContext[this] = newValue
}
fun <V : Any, T : SettingType<V>> SettingReference<V, T>.setSettingValueToItsDefaultIfItIsNotSetValue() {
val defaultValue = savedOrDefaultValue ?: return
if (notRequiredSettingValue == null) {
setValue(defaultValue)
}
}
}
@@ -1,39 +0,0 @@
/*
* Copyright 2010-2020 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.context
import 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.ServicesManager
open class WritingContext(
context: Context,
servicesManager: ServicesManager,
isUnitTestMode: Boolean
) : ReadingContext(context, servicesManager, isUnitTestMode) {
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>
return task.action(this@WritingContext, value)
}
inline fun <reified T : Any> PropertyReference<T>.update(
crossinline updater: suspend ComputeContext<*>.(T) -> TaskResult<T>
): TaskResult<Unit> = compute {
val (newValue) = updater(propertyValue)
`access$context`.propertyContext[this@update] = newValue
}
fun <T : Any> PropertyReference<List<T>>.addValues(
vararg values: T
): TaskResult<Unit> = update { oldValues -> success(oldValues + values) }
fun <T : Any> PropertyReference<List<T>>.addValues(
values: List<T>
): TaskResult<Unit> = update { oldValues -> success(oldValues + values) }
}
@@ -1,7 +1,6 @@
package org.jetbrains.kotlin.tools.projectWizard.core.entity
import org.jetbrains.kotlin.tools.projectWizard.SettingsOwner
import org.jetbrains.kotlin.tools.projectWizard.core.Plugin
import org.jetbrains.kotlin.tools.projectWizard.core.PluginReference
import org.jetbrains.kotlin.tools.projectWizard.core.path
import org.jetbrains.kotlin.tools.projectWizard.core.safeAs
@@ -1,7 +1,6 @@
package org.jetbrains.kotlin.tools.projectWizard.core.entity
import org.jetbrains.kotlin.tools.projectWizard.core.Plugin
import org.jetbrains.kotlin.tools.projectWizard.core.PluginReference
import kotlin.reflect.KProperty1
typealias PropertyReference<T> = KProperty1<out Plugin, Property<T>>
@@ -20,12 +19,3 @@ data class Property<out T : Any>(
fun build(): Property<T> = Property(name, defaultValue)
}
}
fun <T : Any> propertyDelegate(
context: PropertyContext,
init: Property.Builder<T>.() -> Unit,
defaultValue: T
) = entityDelegate(context) { name ->
Property.Builder(name, defaultValue).apply(init).build()
}
@@ -1,9 +1,10 @@
package org.jetbrains.kotlin.tools.projectWizard.core.entity
import org.jetbrains.kotlin.tools.projectWizard.core.Failure
import org.jetbrains.kotlin.tools.projectWizard.core.ReadingContext
import org.jetbrains.kotlin.tools.projectWizard.core.UNIT_SUCCESS
import org.jetbrains.kotlin.tools.projectWizard.core.ValidationError
import org.jetbrains.kotlin.tools.projectWizard.core.context.ReadingContext
inline class SettingValidator<V>(val validate: ReadingContext.(V) -> ValidationResult) {
infix fun and(other: SettingValidator<V>) = SettingValidator<V> { value ->
@@ -1,6 +1,6 @@
package org.jetbrains.kotlin.tools.projectWizard.core.entity
import org.jetbrains.kotlin.tools.projectWizard.core.context.WritingContext
import org.jetbrains.kotlin.tools.projectWizard.core.*
import org.jetbrains.kotlin.tools.projectWizard.phases.GenerationPhase
import kotlin.reflect.KProperty1
@@ -26,15 +26,6 @@ data class Task1<A, B : Any>(
fun build(): Task1<A, B> = Task1(name, action)
}
companion object {
fun <A, B : Any> delegate(
context: EntityContext<Task, TaskReference>,
init: Builder<A, B>.() -> Unit
) = entityDelegate(context) { name ->
Builder<A, B>(name).apply(init).build()
}
}
}
data class PipelineTask(
@@ -72,14 +63,4 @@ data class PipelineTask(
fun build(): PipelineTask = PipelineTask(name, action, before, after, phase, isAvailable, title)
}
companion object {
fun delegate(
context: EntityContext<Task, TaskReference>,
phase: GenerationPhase,
init: Builder.() -> Unit
) = entityDelegate(context) { name ->
Builder(name, phase).apply(init).build()
}
}
}
@@ -7,7 +7,8 @@ package org.jetbrains.kotlin.tools.projectWizard.core.entity.settings
import org.jetbrains.kotlin.tools.projectWizard.core.ActivityCheckerOwner
import org.jetbrains.kotlin.tools.projectWizard.core.Checker
import org.jetbrains.kotlin.tools.projectWizard.core.context.ReadingContext
import org.jetbrains.kotlin.tools.projectWizard.core.ReadingContext
import org.jetbrains.kotlin.tools.projectWizard.core.entity.Entity
import org.jetbrains.kotlin.tools.projectWizard.core.entity.EntityWithValue
import org.jetbrains.kotlin.tools.projectWizard.core.entity.SettingValidator
@@ -5,7 +5,8 @@
package org.jetbrains.kotlin.tools.projectWizard.core.entity.settings
import org.jetbrains.kotlin.tools.projectWizard.core.context.ReadingContext
import org.jetbrains.kotlin.tools.projectWizard.core.ReadingContext
import org.jetbrains.kotlin.tools.projectWizard.core.entity.SettingValidator
import org.jetbrains.kotlin.tools.projectWizard.core.entity.ValidationResult
import org.jetbrains.kotlin.tools.projectWizard.core.entity.settingValidator
@@ -5,11 +5,15 @@
package org.jetbrains.kotlin.tools.projectWizard.core.entity.settings
import org.jetbrains.kotlin.tools.projectWizard.core.EventManager
import org.jetbrains.kotlin.tools.projectWizard.core.entity.path
import kotlin.properties.ReadOnlyProperty
import kotlin.reflect.KProperty
class SettingContext(val onUpdated: (SettingReference<*, *>) -> Unit) {
class SettingContext {
private val values = mutableMapOf<String, Any>()
private val pluginSettings = mutableMapOf<String, PluginSetting<*, *>>()
val eventManager = EventManager()
@Suppress("UNCHECKED_CAST")
operator fun <V : Any, T : SettingType<V>> get(
@@ -21,30 +25,34 @@ class SettingContext(val onUpdated: (SettingReference<*, *>) -> Unit) {
newValue: V
) {
values[reference.path] = newValue
onUpdated(reference)
eventManager.fireListeners(reference)
}
val allPluginSettings: Collection<PluginSetting<*, *>>
get() = pluginSettings.values
@Suppress("UNCHECKED_CAST")
fun <V : Any, T : SettingType<V>> getPluginSetting(pluginSettingReference: PluginSettingReference<V, T>) =
pluginSettings[pluginSettingReference.path] as PluginSetting<V, T>
@Suppress("UNCHECKED_CAST")
fun <V : Any, T : SettingType<V>> getPluginSetting(pluginSettingReference: PluginSettingPropertyReference<V, T>) =
private fun <V : Any, T : SettingType<V>> getPluginSetting(pluginSettingReference: PluginSettingPropertyReference<V, T>) =
pluginSettings[pluginSettingReference.path] as? PluginSetting<V, T>
@Suppress("UNCHECKED_CAST")
fun <V : Any, T : SettingType<V>> setPluginSetting(
private fun <V : Any, T : SettingType<V>> setPluginSetting(
pluginSettingReference: PluginSettingPropertyReference<V, T>,
setting: PluginSetting<V, T>
) {
pluginSettings[pluginSettingReference.path] = setting
}
@Suppress("UNCHECKED_CAST")
fun <V : Any, T : SettingType<V>> pluginSettingValue(setting: PluginSetting<V, T>): V? =
values[setting.path] as? V
fun <V : Any, T : SettingType<V>> settingDelegate(
create: (path: String) -> SettingBuilder<V, T>
): ReadOnlyProperty<Any, PluginSetting<V, T>> = object : ReadOnlyProperty<Any, PluginSetting<V, T>> {
override fun getValue(thisRef: Any, property: KProperty<*>): PluginSetting<V, T> {
@Suppress("UNCHECKED_CAST")
val reference = property as PluginSettingPropertyReference<V, T>
getPluginSetting(reference)?.let { return it }
val setting = PluginSetting(create(reference.path).buildInternal())
setPluginSetting(reference, setting)
return setting
}
}
}
@@ -7,8 +7,8 @@ package org.jetbrains.kotlin.tools.projectWizard.core.entity.settings
import org.jetbrains.kotlin.tools.projectWizard.Identificator
import org.jetbrains.kotlin.tools.projectWizard.core.Plugin
import org.jetbrains.kotlin.tools.projectWizard.core.context.ReadingContext
import org.jetbrains.kotlin.tools.projectWizard.core.entity.*
import org.jetbrains.kotlin.tools.projectWizard.core.ReadingContext
import org.jetbrains.kotlin.tools.projectWizard.core.entity.path
import org.jetbrains.kotlin.tools.projectWizard.core.safeAs
import org.jetbrains.kotlin.tools.projectWizard.moduleConfigurators.ModuleConfigurator
import org.jetbrains.kotlin.tools.projectWizard.settings.buildsystem.Module
@@ -6,7 +6,7 @@
package org.jetbrains.kotlin.tools.projectWizard.core.entity.settings
import org.jetbrains.kotlin.tools.projectWizard.core.*
import org.jetbrains.kotlin.tools.projectWizard.core.context.ReadingContext
import org.jetbrains.kotlin.tools.projectWizard.core.entity.*
import org.jetbrains.kotlin.tools.projectWizard.phases.GenerationPhase
import org.jetbrains.kotlin.tools.projectWizard.settings.DisplayableSettingItem
@@ -5,7 +5,8 @@
package org.jetbrains.kotlin.tools.projectWizard.core.service
import org.jetbrains.kotlin.tools.projectWizard.core.context.ReadingContext
import org.jetbrains.kotlin.tools.projectWizard.core.ReadingContext
import org.jetbrains.kotlin.tools.projectWizard.plugins.buildSystem.BuildSystemType
interface BuildSystemAvailabilityWizardService : WizardService {
@@ -6,7 +6,8 @@
package org.jetbrains.kotlin.tools.projectWizard.core.service
import org.jetbrains.kotlin.tools.projectWizard.WizardRunConfiguration
import org.jetbrains.kotlin.tools.projectWizard.core.context.ReadingContext
import org.jetbrains.kotlin.tools.projectWizard.core.ReadingContext
interface RunConfigurationsService : WizardService {
fun ReadingContext.addRunConfigurations(configurations: List<WizardRunConfiguration>)
@@ -8,13 +8,16 @@ 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?) {
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>) =
fun withAdditionalServices(services: List<WizardService>) =
ServicesManager(this.services + services, serviceSelector)
}
@@ -4,7 +4,6 @@ import kotlinx.collections.immutable.toPersistentList
import java.io.IOException
import java.nio.file.Path
import java.nio.file.Paths
import java.util.*
import kotlin.properties.ReadOnlyProperty
import kotlin.random.Random
import kotlin.reflect.KProperty
@@ -2,7 +2,6 @@ package org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem
import kotlinx.collections.immutable.PersistentList
import org.jetbrains.kotlin.tools.projectWizard.core.*
import org.jetbrains.kotlin.tools.projectWizard.core.safeAs
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.gradle.*
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.gradle.multiplatform.DefaultTargetConfigurationIR
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.gradle.multiplatform.TargetConfigurationIR
@@ -1,6 +1,8 @@
package org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem
import kotlinx.collections.immutable.*
import kotlinx.collections.immutable.PersistentList
import kotlinx.collections.immutable.plus
import kotlinx.collections.immutable.toPersistentList
interface IrsOwner {
@@ -2,14 +2,11 @@ package org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem
import kotlinx.collections.immutable.PersistentList
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.gradle.GradleIR
import org.jetbrains.kotlin.tools.projectWizard.plugins.kotlin.ModuleType
import org.jetbrains.kotlin.tools.projectWizard.plugins.printer.BuildFilePrinter
import org.jetbrains.kotlin.tools.projectWizard.plugins.printer.GradlePrinter
import org.jetbrains.kotlin.tools.projectWizard.plugins.printer.MavenPrinter
import org.jetbrains.kotlin.tools.projectWizard.settings.buildsystem.Module
import org.jetbrains.kotlin.tools.projectWizard.settings.buildsystem.ModuleKind
import org.jetbrains.kotlin.tools.projectWizard.settings.buildsystem.Sourceset
import org.jetbrains.kotlin.tools.projectWizard.settings.buildsystem.SourcesetType
import org.jetbrains.kotlin.tools.projectWizard.templates.Template
import java.nio.file.Path
@@ -1,6 +1,9 @@
package org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.gradle
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.*
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.BuildSystemIR
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.FreeIR
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.RepositoryIR
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.render
import org.jetbrains.kotlin.tools.projectWizard.plugins.printer.BuildFilePrinter
import org.jetbrains.kotlin.tools.projectWizard.plugins.printer.GradlePrinter
@@ -5,31 +5,30 @@
package org.jetbrains.kotlin.tools.projectWizard.moduleConfigurators
import org.jetbrains.kotlin.tools.projectWizard.Versions
import org.jetbrains.kotlin.tools.projectWizard.core.context.ReadingContext
import org.jetbrains.kotlin.tools.projectWizard.core.context.WritingContext
import org.jetbrains.kotlin.tools.projectWizard.core.*
import org.jetbrains.kotlin.tools.projectWizard.core.entity.settings.SettingType
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.gradle.AndroidConfigIR
import org.jetbrains.kotlin.tools.projectWizard.plugins.AndroidPlugin
import org.jetbrains.kotlin.tools.projectWizard.plugins.kotlin.ModuleConfigurationData
import org.jetbrains.kotlin.tools.projectWizard.plugins.kotlin.ModuleType
import org.jetbrains.kotlin.tools.projectWizard.settings.buildsystem.Module
import org.jetbrains.kotlin.tools.projectWizard.settings.javaPackage
import org.jetbrains.kotlin.tools.projectWizard.core.entity.settings.ModuleConfiguratorSetting
import org.jetbrains.kotlin.tools.projectWizard.core.entity.settings.PluginSettingReference
import org.jetbrains.kotlin.tools.projectWizard.core.entity.settings.SettingType
import org.jetbrains.kotlin.tools.projectWizard.core.entity.settings.reference
import org.jetbrains.kotlin.tools.projectWizard.core.service.kotlinVersionKind
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.*
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.gradle.AndroidConfigIR
import org.jetbrains.kotlin.tools.projectWizard.library.MavenArtifact
import org.jetbrains.kotlin.tools.projectWizard.phases.GenerationPhase
import org.jetbrains.kotlin.tools.projectWizard.plugins.AndroidPlugin
import org.jetbrains.kotlin.tools.projectWizard.plugins.kotlin.KotlinPlugin
import org.jetbrains.kotlin.tools.projectWizard.plugins.kotlin.ModuleConfigurationData
import org.jetbrains.kotlin.tools.projectWizard.plugins.kotlin.ModuleSubType
import org.jetbrains.kotlin.tools.projectWizard.plugins.kotlin.ModuleType
import org.jetbrains.kotlin.tools.projectWizard.plugins.templates.TemplatesPlugin
import org.jetbrains.kotlin.tools.projectWizard.settings.DisplayableSettingItem
import org.jetbrains.kotlin.tools.projectWizard.settings.JavaPackage
import org.jetbrains.kotlin.tools.projectWizard.settings.buildsystem.DefaultRepository
import org.jetbrains.kotlin.tools.projectWizard.settings.buildsystem.Module
import org.jetbrains.kotlin.tools.projectWizard.settings.buildsystem.Repository
import org.jetbrains.kotlin.tools.projectWizard.settings.javaPackage
import org.jetbrains.kotlin.tools.projectWizard.settings.version.Version
import org.jetbrains.kotlin.tools.projectWizard.templates.FileTemplate
import org.jetbrains.kotlin.tools.projectWizard.templates.FileTemplateDescriptor
@@ -1,7 +1,7 @@
package org.jetbrains.kotlin.tools.projectWizard.moduleConfigurators
import org.jetbrains.kotlin.tools.projectWizard.core.context.ReadingContext
import org.jetbrains.kotlin.tools.projectWizard.core.context.WritingContext
import org.jetbrains.kotlin.tools.projectWizard.core.*
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.*
import org.jetbrains.kotlin.tools.projectWizard.library.MavenArtifact
@@ -5,15 +5,12 @@
package org.jetbrains.kotlin.tools.projectWizard.moduleConfigurators
import org.jetbrains.kotlin.tools.projectWizard.core.TaskResult
import org.jetbrains.kotlin.tools.projectWizard.core.asPath
import org.jetbrains.kotlin.tools.projectWizard.core.context.WritingContext
import org.jetbrains.kotlin.tools.projectWizard.core.*
import org.jetbrains.kotlin.tools.projectWizard.plugins.kotlin.ModuleConfigurationData
import org.jetbrains.kotlin.tools.projectWizard.plugins.templates.TemplatesPlugin
import org.jetbrains.kotlin.tools.projectWizard.settings.buildsystem.Module
import org.jetbrains.kotlin.tools.projectWizard.settings.buildsystem.ModuleKind
import org.jetbrains.kotlin.tools.projectWizard.core.buildList
import org.jetbrains.kotlin.tools.projectWizard.core.div
import org.jetbrains.kotlin.tools.projectWizard.templates.FileTemplate
import org.jetbrains.kotlin.tools.projectWizard.templates.FileTemplateDescriptor
import java.nio.file.Path
@@ -5,7 +5,8 @@
package org.jetbrains.kotlin.tools.projectWizard.moduleConfigurators
import org.jetbrains.kotlin.tools.projectWizard.core.context.ReadingContext
import org.jetbrains.kotlin.tools.projectWizard.core.ReadingContext
import org.jetbrains.kotlin.tools.projectWizard.core.buildList
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.BuildSystemIR
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.KotlinBuildSystemPluginIR
@@ -1,12 +1,9 @@
package org.jetbrains.kotlin.tools.projectWizard.moduleConfigurators
import org.jetbrains.kotlin.tools.projectWizard.Identificator
import org.jetbrains.kotlin.tools.projectWizard.SettingsOwner
import org.jetbrains.kotlin.tools.projectWizard.core.context.ReadingContext
import org.jetbrains.kotlin.tools.projectWizard.core.context.WritingContext
import org.jetbrains.kotlin.tools.projectWizard.core.*
import org.jetbrains.kotlin.tools.projectWizard.core.cached
import org.jetbrains.kotlin.tools.projectWizard.core.context.SettingsWritingContext
import org.jetbrains.kotlin.tools.projectWizard.core.entity.settings.*
import org.jetbrains.kotlin.tools.projectWizard.enumSettingImpl
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.BuildSystemIR
@@ -16,7 +13,8 @@ import org.jetbrains.kotlin.tools.projectWizard.phases.GenerationPhase
import org.jetbrains.kotlin.tools.projectWizard.plugins.kotlin.ModuleConfigurationData
import org.jetbrains.kotlin.tools.projectWizard.plugins.kotlin.correspondingStdlib
import org.jetbrains.kotlin.tools.projectWizard.settings.DisplayableSettingItem
import org.jetbrains.kotlin.tools.projectWizard.settings.buildsystem.*
import org.jetbrains.kotlin.tools.projectWizard.settings.buildsystem.Module
import org.jetbrains.kotlin.tools.projectWizard.settings.buildsystem.ModuleKind
import org.jetbrains.kotlin.tools.projectWizard.settings.version.Version
import java.nio.file.Path
import kotlin.properties.ReadOnlyProperty
@@ -5,7 +5,8 @@
package org.jetbrains.kotlin.tools.projectWizard.moduleConfigurators
import org.jetbrains.kotlin.tools.projectWizard.core.context.ReadingContext
import org.jetbrains.kotlin.tools.projectWizard.core.ReadingContext
import org.jetbrains.kotlin.tools.projectWizard.core.entity.settings.ModuleConfiguratorSetting
import org.jetbrains.kotlin.tools.projectWizard.core.entity.settings.ModuleConfiguratorSettingReference
import org.jetbrains.kotlin.tools.projectWizard.core.safeAs
@@ -1,7 +1,8 @@
package org.jetbrains.kotlin.tools.projectWizard.moduleConfigurators
import kotlinx.collections.immutable.toPersistentList
import org.jetbrains.kotlin.tools.projectWizard.core.context.ReadingContext
import org.jetbrains.kotlin.tools.projectWizard.core.ReadingContext
import org.jetbrains.kotlin.tools.projectWizard.core.buildList
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.BuildSystemIR
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.gradle.CreateGradleValueIR
@@ -1,7 +1,8 @@
package org.jetbrains.kotlin.tools.projectWizard.moduleConfigurators
import kotlinx.collections.immutable.toPersistentList
import org.jetbrains.kotlin.tools.projectWizard.core.context.ReadingContext
import org.jetbrains.kotlin.tools.projectWizard.core.ReadingContext
import org.jetbrains.kotlin.tools.projectWizard.core.buildList
import org.jetbrains.kotlin.tools.projectWizard.core.buildPersistenceList
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.BuildSystemIR
@@ -1,21 +1,22 @@
package org.jetbrains.kotlin.tools.projectWizard.moduleConfigurators
import org.jetbrains.kotlin.tools.projectWizard.core.context.ReadingContext
import org.jetbrains.kotlin.tools.projectWizard.core.ReadingContext
import org.jetbrains.kotlin.tools.projectWizard.core.buildList
import org.jetbrains.kotlin.tools.projectWizard.core.entity.settings.ModuleConfiguratorSetting
import org.jetbrains.kotlin.tools.projectWizard.core.safeAs
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.BuildSystemIR
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.KotlinBuildSystemPluginIR
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.gradle.*
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.maven.MavenPropertyIR
import org.jetbrains.kotlin.tools.projectWizard.phases.GenerationPhase
import org.jetbrains.kotlin.tools.projectWizard.plugins.buildSystem.BuildSystemType
import org.jetbrains.kotlin.tools.projectWizard.plugins.buildSystem.isGradle
import org.jetbrains.kotlin.tools.projectWizard.plugins.kotlin.ModuleConfigurationData
import org.jetbrains.kotlin.tools.projectWizard.plugins.kotlin.ModuleType
import org.jetbrains.kotlin.tools.projectWizard.settings.DisplayableSettingItem
import org.jetbrains.kotlin.tools.projectWizard.settings.buildsystem.Module
import org.jetbrains.kotlin.tools.projectWizard.settings.buildsystem.ModuleKind
import org.jetbrains.kotlin.tools.projectWizard.core.buildList
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.gradle.*
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.maven.MavenPropertyIR
import org.jetbrains.kotlin.tools.projectWizard.plugins.buildSystem.BuildSystemType
import org.jetbrains.kotlin.tools.projectWizard.plugins.buildSystem.isGradle
interface JvmModuleConfigurator : ModuleConfiguratorWithTests {
companion object : ModuleConfiguratorSettings() {
@@ -1,7 +1,7 @@
package org.jetbrains.kotlin.tools.projectWizard.plugins
import org.jetbrains.kotlin.tools.projectWizard.core.context.ReadingContext
import org.jetbrains.kotlin.tools.projectWizard.core.context.WritingContext
import org.jetbrains.kotlin.tools.projectWizard.core.*
import org.jetbrains.kotlin.tools.projectWizard.core.entity.StringValidators
import org.jetbrains.kotlin.tools.projectWizard.core.entity.settings.reference
@@ -1,7 +1,7 @@
package org.jetbrains.kotlin.tools.projectWizard.plugins.buildSystem
import org.jetbrains.kotlin.tools.projectWizard.core.context.ReadingContext
import org.jetbrains.kotlin.tools.projectWizard.core.context.WritingContext
import org.jetbrains.kotlin.tools.projectWizard.core.*
import org.jetbrains.kotlin.tools.projectWizard.core.entity.ValidationResult
import org.jetbrains.kotlin.tools.projectWizard.core.entity.settings.reference
@@ -1,6 +1,6 @@
package org.jetbrains.kotlin.tools.projectWizard.plugins.buildSystem.gradle
import org.jetbrains.kotlin.tools.projectWizard.core.context.ReadingContext
import org.jetbrains.kotlin.tools.projectWizard.core.*
import org.jetbrains.kotlin.tools.projectWizard.core.entity.settings.reference
import org.jetbrains.kotlin.tools.projectWizard.core.service.FileSystemWizardService
@@ -1,15 +1,15 @@
package org.jetbrains.kotlin.tools.projectWizard.plugins.kotlin
import org.jetbrains.kotlin.tools.projectWizard.Versions
import org.jetbrains.kotlin.tools.projectWizard.core.context.WritingContext
import org.jetbrains.kotlin.tools.projectWizard.core.*
import org.jetbrains.kotlin.tools.projectWizard.core.context.ReadingContext
import org.jetbrains.kotlin.tools.projectWizard.core.entity.*
import org.jetbrains.kotlin.tools.projectWizard.core.entity.ValidationResult
import org.jetbrains.kotlin.tools.projectWizard.core.entity.fold
import org.jetbrains.kotlin.tools.projectWizard.core.service.FileSystemWizardService
import org.jetbrains.kotlin.tools.projectWizard.core.service.KotlinVersionProviderService
import org.jetbrains.kotlin.tools.projectWizard.core.service.KotlinVersionProviderServiceImpl
import org.jetbrains.kotlin.tools.projectWizard.core.service.kotlinVersionKind
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.*
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.BuildFileIR
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.RepositoryIR
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.withIrs
import org.jetbrains.kotlin.tools.projectWizard.phases.GenerationPhase
import org.jetbrains.kotlin.tools.projectWizard.plugins.StructurePlugin
import org.jetbrains.kotlin.tools.projectWizard.plugins.buildSystem.BuildSystemPlugin
@@ -2,8 +2,8 @@ package org.jetbrains.kotlin.tools.projectWizard.plugins.kotlin
import kotlinx.collections.immutable.persistentListOf
import kotlinx.collections.immutable.toPersistentList
import org.jetbrains.kotlin.tools.projectWizard.core.context.ReadingContext
import org.jetbrains.kotlin.tools.projectWizard.core.context.WritingContext
import org.jetbrains.kotlin.tools.projectWizard.core.*
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.*
import org.jetbrains.kotlin.tools.projectWizard.moduleConfigurators.*
@@ -1,9 +1,6 @@
package org.jetbrains.kotlin.tools.projectWizard.plugins.printer
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.BuildSystemIR
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.gradle.BodyIR
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.gradle.isEmpty
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.render
class GradlePrinter(val dsl: GradleDsl, override val indent: Int = 4) : BuildFilePrinter() {
fun inBrackets(inner: () -> Unit) {
@@ -1,7 +1,7 @@
package org.jetbrains.kotlin.tools.projectWizard.plugins.projectTemplates
import org.jetbrains.kotlin.tools.projectWizard.core.*
import org.jetbrains.kotlin.tools.projectWizard.core.context.SettingsWritingContext
import org.jetbrains.kotlin.tools.projectWizard.phases.GenerationPhase
import org.jetbrains.kotlin.tools.projectWizard.plugins.kotlin.KotlinPlugin
import org.jetbrains.kotlin.tools.projectWizard.plugins.kotlin.withAllSubModules
@@ -1,7 +1,7 @@
package org.jetbrains.kotlin.tools.projectWizard.plugins.templates
import org.jetbrains.kotlin.tools.projectWizard.core.*
import org.jetbrains.kotlin.tools.projectWizard.templates.*
import org.jetbrains.kotlin.tools.projectWizard.core.Context
import org.jetbrains.kotlin.tools.projectWizard.templates.ConsoleJvmApplicationTemplate
class ConsoleJvmApplicationTemplatePlugin(context: Context) : TemplatePlugin(context) {
val addTemplate by addTemplateTask(
@@ -1,7 +1,7 @@
package org.jetbrains.kotlin.tools.projectWizard.plugins.templates
import org.jetbrains.kotlin.tools.projectWizard.core.*
import org.jetbrains.kotlin.tools.projectWizard.templates.*
import org.jetbrains.kotlin.tools.projectWizard.core.Context
import org.jetbrains.kotlin.tools.projectWizard.templates.SimpleJsClientTemplate
class JsTemplatesPlugin(context: Context) : TemplatePlugin(context) {
val addTemplate by addTemplateTask(SimpleJsClientTemplate())
@@ -1,7 +1,7 @@
package org.jetbrains.kotlin.tools.projectWizard.plugins.templates
import org.jetbrains.kotlin.tools.projectWizard.core.*
import org.jetbrains.kotlin.tools.projectWizard.templates.*
import org.jetbrains.kotlin.tools.projectWizard.core.Context
import org.jetbrains.kotlin.tools.projectWizard.templates.KtorServerTemplate
class KtorTemplatesPlugin(context: Context) : TemplatePlugin(context) {
val addTemplate by addTemplateTask(KtorServerTemplate())
@@ -2,8 +2,8 @@ package org.jetbrains.kotlin.tools.projectWizard.plugins.templates
import org.jetbrains.kotlin.tools.projectWizard.core.Context
import org.jetbrains.kotlin.tools.projectWizard.core.Plugin
import org.jetbrains.kotlin.tools.projectWizard.templates.Template
import org.jetbrains.kotlin.tools.projectWizard.phases.GenerationPhase
import org.jetbrains.kotlin.tools.projectWizard.templates.Template
abstract class TemplatePlugin(context: Context) : Plugin(context) {
fun addTemplateTask(template: Template) = pipelineTask(GenerationPhase.PREPARE) {
@@ -1,6 +1,6 @@
package org.jetbrains.kotlin.tools.projectWizard.plugins.templates
import org.jetbrains.kotlin.tools.projectWizard.core.context.WritingContext
import org.jetbrains.kotlin.tools.projectWizard.core.*
import org.jetbrains.kotlin.tools.projectWizard.core.Defaults.KOTLIN_DIR
import org.jetbrains.kotlin.tools.projectWizard.core.Defaults.RESOURCES_DIR
@@ -4,7 +4,7 @@ import org.jetbrains.kotlin.tools.projectWizard.GeneratedIdentificator
import org.jetbrains.kotlin.tools.projectWizard.Identificator
import org.jetbrains.kotlin.tools.projectWizard.IdentificatorOwner
import org.jetbrains.kotlin.tools.projectWizard.core.*
import org.jetbrains.kotlin.tools.projectWizard.core.context.SettingsWritingContext
import org.jetbrains.kotlin.tools.projectWizard.core.entity.*
import org.jetbrains.kotlin.tools.projectWizard.core.entity.settings.ModuleConfiguratorSetting
import org.jetbrains.kotlin.tools.projectWizard.core.entity.settings.PluginSetting
@@ -4,7 +4,7 @@ import org.jetbrains.kotlin.tools.projectWizard.GeneratedIdentificator
import org.jetbrains.kotlin.tools.projectWizard.Identificator
import org.jetbrains.kotlin.tools.projectWizard.IdentificatorOwner
import org.jetbrains.kotlin.tools.projectWizard.core.*
import org.jetbrains.kotlin.tools.projectWizard.core.context.WritingContext
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.BuildFileIR
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.ModuleIR
import org.jetbrains.kotlin.tools.projectWizard.plugins.buildSystem.BuildSystemPlugin
@@ -1,11 +1,13 @@
package org.jetbrains.kotlin.tools.projectWizard.templates
import org.jetbrains.kotlin.tools.projectWizard.core.buildList
import org.jetbrains.kotlin.tools.projectWizard.core.context.WritingContext
import org.jetbrains.kotlin.tools.projectWizard.core.WritingContext
import org.jetbrains.kotlin.tools.projectWizard.core.asPath
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.*
import org.jetbrains.kotlin.tools.projectWizard.core.buildList
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.BuildSystemIR
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.ModuleIR
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.gradle.multiplatform.TargetConfigurationIR
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.gradle.multiplatform.addWithJavaIntoJvmTarget
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.runTaskIrs
import org.jetbrains.kotlin.tools.projectWizard.plugins.kotlin.ModuleType
import org.jetbrains.kotlin.tools.projectWizard.settings.buildsystem.SourcesetType
@@ -5,7 +5,8 @@
package org.jetbrains.kotlin.tools.projectWizard.templates
import org.jetbrains.kotlin.tools.projectWizard.core.context.WritingContext
import org.jetbrains.kotlin.tools.projectWizard.core.WritingContext
import org.jetbrains.kotlin.tools.projectWizard.core.asPath
import org.jetbrains.kotlin.tools.projectWizard.core.buildList
import org.jetbrains.kotlin.tools.projectWizard.core.entity.settings.TemplateSetting
@@ -5,7 +5,8 @@
package org.jetbrains.kotlin.tools.projectWizard.templates
import org.jetbrains.kotlin.tools.projectWizard.core.context.WritingContext
import org.jetbrains.kotlin.tools.projectWizard.core.WritingContext
import org.jetbrains.kotlin.tools.projectWizard.core.asPath
import org.jetbrains.kotlin.tools.projectWizard.core.buildList
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.ModuleIR
@@ -5,13 +5,11 @@
package org.jetbrains.kotlin.tools.projectWizard.templates
import org.jetbrains.kotlin.tools.projectWizard.WizardGradleRunConfiguration
import org.jetbrains.kotlin.tools.projectWizard.WizardRunConfiguration
import org.jetbrains.kotlin.tools.projectWizard.core.context.ReadingContext
import org.jetbrains.kotlin.tools.projectWizard.core.context.WritingContext
import org.jetbrains.kotlin.tools.projectWizard.core.*
import org.jetbrains.kotlin.tools.projectWizard.core.entity.settings.TemplateSetting
import org.jetbrains.kotlin.tools.projectWizard.core.safeAs
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.*
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.gradle.*
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.gradle.multiplatform.DefaultTargetConfigurationIR
@@ -3,10 +3,10 @@ package org.jetbrains.kotlin.tools.projectWizard.templates
import org.jetbrains.kotlin.tools.projectWizard.Identificator
import org.jetbrains.kotlin.tools.projectWizard.SettingsOwner
import org.jetbrains.kotlin.tools.projectWizard.WizardRunConfiguration
import org.jetbrains.kotlin.tools.projectWizard.core.context.ReadingContext
import org.jetbrains.kotlin.tools.projectWizard.core.context.WritingContext
import org.jetbrains.kotlin.tools.projectWizard.core.*
import org.jetbrains.kotlin.tools.projectWizard.core.context.SettingsWritingContext
import org.jetbrains.kotlin.tools.projectWizard.core.entity.settings.*
import org.jetbrains.kotlin.tools.projectWizard.enumSettingImpl
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.BuildSystemIR
@@ -6,7 +6,8 @@ import org.apache.velocity.runtime.RuntimeConstants
import org.apache.velocity.runtime.RuntimeServices
import org.apache.velocity.runtime.log.LogChute
import org.jetbrains.kotlin.tools.projectWizard.core.TaskResult
import org.jetbrains.kotlin.tools.projectWizard.core.context.WritingContext
import org.jetbrains.kotlin.tools.projectWizard.core.WritingContext
import org.jetbrains.kotlin.tools.projectWizard.core.div
import org.jetbrains.kotlin.tools.projectWizard.core.service.FileFormattingService
import org.jetbrains.kotlin.tools.projectWizard.core.service.FileSystemWizardService
@@ -1,65 +1,58 @@
package org.jetbrains.kotlin.tools.projectWizard.wizard
import org.jetbrains.kotlin.tools.projectWizard.core.context.ReadingContext
import org.jetbrains.kotlin.tools.projectWizard.core.context.WritingContext
import org.jetbrains.kotlin.tools.projectWizard.core.*
import org.jetbrains.kotlin.tools.projectWizard.core.context.SettingsWritingContext
import org.jetbrains.kotlin.tools.projectWizard.core.entity.*
import org.jetbrains.kotlin.tools.projectWizard.core.entity.settings.*
import org.jetbrains.kotlin.tools.projectWizard.core.service.WizardService
import org.jetbrains.kotlin.tools.projectWizard.core.entity.settings.SettingSerializer
import org.jetbrains.kotlin.tools.projectWizard.core.entity.settings.reference
import org.jetbrains.kotlin.tools.projectWizard.core.service.ServicesManager
import org.jetbrains.kotlin.tools.projectWizard.core.service.SettingSavingWizardService
import org.jetbrains.kotlin.tools.projectWizard.core.service.WizardService
import org.jetbrains.kotlin.tools.projectWizard.phases.GenerationPhase
import org.jetbrains.kotlin.tools.projectWizard.plugins.kotlin.KotlinPlugin
import org.jetbrains.kotlin.tools.projectWizard.plugins.kotlin.withAllSubModules
abstract class Wizard(createPlugins: PluginsCreator, val servicesManager: ServicesManager, private val isUnitTestMode: Boolean) {
val context = Context(createPlugins, EventManager())
val valuesReadingContext = ReadingContext(context, servicesManager, isUnitTestMode)
private val settingsWritingContext = SettingsWritingContext(context, servicesManager, isUnitTestMode)
protected val plugins = context.plugins
protected val pluginSettings = plugins.flatMap { it.declaredSettings }.distinctBy { it.path }
abstract class Wizard(createPlugins: PluginsCreator, servicesManager: ServicesManager, isUnitTestMode: Boolean) {
val context = Context(createPlugins, servicesManager, isUnitTestMode)
inline fun <reified V : Any> settingValue(setting: PluginSettingReference<V, SettingType<V>>): V =
with(valuesReadingContext) { setting.settingValue }
private fun Context.checkAllRequiredSettingPresent(phases: Set<GenerationPhase>): TaskResult<Unit> =
private fun checkAllRequiredSettingPresent(phases: Set<GenerationPhase>): TaskResult<Unit> = context.read {
getUnspecifiedSettings(phases).let { unspecifiedSettings ->
if (unspecifiedSettings.isEmpty()) UNIT_SUCCESS
else Failure(RequiredSettingsIsNotPresentError(unspecifiedSettings.map { it.path }))
}
}
private fun initNonPluginDefaultValues() {
with(settingsWritingContext) {
KotlinPlugin::modules.reference.notRequiredSettingValue?.withAllSubModules(includeSourcesets = true)?.forEach { module ->
with(module) { initDefaultValuesForSettings() }
}
context.writeSettings {
KotlinPlugin::modules.reference.notRequiredSettingValue
?.withAllSubModules(includeSourcesets = true)
?.forEach { module ->
with(module) { initDefaultValuesForSettings() }
}
}
}
protected fun initPluginSettingsDefaultValues() {
with(settingsWritingContext) {
context.writeSettings {
for (setting in pluginSettings) {
setting.reference.setSettingValueToItsDefaultIfItIsNotSetValue()
}
}
}
@Suppress("UNUSED_PARAMETER")
fun ReadingContext.validate(phases: Set<GenerationPhase>): TaskResult<Unit> =
context.settingContext.allPluginSettings.map { setting ->
val value = context.settingContext.pluginSettingValue(setting) ?: return@map ValidationResult.OK
fun validate(phases: Set<GenerationPhase>): TaskResult<Unit> = context.read {
pluginSettings.map { setting ->
val value = setting.reference.notRequiredSettingValue ?: return@map ValidationResult.OK
if (setting.neededAtPhase in phases && setting.isActive(this))
(setting.validator as SettingValidator<Any>).validate(this, value)
else ValidationResult.OK
}.fold(ValidationResult.OK, ValidationResult::and).toResult()
}.fold().toResult()
}
private fun ReadingContext.saveSettingValues(phases: Set<GenerationPhase>) {
private fun saveSettingValues(phases: Set<GenerationPhase>) = context.read {
for (setting in pluginSettings) {
if (setting.neededAtPhase !in phases) continue
if (!setting.isSavable) continue
if (!setting.isAvailable(valuesReadingContext)) continue
if (!setting.isAvailable(this)) continue
val serializer = setting.type.serializer as? SettingSerializer.Serializer<Any> ?: continue
service<SettingSavingWizardService>().saveSettingValue(
setting.path,
@@ -75,21 +68,23 @@ abstract class Wizard(createPlugins: PluginsCreator, val servicesManager: Servic
): TaskResult<Unit> = computeM {
initPluginSettingsDefaultValues()
initNonPluginDefaultValues()
context.checkAllRequiredSettingPresent(phases).ensure()
val taskRunningContext = WritingContext(context, servicesManager.withServices(services), isUnitTestMode)
taskRunningContext.validate(phases).ensure()
taskRunningContext.saveSettingValues(phases)
checkAllRequiredSettingPresent(phases).ensure()
validate(phases).ensure()
saveSettingValues(phases)
val (tasksSorted) = context.sortTasks().map { tasks ->
tasks.groupBy { it.phase }.toList().sortedBy { it.first }.flatMap { it.second }
}
tasksSorted
// We should take only one task of each type as all tasks with the same path are considered to be the same
.distinctBy { it.path }
.asSequence()
.filter { task -> task.phase in phases }
.filter { task -> task.isAvailable(taskRunningContext) }
.map { task -> onTaskExecuting(task); task.action(taskRunningContext) }
.sequenceFailFirst()
.ignore()
context.withAdditionalServices(services).write {
tasksSorted
// We should take only one task of each type as all tasks with the same path are considered to be the same
.distinctBy { it.path }
.asSequence()
.filter { task -> task.phase in phases }
.filter { task -> task.isAvailable(this) }
.map { task -> onTaskExecuting(task); task.action(this) }
.sequenceFailFirst()
.ignore()
}
}
}