Wizard: move Android SDK Setting to AndroidPlugin

This commit is contained in:
Ilya Kirillov
2020-02-20 16:33:13 +03:00
parent 9c5ff6c131
commit 9e47d0b33c
11 changed files with 87 additions and 31 deletions
@@ -5,7 +5,7 @@ import org.jetbrains.kotlin.idea.projectWizard.UiEditorUsageStats
import org.jetbrains.kotlin.tools.projectWizard.core.ValuesReadingContext
import org.jetbrains.kotlin.tools.projectWizard.core.entity.StringValidators
import org.jetbrains.kotlin.tools.projectWizard.core.entity.ValidationResult
import org.jetbrains.kotlin.tools.projectWizard.moduleConfigurators.configuratorSettings
import org.jetbrains.kotlin.tools.projectWizard.moduleConfigurators.getConfiguratorSettings
import org.jetbrains.kotlin.tools.projectWizard.moduleConfigurators.moduleType
import org.jetbrains.kotlin.tools.projectWizard.plugins.kotlin.ModuleType
import org.jetbrains.kotlin.tools.projectWizard.settings.buildsystem.Module
@@ -71,7 +71,7 @@ class ModuleSettingsComponent(
nameField.component.isVisible = module.kind != ModuleKind.target
|| module.configurator.moduleType != ModuleType.common
moduleConfiguratorSettingsList.setSettings(module.configuratorSettings)
moduleConfiguratorSettingsList.setSettings(module.getConfiguratorSettings())
templateComponent.module = module
}
}
@@ -36,4 +36,9 @@ open class ValuesReadingContext(
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)
}
@@ -24,9 +24,9 @@ sealed class SettingReference<out V : Any, out T : SettingType<V>> {
final override fun hashCode() = path.hashCode()
}
data class PluginSettingReference<V : Any, T : SettingType<V>>(
data class PluginSettingReference<out V : Any, out T : SettingType<V>>(
override val path: String,
override val type: KClass<T>
override val type: KClass<@UnsafeVariance T>
) : SettingReference<V, T>() {
constructor(kProperty: KProperty1<out Plugin, PluginSetting<V, T>>, type: KClass<T>) :
@@ -40,6 +40,9 @@ data class PluginSettingReference<V : Any, T : SettingType<V>>(
settingContext.getPluginSetting(this@PluginSettingReference)
}
inline val <V : Any, reified T : SettingType<V>> PluginSetting<V, T>.reference: PluginSettingReference<V, T>
get() = PluginSettingReference(path, T::class)
sealed class ModuleConfiguratorSettingReference<V : Any, T : SettingType<V>> : SettingReference<V, T>() {
abstract val descriptor: ModuleConfigurator
abstract val moduleId: Identificator
@@ -3,6 +3,7 @@ package org.jetbrains.kotlin.tools.projectWizard.core
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
@@ -1,7 +1,9 @@
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.PluginSettingReference
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.kotlinVersionKind
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.*
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.gradle.AndroidConfigIR
@@ -9,7 +11,7 @@ import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.gradle.BuildScrip
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.gradle.BuildScriptRepositoryIR
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.gradle.RawGradleIR
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.buildSystem.gradle.GradlePlugin
import org.jetbrains.kotlin.tools.projectWizard.plugins.kotlin.ModuleConfigurationData
import org.jetbrains.kotlin.tools.projectWizard.plugins.kotlin.ModuleType
@@ -27,18 +29,14 @@ import java.nio.file.Path
object AndroidSinglePlatformModuleConfigurator : ModuleConfiguratorWithSettings(),
SinglePlatformModuleConfigurator,
AndroidModuleConfigurator,
ModuleConfiguratorWithModuleType{
ModuleConfiguratorWithModuleType {
override val moduleType = ModuleType.jvm
override val id = "android"
override val suggestedModuleName = "android"
override val text = "Android"
override val greyText = "Requires Android SDK"
val androidSdkPath by pathSetting("Android SDK Path", neededAtPhase = GenerationPhase.PROJECT_GENERATION) {
shouldExists()
}
private fun createRepositories(configurationData: ModuleConfigurationData) =buildList<Repository> {
private fun createRepositories(configurationData: ModuleConfigurationData) = buildList<Repository> {
+DefaultRepository.GRADLE_PLUGIN_PORTAL
+DefaultRepository.GOOGLE
+DefaultRepository.JCENTER
@@ -79,12 +77,7 @@ object AndroidSinglePlatformModuleConfigurator : ModuleConfiguratorWithSettings(
configurationData: ModuleConfigurationData,
module: Module,
modulePath: Path
): TaskResult<Unit> = withSettingsOf(module) {
val path = androidSdkPath.reference.settingValue
GradlePlugin::localProperties.addValues(
"sdk.dir" to path
)
} andThen computeM {
): TaskResult<Unit> = computeM {
val javaPackage = module.javaPackage(configurationData.pomIr)
TemplatesPlugin::addFileTemplates.execute(
listOf(
@@ -119,8 +112,8 @@ object AndroidSinglePlatformModuleConfigurator : ModuleConfiguratorWithSettings(
override fun createStdlibType(configurationData: ModuleConfigurationData, module: Module): StdlibType? =
StdlibType.StdlibJdk7
override val settings: List<ModuleConfiguratorSetting<*, *>> =
listOf(androidSdkPath)
override fun getPluginSettings(): List<PluginSettingReference<Any, SettingType<Any>>> =
listOf(AndroidPlugin::androidSdkPath.reference)
private object FileTemplateDescriptors {
val activityMainXml = FileTemplateDescriptor(
@@ -58,7 +58,8 @@ abstract class ModuleConfiguratorWithSettings : ModuleConfigurator, SettingsOwne
ModuleConfiguratorSetting(create(name).buildInternal())
}
abstract val settings: List<ModuleConfiguratorSetting<*, *>>
open fun getConfiguratorSettings(): List<ModuleConfiguratorSetting<*, *>> = emptyList()
open fun getPluginSettings(): List<PluginSettingReference<Any, SettingType<Any>>> = emptyList()
@Suppress("UNCHECKED_CAST")
override fun <V : DisplayableSettingItem> dropDownSetting(
@@ -162,7 +163,7 @@ abstract class ModuleConfiguratorWithSettings : ModuleConfigurator, SettingsOwne
fun initDefaultValuesFor(module: Module, context: Context) {
withSettingsOf(module) {
settings.forEach { setting ->
getConfiguratorSettings().forEach { setting ->
val defaultValue = setting.defaultValue ?: return@forEach
context.settingContext[setting.reference] = defaultValue
}
@@ -172,14 +173,25 @@ abstract class ModuleConfiguratorWithSettings : ModuleConfigurator, SettingsOwne
val ModuleConfigurator.settings
get() = when (this) {
is ModuleConfiguratorWithSettings -> settings
is ModuleConfiguratorWithSettings -> getConfiguratorSettings()
else -> emptyList()
}
val Module.configuratorSettings
get() = configurator.settings.map { setting ->
ModuleBasedConfiguratorSettingReference(configurator, this, setting)
fun ValuesReadingContext.allSettingsOfModuleConfigurator(moduleConfigurator: ModuleConfigurator) = when (moduleConfigurator) {
is ModuleConfiguratorWithSettings -> buildList<Setting<Any, SettingType<Any>>> {
+moduleConfigurator.getConfiguratorSettings()
+moduleConfigurator.getPluginSettings().map { it.pluginSetting }
}
else -> emptyList()
}
fun Module.getConfiguratorSettings() = buildList<SettingReference<*, *>> {
+configurator.settings.map { setting ->
ModuleBasedConfiguratorSettingReference(configurator, this@getConfiguratorSettings, setting)
}
configurator.safeAs<ModuleConfiguratorWithSettings>()?.getPluginSettings()?.let { +it }
}
interface ModuleConfigurator : DisplayableSettingItem, EntitiesOwnerDescriptor {
val moduleKind: ModuleKind
@@ -50,7 +50,7 @@ abstract class ModuleConfiguratorWithTests : ModuleConfiguratorWithSettings() {
}
}
override val settings: List<ModuleConfiguratorSetting<*, *>> = listOf(testFramework)
override fun getConfiguratorSettings(): List<ModuleConfiguratorSetting<*, *>> = listOf(testFramework)
}
@@ -21,8 +21,8 @@ abstract class JvmModuleConfigurator : ModuleConfiguratorWithTests() {
val targetJvmVersion by enumSetting<TargetJvmVersion>("Target JVM Version", GenerationPhase.PROJECT_GENERATION) {
defaultValue = TargetJvmVersion.JVM_1_8
}
override val settings: List<ModuleConfiguratorSetting<*, *>>
get() = super.settings + targetJvmVersion
override fun getConfiguratorSettings(): List<ModuleConfiguratorSetting<*, *>> = super.getConfiguratorSettings() + targetJvmVersion
}
enum class TargetJvmVersion(val value: String) : DisplayableSettingItem {
@@ -0,0 +1,37 @@
/*
* 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.plugins
import org.jetbrains.kotlin.tools.projectWizard.core.Context
import org.jetbrains.kotlin.tools.projectWizard.core.Plugin
import org.jetbrains.kotlin.tools.projectWizard.core.UNIT_SUCCESS
import org.jetbrains.kotlin.tools.projectWizard.moduleConfigurators.AndroidModuleConfigurator
import org.jetbrains.kotlin.tools.projectWizard.phases.GenerationPhase
import org.jetbrains.kotlin.tools.projectWizard.plugins.buildSystem.allModules
import org.jetbrains.kotlin.tools.projectWizard.plugins.buildSystem.gradle.GradlePlugin
import org.jetbrains.kotlin.tools.projectWizard.plugins.kotlin.KotlinPlugin
class AndroidPlugin(context: Context) : Plugin(context) {
val androidSdkPath by pathSetting(
"Android SDK Path",
neededAtPhase = GenerationPhase.PROJECT_GENERATION
) {
shouldExists()
}
val addAndroidSdkToLocalProperties by pipelineTask(GenerationPhase.PROJECT_GENERATION) {
runBefore(GradlePlugin::createLocalPropertiesFile)
runAfter(KotlinPlugin::createModules)
withAction {
if (allModules.none { it.originalModule.configurator is AndroidModuleConfigurator }) return@withAction UNIT_SUCCESS
val path = AndroidPlugin::androidSdkPath.settingValue
GradlePlugin::localProperties.addValues(
"sdk.dir" to path
)
}
}
}
@@ -23,6 +23,7 @@ object Plugins {
TemplatesPlugin(context),
ProjectTemplatesPlugin(context),
RunConfigurationsPlugin(context),
AndroidPlugin(context),
// templates
ConsoleJvmApplicationTemplatePlugin(context),
@@ -38,8 +38,12 @@ class Module(
StringValidators.shouldBeValidIdentifier("Module name `$name`", ALLOWED_SPECIAL_CHARS_IN_MODULE_NAMES).validate(this, module.name)
} and settingValidator { module ->
withSettingsOf(module) {
configurator.settings.map { setting ->
val value = setting.reference.notRequiredSettingValue
allSettingsOfModuleConfigurator(configurator).map { setting ->
val value = when (setting) {
is PluginSetting<Any, SettingType<Any>> -> setting.reference.notRequiredSettingValue
is ModuleConfiguratorSetting<Any, SettingType<Any>> -> setting.reference.notRequiredSettingValue
else -> null
}
?: setting.defaultValue
?: return@map ValidationResult.ValidationError("${setting.title.capitalize()} should not be blank")
(setting.validator as SettingValidator<Any>).validate(this@settingValidator, value)