Wizard: move pom settings to the first phase

This commit is contained in:
Ilya Kirillov
2020-03-17 23:06:36 +03:00
parent c71972afc9
commit 0dc0c41842
13 changed files with 172 additions and 133 deletions
@@ -1,7 +1,6 @@
package org.jetbrains.kotlin.tools.projectWizard.wizard
import com.intellij.ide.RecentProjectsManager
import com.intellij.ide.projectWizard.ProjectSettingsStep
import com.intellij.ide.util.projectWizard.*
import com.intellij.openapi.Disposable
import com.intellij.openapi.application.ApplicationNamesInfo
@@ -15,13 +14,11 @@ import com.intellij.openapi.roots.ui.configuration.ModulesProvider
import com.intellij.openapi.ui.Messages
import com.intellij.util.SystemProperties
import org.jetbrains.kotlin.idea.configuration.ExperimentalFeatures
import org.jetbrains.kotlin.idea.framework.KotlinModuleSettingStep
import org.jetbrains.kotlin.idea.framework.KotlinTemplatesFactory
import org.jetbrains.kotlin.idea.projectWizard.ProjectCreationStats
import org.jetbrains.kotlin.idea.projectWizard.UiEditorUsageStats
import org.jetbrains.kotlin.idea.projectWizard.WizardStatsService
import org.jetbrains.kotlin.idea.util.application.runWriteAction
import org.jetbrains.kotlin.platform.jvm.JvmPlatforms
import org.jetbrains.kotlin.tools.projectWizard.core.*
import org.jetbrains.kotlin.tools.projectWizard.core.entity.StringValidators
import org.jetbrains.kotlin.tools.projectWizard.core.entity.ValidationResult
@@ -30,16 +27,14 @@ import org.jetbrains.kotlin.tools.projectWizard.phases.GenerationPhase
import org.jetbrains.kotlin.tools.projectWizard.plugins.Plugins
import org.jetbrains.kotlin.tools.projectWizard.plugins.StructurePlugin
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.IdeaServices
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.PomWizardStepComponent
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.asHtml
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.firstStep.FirstWizardStepComponent
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.runWithProgressBar
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.secondStep.SecondStepWizardComponent
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
import java.io.File
import java.nio.file.Paths
import javax.swing.JButton
import javax.swing.JComponent
import com.intellij.openapi.module.Module as IdeaModule
@@ -60,7 +55,6 @@ class NewProjectWizardModuleBuilder : EmptyModuleBuilder() {
companion object {
const val MODULE_BUILDER_ID = "kotlin.newProjectWizard.builder"
private const val DEFAULT_GROUP_ID = "me.user"
private val projectNameValidator = StringValidators.shouldBeValidIdentifier("Project name", setOf('-', '_'))
private const val INVALID_PROJECT_NAME_MESSAGE = "Invalid project name"
}
@@ -68,7 +62,7 @@ class NewProjectWizardModuleBuilder : EmptyModuleBuilder() {
override fun isAvailable(): Boolean = ExperimentalFeatures.NewWizard.isEnabled
private var wizardContext: WizardContext? = null
private var pomValuesAreSet: Boolean = false
private var finishButtonClicked: Boolean = false
override fun getModuleType(): ModuleType<*> = NewProjectWizardModuleType()
override fun getParentGroup(): String = KotlinTemplatesFactory.KOTLIN_PARENT_GROUP_NAME
@@ -78,7 +72,7 @@ class NewProjectWizardModuleBuilder : EmptyModuleBuilder() {
modulesProvider: ModulesProvider
): Array<ModuleWizardStep> {
this.wizardContext = wizardContext
return arrayOf(ModuleNewWizardSecondStep(wizard, uiEditorUsagesStats))
return arrayOf(ModuleNewWizardSecondStep(wizard, uiEditorUsagesStats, wizardContext))
}
override fun commit(
@@ -114,19 +108,15 @@ class NewProjectWizardModuleBuilder : EmptyModuleBuilder() {
}
}
override fun modifySettingsStep(settingsStep: SettingsStep): ModuleWizardStep {
updateProjectNameAndPomDate(settingsStep)
return when (wizard.buildSystemType) {
BuildSystemType.Jps -> {
KotlinModuleSettingStep(
JvmPlatforms.defaultJvmPlatform,
this,
settingsStep,
wizardContext
)
}
else -> PomWizardStep(settingsStep, wizard)
}
private fun clickFinishButton() {
if (finishButtonClicked) return
finishButtonClicked = true
wizardContext?.getActionButtonWithText("Finish", "Next")?.doClick()
}
override fun modifySettingsStep(settingsStep: SettingsStep): ModuleWizardStep? {
clickFinishButton()
return null
}
override fun validateModuleName(moduleName: String): Boolean {
@@ -141,42 +131,10 @@ class NewProjectWizardModuleBuilder : EmptyModuleBuilder() {
}
}
private fun updateProjectNameAndPomDate(settingsStep: SettingsStep) {
if (pomValuesAreSet) return
val suggestedProjectName = wizard.context.read {
ProjectTemplatesPlugin::template.settingValue.suggestedProjectName.decapitalize()
}
settingsStep.moduleNameLocationSettings?.apply {
moduleName = wizard.projectName!!
moduleContentRoot = wizard.projectPath!!.toString()
}
settingsStep.safeAs<ProjectSettingsStep>()?.bindModuleSettings()
wizard.artifactId = suggestedProjectName
wizard.groupId = suggestGroupId()
pomValuesAreSet = true
}
private fun suggestGroupId(): String {
val username = SystemProperties.getUserName() ?: return DEFAULT_GROUP_ID
if (!username.matches("[\\w\\s]+".toRegex())) return DEFAULT_GROUP_ID
val usernameAsGroupId = username.trim().toLowerCase().split("\\s+".toRegex()).joinToString(separator = ".")
return "me.$usernameAsGroupId"
}
override fun getCustomOptionsStep(context: WizardContext?, parentDisposable: Disposable?) =
ModuleNewWizardFirstStep(wizard)
override fun setName(name: String) {
wizard.projectName = name
}
override fun setModuleFilePath(path: String) = Unit
override fun setContentEntryPath(moduleRootPath: String) {
wizard.projectPath = Paths.get(moduleRootPath)
}
}
abstract class WizardStep(protected val wizard: IdeWizard, private val phase: GenerationPhase) : ModuleWizardStep() {
@@ -195,29 +153,13 @@ abstract class WizardStep(protected val wizard: IdeWizard, private val phase: Ge
}
}
private class PomWizardStep(
originalSettingStep: SettingsStep,
wizard: IdeWizard
) : WizardStep(wizard, GenerationPhase.PROJECT_GENERATION) {
private val pomWizardStepComponent = PomWizardStepComponent(wizard.context)
init {
originalSettingStep.addSettingsComponent(component)
pomWizardStepComponent.onInit()
}
override fun getComponent(): JComponent = pomWizardStepComponent.component
}
class ModuleNewWizardFirstStep(wizard: IdeWizard) : WizardStep(wizard, GenerationPhase.FIRST_STEP) {
private val component = FirstWizardStepComponent(wizard)
override fun getComponent(): JComponent = component.component
init {
runPreparePhase()
initDefaultProjectNameAndPathValues()
initDefaultValues()
component.onInit()
}
@@ -227,15 +169,31 @@ class ModuleNewWizardFirstStep(wizard: IdeWizard) : WizardStep(wizard, Generatio
}
}
private fun initDefaultProjectNameAndPathValues() {
override fun handleErrors(error: ValidationResult.ValidationError) {
component.navigateTo(error)
}
private fun initDefaultValues() {
val suggestedProjectParentLocation = suggestProjectLocation()
val suggestedProjectName = ProjectWizardUtil.findNonExistingFileName(suggestedProjectParentLocation, "untitled", "")
wizard.context.writeSettings {
StructurePlugin::name.reference.setValue(suggestedProjectName)
StructurePlugin::projectPath.reference.setValue(suggestedProjectParentLocation / suggestedProjectName)
StructurePlugin::artifactId.reference.setValue(suggestedProjectName)
if (StructurePlugin::groupId.reference.notRequiredSettingValue == null) {
StructurePlugin::groupId.reference.setValue(suggestGroupId())
}
}
}
private fun suggestGroupId(): String {
val username = SystemProperties.getUserName() ?: return DEFAULT_GROUP_ID
if (!username.matches("[\\w\\s]+".toRegex())) return DEFAULT_GROUP_ID
val usernameAsGroupId = username.trim().toLowerCase().split("\\s+".toRegex()).joinToString(separator = ".")
return "me.$usernameAsGroupId"
}
// copied from com.intellij.ide.util.projectWizard.WizardContext.getProjectFileDirectory
private fun suggestProjectLocation(): String {
val lastProjectLocation = RecentProjectsManager.getInstance().lastProjectCreationLocation
@@ -246,11 +204,16 @@ class ModuleNewWizardFirstStep(wizard: IdeWizard) : WizardStep(wizard, Generatio
val productName = ApplicationNamesInfo.getInstance().lowercaseProductName
return userHome.replace('/', File.separatorChar) + File.separator + productName.replace(" ", "") + "Projects"
}
companion object {
private const val DEFAULT_GROUP_ID = "me.user"
}
}
class ModuleNewWizardSecondStep(
wizard: IdeWizard,
uiEditorUsagesStats: UiEditorUsageStats
uiEditorUsagesStats: UiEditorUsageStats,
private val wizardContext: WizardContext
) : WizardStep(wizard, GenerationPhase.SECOND_STEP) {
private val component = SecondStepWizardComponent(wizard, uiEditorUsagesStats)
override fun getComponent(): JComponent = component.component
@@ -259,7 +222,22 @@ class ModuleNewWizardSecondStep(
component.onInit()
}
override fun getPreferredFocusedComponent(): JComponent? {
wizardContext.getActionButtonWithText("Next")?.apply {
text = "Finish"
updateUI()
}
return super.getPreferredFocusedComponent()
}
override fun handleErrors(error: ValidationResult.ValidationError) {
component.navigateTo(error)
}
}
}
private fun WizardContext.getActionButtonWithText(text: String, alternativeText: String? = null): JButton? =
wizard?.cancelButton?.parent?.components?.find { child ->
child.safeAs<JButton>()?.let { button ->
button.text == text || alternativeText != null && button.text == alternativeText
} == true
} as? JButton
@@ -22,6 +22,10 @@ abstract class Component : Displayable, ErrorNavigatable {
this@Component.subComponents += it
}
protected fun clearSubComponents() {
subComponents.clear()
}
override fun navigateTo(error: ValidationResult.ValidationError) {
subComponents.forEach { it.navigateTo(error) }
}
@@ -1,40 +0,0 @@
package org.jetbrains.kotlin.tools.projectWizard.wizard.ui
import com.intellij.ui.components.panels.VerticalLayout
import org.jetbrains.kotlin.tools.projectWizard.core.Context
import org.jetbrains.kotlin.tools.projectWizard.core.entity.settings.reference
import org.jetbrains.kotlin.tools.projectWizard.plugins.StructurePlugin
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.setting.StringSettingComponent
import javax.swing.Box
import javax.swing.JSeparator
import javax.swing.SwingConstants
class PomWizardStepComponent(context: Context) : WizardStepComponent(context) {
private val groupIdComponent = StringSettingComponent(
StructurePlugin::groupId.reference,
context,
needLabel = true
).asSubComponent()
private val artifactIdComponent = StringSettingComponent(
StructurePlugin::artifactId.reference,
context,
needLabel = true
).asSubComponent()
private val versionComponent = StringSettingComponent(
StructurePlugin::version.reference,
context,
needLabel = true
).asSubComponent()
override val component = panel(VerticalLayout(0)) {
add(Box.createVerticalStrut(10))
add(JSeparator(SwingConstants.HORIZONTAL))
add(Box.createVerticalStrut(10))
add(groupIdComponent.component)
add(artifactIdComponent.component)
add(versionComponent.component)
}
}
@@ -11,7 +11,7 @@ abstract class SubStep(
protected abstract fun buildContent(): JComponent
final override val component: JComponent by lazy(LazyThreadSafetyMode.NONE) {
panel {
customPanel {
add(buildContent(), BorderLayout.CENTER)
}
}
@@ -16,7 +16,7 @@ import org.jetbrains.kotlin.tools.projectWizard.core.entity.settings.SettingType
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.DynamicComponent
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.FocusableComponent
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.label
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.panel
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.customPanel
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.setting.IdeaBasedComponentValidator
import java.awt.BorderLayout
import javax.swing.JComponent
@@ -57,7 +57,7 @@ abstract class UIComponent<V : Any>(
}
final override val component: JComponent by lazy(LazyThreadSafetyMode.NONE) {
panel {
customPanel {
labelText?.let { add(label("$it:"), BorderLayout.NORTH) }
add(uiComponent, BorderLayout.CENTER)
}
@@ -1,8 +1,14 @@
package org.jetbrains.kotlin.tools.projectWizard.wizard.ui.firstStep
import com.intellij.icons.AllIcons
import com.intellij.ui.JBColor
import com.intellij.ui.TitledSeparator
import com.intellij.ui.layout.panel
import com.intellij.util.io.size
import com.intellij.util.ui.JBUI
import com.intellij.util.ui.components.BorderLayoutPanel
import org.jetbrains.kotlin.tools.projectWizard.core.Context
import org.jetbrains.kotlin.tools.projectWizard.core.entity.path
import org.jetbrains.kotlin.tools.projectWizard.core.entity.settings.SettingReference
import org.jetbrains.kotlin.tools.projectWizard.core.entity.settings.reference
import org.jetbrains.kotlin.tools.projectWizard.plugins.StructurePlugin
@@ -12,6 +18,8 @@ import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.*
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.secondStep.modulesEditor.ModulesEditorComponent
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.setting.TitledComponentsList
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.setting.createSettingComponent
import java.awt.event.MouseAdapter
import java.awt.event.MouseEvent
import javax.swing.JComponent
class FirstWizardStepComponent(wizard: IdeWizard) : WizardStepComponent(wizard.context) {
@@ -28,6 +36,7 @@ class FirstWizardStepComponent(wizard: IdeWizard) : WizardStepComponent(wizard.c
class ProjectSettingsComponent(context: Context) : DynamicComponent(context) {
private val projectTemplateComponent = ProjectTemplateSettingComponent(context).asSubComponent()
private val buildSystemSetting = BuildSystemTypeSettingComponent(context).asSubComponent()
private val buildSystemAdditionalSettingsComponent = BuildSystemAdditionalSettingsComponent(context).asSubComponent()
private val nameAndLocationComponent = TitledComponentsList(
listOf(
@@ -40,12 +49,89 @@ class ProjectSettingsComponent(context: Context) : DynamicComponent(context) {
).asSubComponent()
override val component: JComponent by lazy(LazyThreadSafetyMode.NONE) {
nameAndLocationComponent.component.apply {
panel {
row {
nameAndLocationComponent.component(growX)
}
row {
buildSystemAdditionalSettingsComponent.component(growX)
}
}.apply {
border = JBUI.Borders.empty(10)
}
}
private var locationWasUpdatedByHand: Boolean = false
private var artifactIdWasUpdatedByHand: Boolean = false
override fun onValueUpdated(reference: SettingReference<*, *>?) {
super.onValueUpdated(reference)
when (reference?.path) {
StructurePlugin::name.path -> {
tryUpdateLocationByProjectName()
tryArtifactIdByProjectName()
}
StructurePlugin::artifactId.path -> {
artifactIdWasUpdatedByHand = true
}
StructurePlugin::projectPath.path -> {
locationWasUpdatedByHand = true
}
}
}
private fun tryUpdateLocationByProjectName() {
if (!locationWasUpdatedByHand) {
val location = read { StructurePlugin::projectPath.settingValue }
if (location.parent != null) modify {
StructurePlugin::projectPath.reference.setValue(location.parent.resolve(StructurePlugin::name.settingValue))
locationWasUpdatedByHand = false
}
}
}
private fun tryArtifactIdByProjectName() {
if (!artifactIdWasUpdatedByHand) modify {
StructurePlugin::artifactId.reference.setValue(StructurePlugin::name.settingValue)
artifactIdWasUpdatedByHand = false
}
}
}
class BuildSystemAdditionalSettingsComponent(context: Context) : DynamicComponent(context) {
private val settingsList = TitledComponentsList(
listOf(
StructurePlugin::groupId.reference.createSettingComponent(context),
StructurePlugin::artifactId.reference.createSettingComponent(context),
StructurePlugin::version.reference.createSettingComponent(context)
),
context
).asSubComponent()
override val component: JComponent = HideableSection("Artifact Coordinates", settingsList.component)
}
@Suppress("SpellCheckingInspection")
private class HideableSection(text: String, private val component: JComponent) : BorderLayoutPanel() {
private val titledSeparator = TitledSeparator(text)
private var isExpanded = false
init {
addToTop(titledSeparator)
addToCenter(component)
update(isExpanded)
addMouseListener(object : MouseAdapter() {
override fun mouseReleased(e: MouseEvent) = update(!isExpanded)
})
}
private fun update(isExpanded: Boolean) {
this.isExpanded = isExpanded
component.isVisible = this.isExpanded
titledSeparator.label.icon = if (this.isExpanded) AllIcons.General.ArrowDown else AllIcons.General.ArrowRight
}
}
class ProjectPreviewComponent(context: Context) : DynamicComponent(context) {
private val modulesEditorComponent = ModulesEditorComponent(
@@ -5,7 +5,6 @@ import org.jetbrains.kotlin.tools.projectWizard.core.Context
import org.jetbrains.kotlin.tools.projectWizard.core.entity.ValidationResult
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.Sourceset
import org.jetbrains.kotlin.tools.projectWizard.wizard.IdeWizard
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.*
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.secondStep.modulesEditor.ModulesEditorComponent
@@ -62,7 +61,7 @@ class ModuleSettingsSubStep(
ModuleSettingsComponent(wizard.context, uiEditorUsagesStats).asSubComponent()
private val nothingSelectedComponent = NothingSelectedComponent().asSubComponent()
private val panel = panel {
private val panel = customPanel {
add(nothingSelectedComponent.component, BorderLayout.CENTER)
}
@@ -62,7 +62,7 @@ class SourcesetDependenciesSettingsComponent(
}
}
override val component = panel {
override val component = customPanel {
add(toolbarDecorator.createPanelWithPopupHandler(sourcesetDependenciesList), BorderLayout.CENTER)
}
}
@@ -76,7 +76,7 @@ private class ChooseModuleDialog(modules: List<Module>, parent: JComponent) : Di
}
).bordered(needTopEmptyBorder = false, needBottomEmptyBorder = false)
override fun createCenterPanel() = panel {
override fun createCenterPanel() = customPanel {
preferredSize = Dimension(preferredSize.width, 300)
add(
label("Please select the modules to add as dependencies:")
@@ -11,7 +11,7 @@ import org.jetbrains.kotlin.tools.projectWizard.plugins.kotlin.KotlinPlugin
import org.jetbrains.kotlin.tools.projectWizard.plugins.kotlin.ProjectKind
import org.jetbrains.kotlin.tools.projectWizard.settings.DisplayableSettingItem
import org.jetbrains.kotlin.tools.projectWizard.settings.buildsystem.Module
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.panel
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.customPanel
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.setting.SettingComponent
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.setting.ValidationIndicator
import java.awt.BorderLayout
@@ -74,7 +74,7 @@ class ModulesEditorComponent(
) else null
override val component: JComponent by lazy(LazyThreadSafetyMode.NONE) {
panel {
customPanel {
if (needBorder) {
border = BorderFactory.createLineBorder(JBColor.border())
}
@@ -11,7 +11,7 @@ import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.components.DropDownCom
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.components.PathFieldComponent
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.components.TextFieldComponent
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.label
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.panel
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.customPanel
import java.awt.BorderLayout
import java.awt.event.ItemEvent
import java.nio.file.Path
@@ -87,9 +87,9 @@ class VersionSettingComponent(
override val validationIndicator = null
override val component: JComponent by lazy(LazyThreadSafetyMode.NONE) {
panel {
customPanel {
add(
panel {
customPanel {
add(settingLabel, BorderLayout.CENTER)
},
BorderLayout.WEST
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.tools.projectWizard.wizard.ui.setting
import com.intellij.openapi.application.ApplicationManager
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
@@ -33,5 +34,16 @@ abstract class UIComponentDelegatingSettingComponent<V : Any, T : SettingType<V>
uiComponent.focusOn()
}
override fun onValueUpdated(reference: SettingReference<*, *>?) {
super.onValueUpdated(reference)
if (reference == this.reference) {
ApplicationManager.getApplication().invokeLater {
if (uiComponent.getUiValue() != value) {
value?.let(uiComponent::updateUiValue)
}
}
}
}
override val component: JComponent by lazy(LazyThreadSafetyMode.NONE) { uiComponent.component }
}
@@ -40,7 +40,7 @@ internal inline fun label(text: String, bold: Boolean = false, init: JBLabel.()
init()
}
inline fun panel(layout: LayoutManager = BorderLayout(), init: JPanel.() -> Unit = {}) = JPanel(layout).apply(init)
inline fun customPanel(layout: LayoutManager = BorderLayout(), init: JPanel.() -> Unit = {}) = JPanel(layout).apply(init)
inline fun borderPanel(init: BorderLayoutPanel.() -> Unit = {}) = BorderLayoutPanel().apply(init)
@@ -13,24 +13,24 @@ import org.jetbrains.kotlin.tools.projectWizard.settings.version.Version
import java.nio.file.Paths
class StructurePlugin(context: Context) : Plugin(context) {
val projectPath by pathSetting("Location", GenerationPhase.PROJECT_GENERATION) {
val projectPath by pathSetting("Location", GenerationPhase.FIRST_STEP) {
defaultValue = value(Paths.get("."))
}
val name by stringSetting("Name", GenerationPhase.PROJECT_GENERATION) {
val name by stringSetting("Name", GenerationPhase.FIRST_STEP) {
shouldNotBeBlank()
validate(StringValidators.shouldBeValidIdentifier("Name", Module.ALLOWED_SPECIAL_CHARS_IN_MODULE_NAMES))
}
val groupId by stringSetting("Group ID", GenerationPhase.PROJECT_GENERATION) {
val groupId by stringSetting("Group ID", GenerationPhase.FIRST_STEP) {
isSavable = true
shouldNotBeBlank()
validate(StringValidators.shouldBeValidIdentifier("Group ID", setOf('.', '_')))
}
val artifactId by stringSetting("Artifact ID", GenerationPhase.PROJECT_GENERATION) {
val artifactId by stringSetting("Artifact ID", GenerationPhase.FIRST_STEP) {
shouldNotBeBlank()
validate(StringValidators.shouldBeValidIdentifier("Artifact ID", setOf('_')))
}
val version by stringSetting("Version", GenerationPhase.PROJECT_GENERATION) {
val version by stringSetting("Version", GenerationPhase.FIRST_STEP) {
shouldNotBeBlank()
validate(StringValidators.shouldBeValidIdentifier("Version", setOf('_', '-', '.')))
defaultValue = value("1.0-SNAPSHOT")