User: kyle wood
Date: 13 Nov 26 06:36
Revision: f1aea09fd4ddfd440b41a625d02ccda0cc8b4eb2
Summary:
Remove legacy creator code (#2662)
TeamCity URL: http://ci.mcdev.io:80/viewModification.html?tab=vcsModificationFiles&modId=10751&personal=false
Index: changelog.md
===================================================================
--- changelog.md (revision 37b6de0fe28b3c7ce9ae7eef85e6512975dc93a8)
+++ changelog.md (revision f1aea09fd4ddfd440b41a625d02ccda0cc8b4eb2)
@@ -1,5 +1,12 @@
# Minecraft Development for IntelliJ
+## [1.9.2]
+
+### Removed
+
+- Removed the old project wizard ("Minecraft (Old Wizard)"). New projects are created with the template-based "Minecraft" project creator.
+- Removed the file templates used by the old project wizard from Settings | Editor | File and Code Templates. The class skeleton templates are unchanged.
+
## [1.9.1]
### Added
Index: gradle.properties
===================================================================
--- gradle.properties (revision 37b6de0fe28b3c7ce9ae7eef85e6512975dc93a8)
+++ gradle.properties (revision f1aea09fd4ddfd440b41a625d02ccda0cc8b4eb2)
@@ -30,3 +30,6 @@
org.gradle.parallel=true
org.gradle.caching=true
+
+# Enabled parallel sync for Gradle 9.4+
+org.gradle.tooling.parallel=true
Index: gradle/wrapper/gradle-wrapper.properties
===================================================================
--- gradle/wrapper/gradle-wrapper.properties (revision 37b6de0fe28b3c7ce9ae7eef85e6512975dc93a8)
+++ gradle/wrapper/gradle-wrapper.properties (revision f1aea09fd4ddfd440b41a625d02ccda0cc8b4eb2)
@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-9.4.1-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-9.9.0-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
Index: src/main/kotlin/creator/MinecraftModuleBuilder.kt
===================================================================
--- src/main/kotlin/creator/MinecraftModuleBuilder.kt (revision 37b6de0fe28b3c7ce9ae7eef85e6512975dc93a8)
+++ src/main/kotlin/creator/MinecraftModuleBuilder.kt (revision 37b6de0fe28b3c7ce9ae7eef85e6512975dc93a8)
@@ -1,62 +0,0 @@
-/*
- * Minecraft Development for IntelliJ
- *
- * https://mcdev.io/
- *
- * Copyright (C) 2025 minecraft-dev
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published
- * by the Free Software Foundation, version 3.0 only.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program. If not, see .
- */
-
-package com.demonwav.mcdev.creator
-
-import com.demonwav.mcdev.asset.MCDevBundle
-import com.demonwav.mcdev.asset.PlatformAssets
-import com.demonwav.mcdev.creator.buildsystem.BuildSystemPropertiesStep
-import com.demonwav.mcdev.creator.platformtype.PlatformTypeStep
-import com.demonwav.mcdev.creator.step.NewProjectWizardChainStep.Companion.nextStep
-import com.intellij.ide.projectWizard.ProjectSettingsStep
-import com.intellij.ide.util.projectWizard.WizardContext
-import com.intellij.ide.wizard.AbstractNewProjectWizardBuilder
-import com.intellij.ide.wizard.GitNewProjectWizardStep
-import com.intellij.ide.wizard.NewProjectWizardBaseStep
-import com.intellij.ide.wizard.RootNewProjectWizardStep
-import com.intellij.openapi.roots.ModifiableRootModel
-
-class MinecraftModuleBuilder : AbstractNewProjectWizardBuilder() {
-
- override fun getPresentableName() = "Minecraft (Old Wizard)"
- override fun getNodeIcon() = PlatformAssets.MINECRAFT_ICON
- override fun getGroupName() = "Minecraft"
- override fun getBuilderId() = "MINECRAFT_MODULE"
- override fun getDescription() = MCDevBundle("creator.ui.create_minecraft_project")
-
- override fun setupRootModel(modifiableRootModel: ModifiableRootModel) {
- if (moduleJdk != null) {
- modifiableRootModel.sdk = moduleJdk
- } else {
- modifiableRootModel.inheritSdk()
- }
- }
-
- override fun getParentGroup() = "Minecraft"
-
- override fun createStep(context: WizardContext) = RootNewProjectWizardStep(context)
- .nextStep(::NewProjectWizardBaseStep)
- .nextStep(::GitNewProjectWizardStep)
- .nextStep(PlatformTypeStep::create)
- .nextStep(::BuildSystemPropertiesStep)
- .nextStep(::ProjectSetupFinalizerWizardStep)
-
- override fun getIgnoredSteps() = listOf(ProjectSettingsStep::class.java)
-}
Index: src/main/kotlin/creator/ParchmentStep.kt
===================================================================
--- src/main/kotlin/creator/ParchmentStep.kt (revision 37b6de0fe28b3c7ce9ae7eef85e6512975dc93a8)
+++ src/main/kotlin/creator/ParchmentStep.kt (revision 37b6de0fe28b3c7ce9ae7eef85e6512975dc93a8)
@@ -1,168 +0,0 @@
-/*
- * Minecraft Development for IntelliJ
- *
- * https://mcdev.io/
- *
- * Copyright (C) 2025 minecraft-dev
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published
- * by the Free Software Foundation, version 3.0 only.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program. If not, see .
- */
-
-package com.demonwav.mcdev.creator
-
-import com.demonwav.mcdev.asset.MCDevBundle
-import com.demonwav.mcdev.creator.step.AbstractMcVersionChainStep
-import com.demonwav.mcdev.util.SemanticVersion
-import com.intellij.icons.AllIcons
-import com.intellij.ide.wizard.AbstractNewProjectWizardStep
-import com.intellij.ide.wizard.NewProjectWizardStep
-import com.intellij.openapi.observable.properties.ObservableMutableProperty
-import com.intellij.openapi.observable.util.and
-import com.intellij.openapi.observable.util.bindBooleanStorage
-import com.intellij.openapi.observable.util.not
-import com.intellij.openapi.project.Project
-import com.intellij.openapi.util.Key
-import com.intellij.ui.content.AlertIcon
-import com.intellij.ui.dsl.builder.Panel
-import com.intellij.ui.dsl.builder.bindItem
-import com.intellij.ui.dsl.builder.bindSelected
-import com.intellij.util.application
-import com.intellij.util.ui.AsyncProcessIcon
-import javax.swing.DefaultComboBoxModel
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.runBlocking
-import kotlinx.coroutines.swing.Swing
-import kotlinx.coroutines.withContext
-
-class ParchmentStep(parent: NewProjectWizardStep) : AbstractNewProjectWizardStep(parent) {
-
- val useParchmentProperty = propertyGraph.property(false)
- .bindBooleanStorage("${javaClass.name}.useParchment")
- var useParchment by useParchmentProperty
-
- val parchmentVersionProperty = propertyGraph.property(null)
- var parchmentVersion by parchmentVersionProperty
-
- val parchmentVersionsProperty = propertyGraph.property>(emptyList())
- var parchmentVersions by parchmentVersionsProperty
-
- val loadingVersionsProperty = propertyGraph.property(false)
- var loadingVersions by loadingVersionsProperty
-
- val hasParchmentVersionProperty = propertyGraph.property(false)
- var hasParchmentVersion by hasParchmentVersionProperty
-
- val includeOlderMcVersionsProperty = propertyGraph.property(false)
- .bindBooleanStorage("${javaClass.name}.includeOlderMcVersions")
- var includeOlderMcVersions by includeOlderMcVersionsProperty
-
- val includeSnapshotsVersionsProperty = propertyGraph.property(false)
- .bindBooleanStorage("${javaClass.name}.includeSnapshotsVersions")
- var includeSnapshotsVersions by includeSnapshotsVersionsProperty
-
- private val parchmentVersionsModel = DefaultComboBoxModel(emptyArray())
- private val mcVersionProperty: ObservableMutableProperty
-
- init {
- storeToData()
- @Suppress("UNCHECKED_CAST")
- mcVersionProperty = findStep().getVersionProperty(0)
- as ObservableMutableProperty
- mcVersionProperty.afterChange { updateVersionsModel() }
-
- includeOlderMcVersionsProperty.afterChange { updateVersionsModel() }
- includeSnapshotsVersionsProperty.afterChange { updateVersionsModel() }
-
- downloadVersions()
- }
-
- private fun updateVersionsModel() {
- val mcVersion = mcVersionProperty.get()
- val versions = parchmentVersions.filter { version ->
- if (!includeOlderMcVersions && version.mcVersion < mcVersion) {
- return@filter false
- }
-
- if (!includeSnapshotsVersions && version.parchmentVersion.contains("-SNAPSHOT")) {
- return@filter false
- }
-
- return@filter true
- }
-
- hasParchmentVersion = versions.isNotEmpty()
-
- parchmentVersionsModel.removeAllElements()
- parchmentVersionsModel.addAll(versions)
-
- parchmentVersionsModel.selectedItem = versions.firstOrNull { !it.parchmentVersion.contains('-') }
- ?: versions.firstOrNull()
-
- loadingVersions = false
- }
-
- private fun downloadVersions() {
- loadingVersions = true
- parchmentVersionsModel.removeAllElements()
- application.executeOnPooledThread {
- runBlocking {
- val versions = ParchmentVersion.downloadData()
- withContext(Dispatchers.Swing) {
- parchmentVersions = versions
- updateVersionsModel()
- }
- }
- }
- }
-
- override fun setupUI(builder: Panel) {
- with(builder) {
- row(MCDevBundle("creator.ui.parchment.label")) {
- checkBox("")
- .bindSelected(useParchmentProperty)
-
- comboBox(parchmentVersionsModel)
- .enabledIf(useParchmentProperty and hasParchmentVersionProperty)
- .bindItem(parchmentVersionProperty)
-
- cell(AsyncProcessIcon("$javaClass.parchmentVersions"))
- .visibleIf(loadingVersionsProperty)
-
- label(MCDevBundle("creator.ui.parchment.no_version.message"))
- .visibleIf(hasParchmentVersionProperty.not() and loadingVersionsProperty.not())
- .applyToComponent { icon = AlertIcon(AllIcons.General.Warning) }
- }
-
- row(MCDevBundle("creator.ui.parchment.include.label")) {
- checkBox(MCDevBundle("creator.ui.parchment.include.old_mc.label"))
- .enabledIf(useParchmentProperty)
- .bindSelected(includeOlderMcVersionsProperty)
- checkBox(MCDevBundle("creator.ui.parchment.include.snapshots.label"))
- .enabledIf(useParchmentProperty)
- .bindSelected(includeSnapshotsVersionsProperty)
- }
- }
-
- super.setupUI(builder)
- }
-
- override fun setupProject(project: Project) {
- data.putUserData(USE_KEY, useParchment)
- data.putUserData(VERSION_KEY, parchmentVersion)
- }
-
- companion object {
- val USE_KEY = Key.create("${ParchmentStep::class.java.name}.useParchment")
- val VERSION_KEY = Key.create("${ParchmentStep::class.java}.parchmentVersion")
- }
-}
Index: src/main/kotlin/creator/PlatformVersion.kt
===================================================================
--- src/main/kotlin/creator/PlatformVersion.kt (revision 37b6de0fe28b3c7ce9ae7eef85e6512975dc93a8)
+++ src/main/kotlin/creator/PlatformVersion.kt (revision 37b6de0fe28b3c7ce9ae7eef85e6512975dc93a8)
@@ -1,116 +0,0 @@
-/*
- * Minecraft Development for IntelliJ
- *
- * https://mcdev.io/
- *
- * Copyright (C) 2025 minecraft-dev
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published
- * by the Free Software Foundation, version 3.0 only.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program. If not, see .
- */
-
-package com.demonwav.mcdev.creator
-
-import com.demonwav.mcdev.platform.PlatformType
-import com.demonwav.mcdev.update.PluginUtil
-import com.demonwav.mcdev.util.fromJson
-import com.demonwav.mcdev.util.mapFirstNotNull
-import com.demonwav.mcdev.util.withSuppressed
-import com.github.kittinunf.fuel.core.FuelManager
-import com.github.kittinunf.fuel.core.requests.suspendable
-import com.github.kittinunf.fuel.coroutines.awaitString
-import com.google.gson.Gson
-import com.intellij.openapi.diagnostic.Attachment
-import com.intellij.openapi.diagnostic.logger
-import com.intellij.util.net.JdkProxyProvider
-import java.io.IOException
-import java.net.Proxy
-import java.net.URI
-import kotlin.reflect.KClass
-
-// Cloudflare and GitHub are both global CDNs
-// Cloudflare is used first / preferred simply due to domain preference
-private const val CLOUDFLARE_BASE_URL = "https://mcdev.io/versions/"
-// Directly retrieving the file via GitHub is the second option. In some regions / networks Cloudflare is blocked,
-// but we may still be able to reach GitHub
-private const val GITHUB_BASE_URL = "https://raw.githubusercontent.com/minecraft-dev/minecraftdev.org/master/versions/"
-// Finally, there are apparently also regions / networks where both Cloudflare and GitHub is blocked.
-// Or maybe the domain `mcdev.io` (and prior to that, `minecraftdev.org`) is blocked due to weird domain
-// rules (perhaps blocking on the word "minecraft"). In one last ditch effort to retrieve the version json
-// we can also pull from this host, a separate host using a separate domain. This is an OVH server, not
-// proxied through Cloudflare.
-private const val OVH_BASE_URL = "https://versions.denwav.com/versions/"
-
-private val URLS = listOf(CLOUDFLARE_BASE_URL, GITHUB_BASE_URL, OVH_BASE_URL)
-
-val PLATFORM_VERSION_LOGGER = logger()
-
-suspend fun getVersionSelector(type: PlatformType): PlatformVersion {
- val versionJson = type.versionJson ?: throw UnsupportedOperationException("Incorrect platform type: $type")
- return getVersionJson(versionJson)
-}
-
-suspend inline fun getVersionJson(path: String): T {
- return getVersionJson(path, T::class)
-}
-
-suspend fun getVersionJson(path: String, type: KClass): T {
- val text = getText(path)
- try {
- return Gson().fromJson(text, type)
- } catch (e: Exception) {
- val attachment = Attachment("JSON Document", text)
- attachment.isIncluded = true
- PLATFORM_VERSION_LOGGER.error("Failed to parse JSON document from '$path'", e, attachment)
- throw e
- }
-}
-
-suspend fun getText(path: String): String {
- var thrown: Exception? = null
- return URLS.mapFirstNotNull { url ->
- try {
- doCall(url + path)
- } catch (e: Exception) {
- PLATFORM_VERSION_LOGGER.warn("Failed to reach URL $url$path")
- thrown = withSuppressed(thrown, e)
- null
- }
- } ?: throw thrown!!
-}
-
-private suspend fun doCall(urlText: String): String {
- val manager = FuelManager()
- manager.proxy = selectProxy(urlText)
-
- return manager.get(urlText)
- .header("User-Agent", "github_org/minecraft-dev/${PluginUtil.pluginVersion}")
- .header("Accepts", "application/json")
- .suspendable()
- .awaitString()
-}
-
-fun selectProxy(urlText: String): Proxy? {
- val uri = URI(urlText)
- val url = uri.toURL()
-
- val proxies = JdkProxyProvider.getInstance().proxySelector.select(uri)
- for (proxy in proxies) {
- try {
- url.openConnection(proxy)
- return proxy
- } catch (_: IOException) {}
- }
- return null
-}
-
-data class PlatformVersion(var versions: List, var selectedIndex: Int)
Index: src/main/kotlin/creator/ProjectSetupFinalizerWizardStep.kt
===================================================================
--- src/main/kotlin/creator/ProjectSetupFinalizerWizardStep.kt (revision 37b6de0fe28b3c7ce9ae7eef85e6512975dc93a8)
+++ src/main/kotlin/creator/ProjectSetupFinalizerWizardStep.kt (revision 37b6de0fe28b3c7ce9ae7eef85e6512975dc93a8)
@@ -1,174 +0,0 @@
-/*
- * Minecraft Development for IntelliJ
- *
- * https://mcdev.io/
- *
- * Copyright (C) 2026 minecraft-dev
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published
- * by the Free Software Foundation, version 3.0 only.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program. If not, see .
- */
-
-package com.demonwav.mcdev.creator
-
-import com.demonwav.mcdev.asset.MCDevBundle
-import com.demonwav.mcdev.creator.step.NewProjectWizardChainStep.Companion.nextStep
-import com.demonwav.mcdev.util.mapFirstNotNull
-import com.intellij.ide.wizard.AbstractNewProjectWizardStep
-import com.intellij.ide.wizard.NewProjectWizardStep
-import com.intellij.openapi.extensions.ExtensionPointName
-import com.intellij.openapi.observable.properties.GraphProperty
-import com.intellij.openapi.project.Project
-import com.intellij.openapi.projectRoots.JavaSdk
-import com.intellij.openapi.projectRoots.JavaSdkVersion
-import com.intellij.openapi.projectRoots.Sdk
-import com.intellij.openapi.ui.ValidationInfo
-import com.intellij.openapi.ui.validation.DialogValidation
-import com.intellij.openapi.ui.validation.WHEN_GRAPH_PROPAGATION_FINISHED
-import com.intellij.ui.JBColor
-import com.intellij.ui.dsl.builder.Panel
-import com.intellij.ui.dsl.builder.Placeholder
-import javax.swing.JLabel
-import javax.swing.JPanel
-
-class ProjectSetupFinalizerWizardStep(parent: NewProjectWizardStep) : AbstractNewProjectWizardStep(parent) {
- private val finalizers: List by lazy {
- val factories = ProjectSetupFinalizer.EP_NAME.extensionList
- val result = mutableListOf()
- if (factories.isNotEmpty()) {
- var par: NewProjectWizardStep = this
- for (factory in factories) {
- val finalizer = factory.create(par)
- result += finalizer
- par = finalizer
- }
- }
- result
- }
- private val step by lazy {
- when (finalizers.size) {
- 0 -> null
- 1 -> finalizers[0]
- else -> {
- var step = finalizers[0].nextStep { finalizers[1] }
- for (i in 2 until finalizers.size) {
- step = step.nextStep { finalizers[i] }
- }
- step
- }
- }
- }
-
- override fun setupUI(builder: Panel) {
- for (step in finalizers) {
- step.setupUI(builder)
- }
- if (finalizers.isNotEmpty()) {
- builder.row {
- cell(JPanel())
- .validationRequestor(WHEN_GRAPH_PROPAGATION_FINISHED(propertyGraph))
- .validation(
- DialogValidation {
- finalizers.mapFirstNotNull(ProjectSetupFinalizer::validate)?.let(::ValidationInfo)
- }
- )
- }
- }
- }
-
- override fun setupProject(project: Project) {
- for (step in finalizers) {
- step.setupProject(project)
- }
- }
-}
-
-/**
- * A step applied after all other steps for all Minecraft project creators. These steps can also block project creation
- * by providing extra validations.
- *
- * To add custom project setup finalizers, register a [Factory] to the
- * `com.demonwav.minecraft-dev.projectSetupFinalizer` extension point.
- */
-interface ProjectSetupFinalizer : NewProjectWizardStep {
- companion object {
- val EP_NAME = ExtensionPointName("com.demonwav.minecraft-dev.projectSetupFinalizer")
- }
-
- /**
- * Validates the existing settings of this wizard.
- *
- * @return `null` if the settings are valid, or an error message if they are invalid.
- */
- fun validate(): String? = null
-
- interface Factory {
- fun create(parent: NewProjectWizardStep): ProjectSetupFinalizer
- }
-}
-
-class JdkProjectSetupFinalizer(
- parent: NewProjectWizardStep,
-) : AbstractNewProjectWizardStep(parent), ProjectSetupFinalizer {
- private val sdkProperty: GraphProperty = propertyGraph.property(null)
- private var sdk by sdkProperty
- private var sdkComboBox: JdkComboBoxWithPreference? = null
- private var preferredJdkLabel: Placeholder? = null
- private var preferredJdkReason = MCDevBundle("creator.validation.jdk_preferred_default_reason")
-
- val preferredJdkProperty = propertyGraph.property(JavaSdkVersion.JDK_17)
-
- var preferredJdk: JavaSdkVersion by preferredJdkProperty
- private set
-
- fun setPreferredJdk(value: JavaSdkVersion, reason: String) {
- preferredJdk = value
- preferredJdkReason = reason
- sdkComboBox?.setPreferredJdk(value)
- updatePreferredJdkLabel()
- }
-
- init {
- storeToData()
-
- sdkProperty.afterChange {
- updatePreferredJdkLabel()
- }
- }
-
- private fun updatePreferredJdkLabel() {
- val sdk = this.sdk ?: return
- val version = JavaSdk.getInstance().getVersion(sdk) ?: return
- if (version == preferredJdk) {
- preferredJdkLabel?.component = null
- } else {
- preferredJdkLabel?.component =
- JLabel(MCDevBundle("creator.validation.jdk_preferred", preferredJdk.description, preferredJdkReason))
- .also { it.foreground = JBColor.YELLOW }
- }
- }
-
- override fun setupUI(builder: Panel) {
- with(builder) {
- row("JDK:") {
- val sdkComboBox = jdkComboBoxWithPreference(context, sdkProperty, "${javaClass.name}.sdk")
- this@JdkProjectSetupFinalizer.sdkComboBox = sdkComboBox.component
- this@JdkProjectSetupFinalizer.preferredJdkLabel = placeholder()
- updatePreferredJdkLabel()
- }
- }
- }
-
- class Factory : ProjectSetupFinalizer.Factory {
- override fun create(parent: NewProjectWizardStep) = JdkProjectSetupFinalizer(parent)
- }
-}
Index: src/main/kotlin/creator/buildsystem/AbstractBuildSystemStep.kt
===================================================================
--- src/main/kotlin/creator/buildsystem/AbstractBuildSystemStep.kt (revision 37b6de0fe28b3c7ce9ae7eef85e6512975dc93a8)
+++ src/main/kotlin/creator/buildsystem/AbstractBuildSystemStep.kt (revision 37b6de0fe28b3c7ce9ae7eef85e6512975dc93a8)
@@ -1,120 +0,0 @@
-/*
- * Minecraft Development for IntelliJ
- *
- * https://mcdev.io/
- *
- * Copyright (C) 2025 minecraft-dev
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published
- * by the Free Software Foundation, version 3.0 only.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program. If not, see .
- */
-
-package com.demonwav.mcdev.creator.buildsystem
-
-import com.demonwav.mcdev.asset.MCDevBundle
-import com.demonwav.mcdev.creator.findStep
-import com.demonwav.mcdev.creator.storeToData
-import com.intellij.ide.util.projectWizard.WizardContext
-import com.intellij.ide.wizard.AbstractNewProjectWizardMultiStep
-import com.intellij.ide.wizard.AbstractNewProjectWizardStep
-import com.intellij.ide.wizard.NewProjectWizardMultiStepFactory
-import com.intellij.ide.wizard.NewProjectWizardStep
-import com.intellij.openapi.extensions.ExtensionPointName
-import com.intellij.openapi.project.Project
-import com.intellij.openapi.util.Key
-import com.intellij.ui.dsl.builder.Panel
-
-abstract class AbstractBuildSystemStep(
- parent: NewProjectWizardStep,
-) : AbstractNewProjectWizardMultiStep(parent, EP_NAME) {
- companion object {
- private val PLATFORM_NAME_KEY = Key.create("mcdev.platformName")
- val EP_NAME = ExtensionPointName("com.demonwav.minecraft-dev.buildSystemWizard")
- }
-
- init {
- storeToData(javaClass)
- }
-
- abstract val platformName: String
-
- override val self get() = this
- override val label
- get() = MCDevBundle("creator.ui.build_system.label")
-
- override fun initSteps(): LinkedHashMap {
- context.putUserData(PLATFORM_NAME_KEY, platformName)
- return super.initSteps()
- }
-
- override fun setupSwitcherUi(builder: Panel) {
- if (steps.size > 1) {
- super.setupSwitcherUi(builder)
- }
- }
-
- override fun setupUI(builder: Panel) {
- val stepUninitialized = step.isEmpty()
- super.setupUI(builder)
-
- // if no value was previously set for the step (i.e. not saved from when the user previously used this wizard)
- // then set the build system to the preferred one for this platform, if one exists
- if (stepUninitialized) {
- for (buildSystem in steps.keys) {
- if (BuildSystemSupport.getInstance(platformName, buildSystem)?.preferred == true) {
- step = buildSystem
- break
- }
- }
- }
- }
-
- interface Factory : NewProjectWizardMultiStepFactory {
- override fun isEnabled(context: WizardContext): Boolean {
- val platformName = context.getUserData(PLATFORM_NAME_KEY)
- ?: throw IllegalStateException("Platform name not set")
- return BuildSystemSupport.getInstance(platformName, name) != null
- }
-
- override fun createStep(parent: AbstractBuildSystemStep): NewProjectWizardStep {
- val platformName = parent.context.getUserData(PLATFORM_NAME_KEY)
- ?: throw IllegalStateException("Platform name not set")
- val buildSystemSupport = BuildSystemSupport.getInstance(platformName, name)
- ?: throw IllegalStateException("Build system unsupported, this factory should have been filtered out")
- return buildSystemSupport.createStep(BuildSystemSupport.PRE_STEP, parent)
- }
- }
-}
-
-class GradleBuildSystem : AbstractBuildSystemStep.Factory {
- override val name
- get() = MCDevBundle("creator.ui.build_system.label.gradle")
-}
-
-class MavenBuildSystem : AbstractBuildSystemStep.Factory {
- override val name
- get() = MCDevBundle("creator.ui.build_system.label.maven")
-}
-
-abstract class AbstractRunBuildSystemStep(
- parent: NewProjectWizardStep,
- private val buildSystemStepClass: Class,
-) : AbstractNewProjectWizardStep(parent) {
- abstract val step: String
-
- override fun setupProject(project: Project) {
- val buildSystemStep = findStep(buildSystemStepClass)
- val buildSystemSupport = BuildSystemSupport.getInstance(buildSystemStep.platformName, buildSystemStep.step)
- ?: throw IllegalStateException("Build system unsupported, this should have been filtered out")
- buildSystemSupport.createStep(step, this).setupProject(project)
- }
-}
Index: src/main/kotlin/creator/buildsystem/BuildSystem.kt
===================================================================
--- src/main/kotlin/creator/buildsystem/BuildSystem.kt (revision 37b6de0fe28b3c7ce9ae7eef85e6512975dc93a8)
+++ src/main/kotlin/creator/buildsystem/BuildSystem.kt (revision 37b6de0fe28b3c7ce9ae7eef85e6512975dc93a8)
@@ -1,42 +0,0 @@
-/*
- * Minecraft Development for IntelliJ
- *
- * https://mcdev.io/
- *
- * Copyright (C) 2025 minecraft-dev
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published
- * by the Free Software Foundation, version 3.0 only.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program. If not, see .
- */
-
-package com.demonwav.mcdev.creator.buildsystem
-
-import java.util.EnumSet
-
-enum class BuildSystemType {
- MAVEN,
- GRADLE,
-}
-
-data class BuildDependency(
- val groupId: String = "",
- val artifactId: String = "",
- val version: String = "",
- val mavenScope: String? = null,
- val gradleConfiguration: String? = null,
-)
-
-data class BuildRepository(
- var id: String = "",
- var url: String = "",
- val buildSystems: EnumSet = EnumSet.allOf(BuildSystemType::class.java),
-)
Index: src/main/kotlin/creator/buildsystem/BuildSystemPropertiesStep.kt
===================================================================
--- src/main/kotlin/creator/buildsystem/BuildSystemPropertiesStep.kt (revision 37b6de0fe28b3c7ce9ae7eef85e6512975dc93a8)
+++ src/main/kotlin/creator/buildsystem/BuildSystemPropertiesStep.kt (revision 37b6de0fe28b3c7ce9ae7eef85e6512975dc93a8)
@@ -1,93 +0,0 @@
-/*
- * Minecraft Development for IntelliJ
- *
- * https://mcdev.io/
- *
- * Copyright (C) 2025 minecraft-dev
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published
- * by the Free Software Foundation, version 3.0 only.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program. If not, see .
- */
-
-package com.demonwav.mcdev.creator.buildsystem
-
-import com.demonwav.mcdev.asset.MCDevBundle
-import com.demonwav.mcdev.creator.storeToData
-import com.demonwav.mcdev.util.SemanticVersion
-import com.intellij.ide.wizard.AbstractNewProjectWizardStep
-import com.intellij.ide.wizard.NewProjectWizardBaseData.Companion.baseData
-import com.intellij.ide.wizard.NewProjectWizardStep
-import com.intellij.openapi.observable.util.bindStorage
-import com.intellij.openapi.ui.validation.CHECK_ARTIFACT_ID
-import com.intellij.openapi.ui.validation.CHECK_GROUP_ID
-import com.intellij.openapi.ui.validation.CHECK_NON_EMPTY
-import com.intellij.openapi.ui.validation.WHEN_GRAPH_PROPAGATION_FINISHED
-import com.intellij.openapi.ui.validation.validationErrorIf
-import com.intellij.ui.dsl.builder.COLUMNS_MEDIUM
-import com.intellij.ui.dsl.builder.Panel
-import com.intellij.ui.dsl.builder.bindText
-import com.intellij.ui.dsl.builder.columns
-import com.intellij.ui.dsl.builder.textValidation
-
-private val nonExampleValidation = validationErrorIf(MCDevBundle("creator.validation.group_id_non_example")) {
- it == "org.example"
-}
-
-private val versionValidation = validationErrorIf(MCDevBundle("creator.validation.semantic_version")) {
- SemanticVersion.tryParse(it) == null
-}
-
-class BuildSystemPropertiesStep(parent: NewProjectWizardStep) : AbstractNewProjectWizardStep(parent) {
-
- val groupIdProperty = propertyGraph.property("org.example")
- .bindStorage("${javaClass.name}.groupId")
- val artifactIdProperty = propertyGraph.lazyProperty(::suggestArtifactId)
- val versionProperty = propertyGraph.property("1.0-SNAPSHOT")
- .bindStorage("${javaClass.name}.version")
-
- var groupId by groupIdProperty
- var artifactId by artifactIdProperty
- var version by versionProperty
-
- init {
- artifactIdProperty.dependsOn(baseData!!.nameProperty, ::suggestArtifactId)
- storeToData()
- }
-
- private fun suggestArtifactId() = baseData!!.name
-
- override fun setupUI(builder: Panel) {
- builder.collapsibleGroup(MCDevBundle("creator.ui.group.title")) {
- row(MCDevBundle("creator.ui.group.group_id")) {
- textField()
- .bindText(groupIdProperty)
- .columns(COLUMNS_MEDIUM)
- .validationRequestor(WHEN_GRAPH_PROPAGATION_FINISHED(propertyGraph))
- .textValidation(CHECK_NON_EMPTY, CHECK_GROUP_ID, nonExampleValidation)
- }
- row(MCDevBundle("creator.ui.group.artifact_id")) {
- textField()
- .bindText(artifactIdProperty)
- .columns(COLUMNS_MEDIUM)
- .validationRequestor(WHEN_GRAPH_PROPAGATION_FINISHED(propertyGraph))
- .textValidation(CHECK_NON_EMPTY, CHECK_ARTIFACT_ID)
- }
- row(MCDevBundle("creator.ui.group.version")) {
- textField()
- .bindText(versionProperty)
- .columns(COLUMNS_MEDIUM)
- .validationRequestor(WHEN_GRAPH_PROPAGATION_FINISHED(propertyGraph))
- .textValidation(versionValidation)
- }
- }.expanded = true
- }
-}
Index: src/main/kotlin/creator/buildsystem/BuildSystemSupport.kt
===================================================================
--- src/main/kotlin/creator/buildsystem/BuildSystemSupport.kt (revision 37b6de0fe28b3c7ce9ae7eef85e6512975dc93a8)
+++ src/main/kotlin/creator/buildsystem/BuildSystemSupport.kt (revision 37b6de0fe28b3c7ce9ae7eef85e6512975dc93a8)
@@ -1,66 +0,0 @@
-/*
- * Minecraft Development for IntelliJ
- *
- * https://mcdev.io/
- *
- * Copyright (C) 2025 minecraft-dev
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published
- * by the Free Software Foundation, version 3.0 only.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program. If not, see .
- */
-
-package com.demonwav.mcdev.creator.buildsystem
-
-import com.intellij.ide.wizard.NewProjectWizardStep
-import com.intellij.openapi.extensions.ExtensionPointName
-import com.intellij.openapi.extensions.RequiredElement
-import com.intellij.openapi.util.KeyedExtensionCollector
-import com.intellij.serviceContainer.BaseKeyedLazyInstance
-import com.intellij.util.KeyedLazyInstance
-import com.intellij.util.xmlb.annotations.Attribute
-
-interface BuildSystemSupport {
- companion object {
- private val EP_NAME = ExtensionPointName>(
- "com.demonwav.minecraft-dev.buildSystemSupport",
- )
- private val COLLECTOR = KeyedExtensionCollector>(EP_NAME)
-
- fun getInstance(platform: String, buildSystem: String): BuildSystemSupport? =
- COLLECTOR.findSingle(platform to buildSystem)
-
- const val PRE_STEP = "pre"
- const val POST_STEP = "post"
- }
-
- fun createStep(step: String, parent: NewProjectWizardStep): NewProjectWizardStep
-
- val preferred get() = false
-}
-
-class BuildSystemSupportEntry : BaseKeyedLazyInstance(), KeyedLazyInstance {
- @Attribute("implementation")
- @RequiredElement
- lateinit var implementation: String
-
- @Attribute("platform")
- @RequiredElement
- lateinit var platform: String
-
- @Attribute("buildSystem")
- @RequiredElement
- lateinit var buildSystem: String
-
- override fun getKey() = (platform to buildSystem).toString()
-
- override fun getImplementationClassName() = implementation
-}
Index: src/main/kotlin/creator/buildsystem/GradleFile.kt
===================================================================
--- src/main/kotlin/creator/buildsystem/GradleFile.kt (revision 37b6de0fe28b3c7ce9ae7eef85e6512975dc93a8)
+++ src/main/kotlin/creator/buildsystem/GradleFile.kt (revision 37b6de0fe28b3c7ce9ae7eef85e6512975dc93a8)
@@ -1,242 +0,0 @@
-/*
- * Minecraft Development for IntelliJ
- *
- * https://mcdev.io/
- *
- * Copyright (C) 2026 minecraft-dev
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published
- * by the Free Software Foundation, version 3.0 only.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program. If not, see .
- */
-
-package com.demonwav.mcdev.creator.buildsystem
-
-import com.demonwav.mcdev.util.childrenOfType
-import com.demonwav.mcdev.util.mapFirstNotNull
-import com.intellij.openapi.extensions.ExtensionPointName
-import com.intellij.openapi.project.Project
-import com.intellij.openapi.util.text.StringUtil
-import com.intellij.psi.PsiFile
-import org.jetbrains.annotations.ApiStatus.Internal
-import org.jetbrains.kotlin.psi.KtBinaryExpression
-import org.jetbrains.kotlin.psi.KtBlockExpression
-import org.jetbrains.kotlin.psi.KtCallExpression
-import org.jetbrains.kotlin.psi.KtFile
-import org.jetbrains.kotlin.psi.KtNameReferenceExpression
-import org.jetbrains.kotlin.psi.KtPsiFactory
-import org.jetbrains.kotlin.psi.KtScriptInitializer
-import org.jetbrains.plugins.groovy.lang.psi.GroovyFile
-import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory
-import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock
-import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrMethodCallExpression
-import org.jetbrains.plugins.groovy.lang.psi.api.util.GrStatementOwner
-
-@Internal
-interface GradleFile {
- companion object {
- val EP_NAME = ExtensionPointName("com.demonwav.minecraft-dev.gradleFileType")
- }
-
- val psi: PsiFile
-
- fun addRepositories(project: Project, repositories: List)
- fun addDependencies(project: Project, dependencies: List)
- fun addPlugins(project: Project, plugins: List)
-
- interface Type {
- fun createGradleFile(psiFile: PsiFile): GradleFile?
- }
-}
-
-class GroovyGradleFile(override val psi: GroovyFile) : GradleFile {
- override fun addRepositories(project: Project, repositories: List) {
- val reposBlock = findOrCreateGroovyBlock(project, psi, "repositories")
- val elementFactory = GroovyPsiElementFactory.getInstance(project)
- for (repo in repositories) {
- if (BuildSystemType.GRADLE !in repo.buildSystems) {
- continue
- }
- val mavenBlock =
- elementFactory.createStatementFromText("maven {\n}", reposBlock) as GrMethodCallExpression
- val mavenClosure = mavenBlock.closureArguments[0]
- if (repo.id.isNotBlank()) {
- val idStatement =
- elementFactory.createStatementFromText("name = ${makeStringLiteral(repo.id)}")
- mavenClosure.addStatementBefore(idStatement, null)
- }
- val urlStatement =
- elementFactory.createStatementFromText("url = ${makeStringLiteral(repo.url)}")
- mavenClosure.addStatementBefore(urlStatement, null)
- reposBlock.addStatementBefore(mavenBlock, null)
- }
- }
-
- override fun addDependencies(project: Project, dependencies: List) {
- val depsBlock = findOrCreateGroovyBlock(project, psi, "dependencies")
- val elementFactory = GroovyPsiElementFactory.getInstance(project)
- for (dep in dependencies) {
- val gradleConfig = dep.gradleConfiguration ?: continue
- val stmt = elementFactory.createStatementFromText(
- "$gradleConfig \"${escapeGString(dep.groupId)}:${
- escapeGString(dep.artifactId)
- }:${escapeGString(dep.version)}\"",
- depsBlock,
- )
- depsBlock.addStatementBefore(stmt, null)
- }
- }
-
- override fun addPlugins(project: Project, plugins: List) {
- val pluginsBlock = findOrCreateGroovyBlock(project, psi, "plugins", first = true)
- val elementFactory = GroovyPsiElementFactory.getInstance(project)
- for (plugin in plugins) {
- val stmt = elementFactory.createStatementFromText(makePluginStatement(plugin, false))
- pluginsBlock.addStatementBefore(stmt, null)
- }
- }
-
- private fun findGroovyBlock(element: GrStatementOwner, name: String): GrClosableBlock? {
- return element.statements
- .mapFirstNotNull { call ->
- if (call is GrMethodCallExpression && call.callReference?.methodName == name) {
- call.closureArguments.firstOrNull()
- } else {
- null
- }
- }
- }
-
- private fun findOrCreateGroovyBlock(
- project: Project,
- element: GrStatementOwner,
- name: String,
- first: Boolean = false,
- ): GrClosableBlock {
- findGroovyBlock(element, name)?.let { return it }
- val block = GroovyPsiElementFactory.getInstance(project).createStatementFromText("$name {\n}", element)
- val anchor = if (first) {
- element.statements.firstOrNull()
- } else {
- null
- }
- return (element.addStatementBefore(block, anchor) as GrMethodCallExpression).closureArguments.first()
- }
-
- class Type : GradleFile.Type {
- override fun createGradleFile(psiFile: PsiFile) = (psiFile as? GroovyFile)?.let(::GroovyGradleFile)
- }
-}
-
-class KotlinGradleFile(override val psi: KtFile) : GradleFile {
- override fun addRepositories(project: Project, repositories: List) {
- val script = psi.script?.blockExpression ?: return
- val reposBlock = findOrCreateKotlinBlock(project, script, "repositories")
- val elementFactory = KtPsiFactory(project)
- for (repo in repositories) {
- if (BuildSystemType.GRADLE !in repo.buildSystems) {
- continue
- }
- val mavenBlock = elementFactory.createExpression("maven {\n}") as KtCallExpression
- val mavenLambda = mavenBlock.lambdaArguments[0].getLambdaExpression()!!.bodyExpression!!
- if (repo.id.isNotBlank()) {
- val idStatement = elementFactory.createAssignment("name = ${makeStringLiteral(repo.id)}")
- mavenLambda.addBefore(idStatement, mavenLambda.rBrace)
- }
- val urlStatement = elementFactory.createAssignment("url = uri(${makeStringLiteral(repo.url)})")
- mavenLambda.addBefore(urlStatement, mavenLambda.rBrace)
- reposBlock.addBefore(mavenBlock, reposBlock.rBrace)
- }
- }
-
- override fun addDependencies(project: Project, dependencies: List) {
- val script = psi.script?.blockExpression ?: return
- val depsBlock = findOrCreateKotlinBlock(project, script, "dependencies")
- val elementFactory = KtPsiFactory(project)
- for (dep in dependencies) {
- val gradleConfig = dep.gradleConfiguration ?: continue
- val stmt = elementFactory.createExpression(
- "$gradleConfig(\"${escapeGString(dep.groupId)}:${
- escapeGString(dep.artifactId)
- }:${escapeGString(dep.version)}\")",
- )
- depsBlock.addBefore(stmt, depsBlock.rBrace)
- }
- }
-
- override fun addPlugins(project: Project, plugins: List) {
- val script = psi.script?.blockExpression ?: return
- val pluginsBlock = findOrCreateKotlinBlock(project, script, "plugins", first = true)
- val elementFactory = KtPsiFactory(project)
- for (plugin in plugins) {
- val stmt = elementFactory.createExpression(makePluginStatement(plugin, true))
- pluginsBlock.addBefore(stmt, pluginsBlock.rBrace)
- }
- }
-
- private fun findKotlinBlock(element: KtBlockExpression, name: String): KtBlockExpression? {
- return element.childrenOfType()
- .flatMap { it.childrenOfType() }
- .mapFirstNotNull { call ->
- if ((call.calleeExpression as? KtNameReferenceExpression)?.getReferencedName() == name) {
- call.lambdaArguments.firstOrNull()?.getLambdaExpression()?.bodyExpression
- } else {
- null
- }
- }
- }
-
- private fun findOrCreateKotlinBlock(
- project: Project,
- element: KtBlockExpression,
- name: String,
- first: Boolean = false,
- ): KtBlockExpression {
- findKotlinBlock(element, name)?.let { return it }
- val block = KtPsiFactory(project).createExpression("$name {\n}")
- val addedBlock = if (first) {
- element.addAfter(block, element.lBrace)
- } else {
- element.addBefore(block, element.rBrace)
- }
- return (addedBlock as KtCallExpression).lambdaArguments.first().getLambdaExpression()!!.bodyExpression!!
- }
-
- private fun KtPsiFactory.createAssignment(text: String): KtBinaryExpression {
- return this.createBlock(text).firstStatement as KtBinaryExpression
- }
-
- class Type : GradleFile.Type {
- override fun createGradleFile(psiFile: PsiFile) = (psiFile as? KtFile)?.let(::KotlinGradleFile)
- }
-}
-
-private fun makeStringLiteral(str: String): String {
- return "\"${escapeGString(str)}\""
-}
-
-private fun escapeGString(str: String): String {
- return StringUtil.escapeStringCharacters(str.length, str, "\"$", StringBuilder()).toString()
-}
-
-private fun makePluginStatement(plugin: GradlePlugin, kotlin: Boolean): String {
- return buildString {
- if (kotlin) {
- append("id(${makeStringLiteral(plugin.id)})")
- } else {
- append("id ${makeStringLiteral(plugin.id)}")
- }
- plugin.version?.let { append(" version ${makeStringLiteral(it)}") }
- if (!plugin.apply) {
- append(" apply false")
- }
- }
-}
Index: src/main/kotlin/creator/buildsystem/gradle-steps.kt
===================================================================
--- src/main/kotlin/creator/buildsystem/gradle-steps.kt (revision 37b6de0fe28b3c7ce9ae7eef85e6512975dc93a8)
+++ src/main/kotlin/creator/buildsystem/gradle-steps.kt (revision 37b6de0fe28b3c7ce9ae7eef85e6512975dc93a8)
@@ -1,299 +0,0 @@
-/*
- * Minecraft Development for IntelliJ
- *
- * https://mcdev.io/
- *
- * Copyright (C) 2025 minecraft-dev
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published
- * by the Free Software Foundation, version 3.0 only.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program. If not, see .
- */
-
-package com.demonwav.mcdev.creator.buildsystem
-
-import com.demonwav.mcdev.asset.MCDevBundle
-import com.demonwav.mcdev.creator.addTemplates
-import com.demonwav.mcdev.creator.findStep
-import com.demonwav.mcdev.creator.notifyCreatedProjectNotOpened
-import com.demonwav.mcdev.creator.step.AbstractLongRunningStep
-import com.demonwav.mcdev.creator.step.AbstractReformatFilesStep
-import com.demonwav.mcdev.creator.step.FixedAssetsNewProjectWizardStep
-import com.demonwav.mcdev.util.MinecraftTemplates.Companion.GRADLE_WRAPPER_PROPERTIES
-import com.demonwav.mcdev.util.SemanticVersion
-import com.demonwav.mcdev.util.invokeAndWait
-import com.demonwav.mcdev.util.invokeLater
-import com.demonwav.mcdev.util.mapFirstNotNull
-import com.demonwav.mcdev.util.runGradleTask
-import com.demonwav.mcdev.util.runWriteAction
-import com.demonwav.mcdev.util.runWriteTask
-import com.demonwav.mcdev.util.virtualFileOrError
-import com.intellij.execution.RunManager
-import com.intellij.ide.ui.UISettings
-import com.intellij.ide.wizard.NewProjectWizardStep
-import com.intellij.ide.wizard.runAfterOpened
-import com.intellij.lang.properties.psi.PropertiesFile
-import com.intellij.openapi.application.ApplicationManager
-import com.intellij.openapi.fileEditor.FileDocumentManager
-import com.intellij.openapi.fileEditor.impl.NonProjectFileWritingAccessProvider
-import com.intellij.openapi.project.DumbService
-import com.intellij.openapi.project.Project
-import com.intellij.openapi.util.Key
-import com.intellij.openapi.vfs.VfsUtil
-import com.intellij.openapi.vfs.VirtualFile
-import com.intellij.openapi.wm.WindowManager
-import com.intellij.openapi.wm.ex.StatusBarEx
-import com.intellij.psi.PsiDocumentManager
-import com.intellij.psi.PsiFile
-import com.intellij.psi.PsiManager
-import java.nio.file.Path
-import java.util.concurrent.CountDownLatch
-import kotlinx.coroutines.runBlocking
-import org.jetbrains.plugins.gradle.service.execution.GradleExternalTaskConfigurationType
-import org.jetbrains.plugins.gradle.service.execution.GradleRunConfiguration
-import org.jetbrains.plugins.gradle.service.project.open.canLinkAndRefreshGradleProject
-import org.jetbrains.plugins.gradle.service.project.open.linkAndSyncGradleProject
-
-val DEFAULT_GRADLE_VERSION = SemanticVersion.release(8, 7)
-val GRADLE_VERSION_KEY = Key.create("mcdev.gradleVersion")
-
-fun FixedAssetsNewProjectWizardStep.addGradleWrapperProperties(project: Project) {
- val gradleVersion = data.getUserData(GRADLE_VERSION_KEY) ?: DEFAULT_GRADLE_VERSION
- addTemplateProperties("GRADLE_WRAPPER_VERSION" to gradleVersion)
- addTemplates(project, "gradle/wrapper/gradle-wrapper.properties" to GRADLE_WRAPPER_PROPERTIES)
-}
-
-abstract class AbstractRunGradleTaskStep(parent: NewProjectWizardStep) : AbstractLongRunningStep(parent) {
- abstract val task: String
- override val description get() = "Running Gradle task: '$task'"
-
- override fun perform(project: Project) {
- val outputDirectory = context.projectFileDirectory
- DumbService.getInstance(project).runWhenSmart {
- runGradleTask(project, Path.of(outputDirectory)) { settings ->
- settings.taskNames = listOf(task)
- }
- }
- }
-}
-
-class GradleWrapperStep(parent: NewProjectWizardStep) : AbstractRunGradleTaskStep(parent) {
- override val task = "wrapper"
-}
-
-abstract class AbstractPatchGradleFilesStep(parent: NewProjectWizardStep) : AbstractLongRunningStep(parent) {
- override val description
- get() = MCDevBundle("creator.step.gradle.patch_gradle.description")
-
- abstract fun patch(project: Project, gradleFiles: GradleFiles)
-
- protected fun addRepositories(project: Project, buildGradle: GradleFile?, repositories: List) {
- if (buildGradle == null || repositories.isEmpty()) {
- return
- }
-
- buildGradle.psi.runWriteAction {
- buildGradle.addRepositories(project, repositories)
- }
- }
-
- protected fun addDependencies(project: Project, buildGradle: GradleFile?, dependencies: List) {
- if (buildGradle == null || dependencies.isEmpty()) {
- return
- }
-
- buildGradle.psi.runWriteAction {
- buildGradle.addDependencies(project, dependencies)
- }
- }
-
- protected fun addPlugins(project: Project, buildGradle: GradleFile?, plugins: List) {
- if (buildGradle == null || plugins.isEmpty()) {
- return
- }
-
- buildGradle.psi.runWriteAction {
- buildGradle.addPlugins(project, plugins)
- }
- }
-
- override fun perform(project: Project) {
- invokeAndWait {
- if (project.isDisposed || !project.isInitialized) {
- notifyCreatedProjectNotOpened()
- return@invokeAndWait
- }
-
- runWriteTask {
- val rootDir = VfsUtil.findFile(Path.of(context.projectFileDirectory), true)
- ?: return@runWriteTask
- val gradleFiles = GradleFiles(project, rootDir)
- NonProjectFileWritingAccessProvider.disableChecksDuring {
- patch(project, gradleFiles)
- gradleFiles.commit()
- }
- }
- }
- }
-
- class GradleFiles(
- private val project: Project,
- private val rootDir: VirtualFile,
- ) {
- private val lazyBuildGradle = lazy {
- val file = rootDir.findChild("build.gradle") ?: rootDir.findChild("build.gradle.kts")
- ?: return@lazy null
- makeGradleFile(file)
- }
- private val lazySettingsGradle = lazy {
- val file = rootDir.findChild("settings.gradle") ?: rootDir.findChild("settings.gradle.kts")
- ?: return@lazy null
- makeGradleFile(file)
- }
- private val lazyGradleProperties = lazy {
- val file = rootDir.findChild("gradle.properties") ?: return@lazy null
- PsiManager.getInstance(project).findFile(file) as? PropertiesFile
- }
-
- val buildGradle by lazyBuildGradle
- val settingsGradle by lazySettingsGradle
- val gradleProperties by lazyGradleProperties
-
- private fun makeGradleFile(virtualFile: VirtualFile): GradleFile? {
- val psi = PsiManager.getInstance(project).findFile(virtualFile) ?: return null
- return GradleFile.EP_NAME.extensions.mapFirstNotNull { it.createGradleFile(psi) }
- }
-
- fun commit() {
- val files = mutableListOf()
- if (lazyBuildGradle.isInitialized()) {
- buildGradle?.psi?.let { files += it }
- }
- if (lazySettingsGradle.isInitialized()) {
- settingsGradle?.psi?.let { files += it }
- }
- if (lazyGradleProperties.isInitialized()) {
- (gradleProperties as? PsiFile)?.let { files += it }
- }
-
- val psiDocumentManager = PsiDocumentManager.getInstance(project)
- val fileDocumentManager = FileDocumentManager.getInstance()
- for (file in files) {
- val document = psiDocumentManager.getDocument(file) ?: continue
- fileDocumentManager.saveDocument(document)
- }
- }
- }
-}
-
-open class GradleImportStep(parent: NewProjectWizardStep) : AbstractLongRunningStep(parent) {
- override val description
- get() = MCDevBundle("creator.step.gradle.import_gradle.description")
-
- open val additionalRunTasks = emptyList()
-
- override fun perform(project: Project) {
- if (!project.isInitialized) {
- notifyCreatedProjectNotOpened()
- return
- }
-
- val rootDirectory = Path.of(context.projectFileDirectory)
- val buildSystemProps = findStep()
-
- // Tell IntelliJ to import this project
- rootDirectory.virtualFileOrError.refresh(false, true)
-
- val latch = CountDownLatch(1)
-
- invokeLater(project.disposed) {
- val path = rootDirectory.toAbsolutePath().toString()
- if (canLinkAndRefreshGradleProject(path, project, false)) {
- runBlocking {
- linkAndSyncGradleProject(project, path)
- }
- showProgress(project)
- }
-
- runAfterOpened(project) {
- latch.countDown()
- }
- }
-
- // Set up the run config
- // Get the gradle external task type, this is what sets it as a gradle task
- addRunTaskConfiguration(project, rootDirectory, buildSystemProps, "build")
- for (tasks in additionalRunTasks) {
- addRunTaskConfiguration(project, rootDirectory, buildSystemProps, tasks)
- }
-
- if (!ApplicationManager.getApplication().isDispatchThread) {
- latch.await()
- }
- }
-
- private fun addRunTaskConfiguration(
- project: Project,
- rootDirectory: Path,
- buildSystemProps: BuildSystemPropertiesStep,
- task: String,
- ) {
- val gradleType = GradleExternalTaskConfigurationType.getInstance()
-
- val runManager = RunManager.getInstance(project)
- val runConfigName = buildSystemProps.artifactId + ' ' + task
-
- val runConfiguration = GradleRunConfiguration(project, gradleType.factory, runConfigName)
-
- // Set relevant gradle values
- runConfiguration.settings.externalProjectPath = rootDirectory.toAbsolutePath().toString()
- runConfiguration.settings.executionName = runConfigName
- runConfiguration.settings.taskNames = listOf(task)
-
- runConfiguration.isAllowRunningInParallel = false
-
- val settings = runManager.createConfiguration(
- runConfiguration,
- gradleType.factory,
- )
-
- settings.isActivateToolWindowBeforeRun = true
- settings.storeInLocalWorkspace()
-
- runManager.addConfiguration(settings)
- if (runManager.selectedConfiguration == null) {
- runManager.selectedConfiguration = settings
- }
- }
-}
-
-class ReformatBuildGradleStep(parent: NewProjectWizardStep) : AbstractReformatFilesStep(parent) {
- override fun addFilesToReformat() {
- addFileToReformat("build.gradle")
- addFileToReformat("build.gradle.kts")
- }
-}
-
-// Show the background processes window for setup tasks
-private fun showProgress(project: Project) {
- if (!UISettings.getInstance().showStatusBar || UISettings.getInstance().presentationMode) {
- return
- }
-
- val statusBar = WindowManager.getInstance().getStatusBar(project) as? StatusBarEx ?: return
- statusBar.isProcessWindowOpen = true
-}
-
-data class GradlePlugin(
- val id: String,
- val version: String? = null,
- val apply: Boolean = true,
-)
Index: src/main/kotlin/creator/buildsystem/maven-steps.kt
===================================================================
--- src/main/kotlin/creator/buildsystem/maven-steps.kt (revision 37b6de0fe28b3c7ce9ae7eef85e6512975dc93a8)
+++ src/main/kotlin/creator/buildsystem/maven-steps.kt (revision 37b6de0fe28b3c7ce9ae7eef85e6512975dc93a8)
@@ -1,216 +0,0 @@
-/*
- * Minecraft Development for IntelliJ
- *
- * https://mcdev.io/
- *
- * Copyright (C) 2026 minecraft-dev
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published
- * by the Free Software Foundation, version 3.0 only.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program. If not, see .
- */
-
-package com.demonwav.mcdev.creator.buildsystem
-
-import com.demonwav.mcdev.asset.MCDevBundle
-import com.demonwav.mcdev.creator.findStep
-import com.demonwav.mcdev.creator.getVersionJson
-import com.demonwav.mcdev.creator.notifyCreatedProjectNotOpened
-import com.demonwav.mcdev.creator.step.AbstractLongRunningStep
-import com.demonwav.mcdev.creator.step.AbstractModNameStep
-import com.demonwav.mcdev.creator.step.AbstractReformatFilesStep
-import com.demonwav.mcdev.creator.step.DescriptionStep
-import com.demonwav.mcdev.creator.step.FixedAssetsNewProjectWizardStep
-import com.demonwav.mcdev.creator.step.WebsiteStep
-import com.demonwav.mcdev.util.invokeAndWait
-import com.demonwav.mcdev.util.runWriteAction
-import com.demonwav.mcdev.util.runWriteTask
-import com.intellij.execution.RunManager
-import com.intellij.ide.wizard.NewProjectWizardStep
-import com.intellij.openapi.fileEditor.FileDocumentManager
-import com.intellij.openapi.fileEditor.impl.NonProjectFileWritingAccessProvider
-import com.intellij.openapi.project.Project
-import com.intellij.openapi.vfs.VfsUtil
-import com.intellij.psi.PsiDocumentManager
-import com.intellij.psi.PsiManager
-import com.intellij.psi.xml.XmlFile
-import com.intellij.psi.xml.XmlTag
-import com.intellij.util.xml.DomManager
-import java.nio.file.Path
-import kotlinx.coroutines.runBlocking
-import org.jetbrains.idea.maven.dom.model.MavenDomProjectModel
-import org.jetbrains.idea.maven.execution.MavenRunConfiguration
-import org.jetbrains.idea.maven.execution.MavenRunConfigurationType
-
-private val pluginVersions by lazy {
- runBlocking {
- getVersionJson