User: joe
Date: 12 Nov 26 23:38
Revision: c83e78f9365bc2a0a2844ca45bf752f4f07f9cc5
Summary:
Revert "Replace code using internal API in PluginUpdater with the PluginUpdateCheckService API introduced in 2026.1"
This reverts commit f731810dcfe8eef5a723e818c0380d756820444d.
TeamCity URL: http://ci.mcdev.io:80/viewModification.html?tab=vcsModificationFiles&modId=10737&personal=false
Index: src/main/kotlin/update/ConfigurePluginUpdatesDialog.kt
===================================================================
--- src/main/kotlin/update/ConfigurePluginUpdatesDialog.kt (revision ff47a747c3bb3a57e6d3c913fc93ec9783414c3d)
+++ src/main/kotlin/update/ConfigurePluginUpdatesDialog.kt (revision c83e78f9365bc2a0a2844ca45bf752f4f07f9cc5)
@@ -22,8 +22,6 @@
import com.intellij.openapi.diagnostic.thisLogger
import com.intellij.openapi.ui.DialogWrapper
-import com.intellij.openapi.updateSettings.PluginUpdateInfo
-import com.intellij.openapi.updateSettings.impl.PluginDownloader
import com.intellij.openapi.updateSettings.impl.UpdateSettings
import com.intellij.ui.AnimatedIcon
import com.intellij.ui.dsl.builder.Cell
@@ -50,29 +48,24 @@
saveSettings()
updateCheckInProgressIcon.component.isVisible = true
resetUpdateStatus()
- PluginUpdater.runUpdateCheck { result ->
+ PluginUpdater.runUpdateCheck { pluginUpdateStatus ->
updateCheckInProgressIcon.component.isVisible = false
- updateStatusLabel.component.text = result.fold(
- { info ->
- when (info) {
- is PluginUpdateInfo.NoUpdate ->
+ updateStatusLabel.component.text = when (pluginUpdateStatus) {
+ is PluginUpdateStatus.LatestVersionInstalled ->
- "You have the latest version of the plugin (${PluginUtil.pluginVersion}) installed."
+ "You have the latest version of the plugin (${PluginUtil.pluginVersion}) installed."
- is PluginUpdateInfo.UpdateAvailable -> {
- update = info.update
+ is PluginUpdateStatus.Update -> {
+ update = pluginUpdateStatus
- installButton.component.isVisible = true
+ installButton.component.isVisible = true
- "A new version (${info.update.pluginVersion}) is available"
+ "A new version (${pluginUpdateStatus.pluginDescriptor.version}) is available"
- }
+ }
- is PluginUpdateInfo.CheckFailed ->
- "Update check failed: " + info.errors.entries.joinToString("; ") { (host, e) ->
- "${host ?: "Marketplace"}: ${e.message}"
+ else -> // CheckFailed
+ "Update check failed: " + (pluginUpdateStatus as PluginUpdateStatus.CheckFailed).message
- }
+ }
+
+ false
- }
+ }
- },
- { e -> "Update check failed: ${e.message}" },
- )
- }
+ }
- }
updateCheckInProgressIcon = icon(AnimatedIcon.Default.INSTANCE)
installButton = button("Install Update") {
update?.let { update ->
@@ -89,7 +82,7 @@
updateStatusLabel = label("")
}
}
- private var update: PluginDownloader? = null
+ private var update: PluginUpdateStatus.Update? = null
private var initialSelectedChannel: Int = 0
init {
Index: src/main/kotlin/update/PluginUpdateStatus.kt
===================================================================
--- src/main/kotlin/update/PluginUpdateStatus.kt (revision c83e78f9365bc2a0a2844ca45bf752f4f07f9cc5)
+++ src/main/kotlin/update/PluginUpdateStatus.kt (revision c83e78f9365bc2a0a2844ca45bf752f4f07f9cc5)
@@ -0,0 +1,49 @@
+/*
+ * 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.update
+
+import com.intellij.ide.plugins.IdeaPluginDescriptor
+import com.intellij.util.text.VersionComparatorUtil
+
+sealed class PluginUpdateStatus : Comparable {
+
+ protected abstract fun getVersionString(): String?
+
+ fun mergeWith(other: PluginUpdateStatus): PluginUpdateStatus = maxOf(this, other)
+
+ override fun compareTo(other: PluginUpdateStatus): Int {
+ val thisVersion = this.getVersionString() ?: return 1
+ val otherVersion = other.getVersionString() ?: return -1
+ return VersionComparatorUtil.compare(thisVersion, otherVersion)
+ }
+
+ object LatestVersionInstalled : PluginUpdateStatus() {
+ override fun getVersionString(): String = PluginUtil.pluginVersion
+ }
+
+ class Update(val pluginDescriptor: IdeaPluginDescriptor, val hostToInstallFrom: String?) : PluginUpdateStatus() {
+ override fun getVersionString(): String? = this.pluginDescriptor.version
+ }
+
+ class CheckFailed(val message: String) : PluginUpdateStatus() {
+ override fun getVersionString(): String? = null
+ }
+}
Index: src/main/kotlin/update/PluginUpdater.kt
===================================================================
--- src/main/kotlin/update/PluginUpdater.kt (revision ff47a747c3bb3a57e6d3c913fc93ec9783414c3d)
+++ src/main/kotlin/update/PluginUpdater.kt (revision c83e78f9365bc2a0a2844ca45bf752f4f07f9cc5)
@@ -21,27 +21,113 @@
package com.demonwav.mcdev.update
import com.demonwav.mcdev.util.McdevReflection
+import com.demonwav.mcdev.util.forEachNotNull
import com.demonwav.mcdev.util.invokeLater
+import com.intellij.ide.plugins.IdeaPluginDescriptor
+import com.intellij.ide.plugins.PluginManagerCore
import com.intellij.ide.plugins.PluginManagerMain
+import com.intellij.ide.plugins.PluginNode
+import com.intellij.ide.plugins.RepositoryHelper
+import com.intellij.openapi.application.ApplicationInfo
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.application.ModalityState
import com.intellij.openapi.progress.ProgressIndicator
import com.intellij.openapi.progress.ProgressManager
import com.intellij.openapi.progress.Task
-import com.intellij.openapi.updateSettings.PluginUpdateCheckService
-import com.intellij.openapi.updateSettings.PluginUpdateInfo
import com.intellij.openapi.updateSettings.impl.PluginDownloader
+import com.intellij.openapi.util.JDOMUtil
+import com.intellij.openapi.util.SystemInfo
+import com.intellij.util.io.HttpRequests
import java.io.IOException
+import java.net.URLEncoder
+import org.jdom.Element
+import org.jdom.JDOMException
object PluginUpdater {
- fun runUpdateCheck(callback: (Result) -> Unit) {
- ApplicationManager.getApplication().executeOnPooledThread {
- val result = runCatching { PluginUpdateCheckService.getInstance().getPluginUpdate(PluginUtil.PLUGIN_ID) }
- ApplicationManager.getApplication().invokeLater({ callback(result) }, ModalityState.any())
+ fun runUpdateCheck(callback: (PluginUpdateStatus) -> Boolean) {
+ ApplicationManager.getApplication().executeOnPooledThread { updateCheck(callback) }
- }
+ }
+
+ private fun updateCheck(callback: (PluginUpdateStatus) -> Boolean) {
+ var updateStatus: PluginUpdateStatus
+ try {
+ updateStatus = checkUpdatesInMainRepo()
+
+ RepositoryHelper.getPluginHosts()
+ .forEachNotNull { updateStatus = updateStatus.mergeWith(checkUpdatesInCustomRepo(it)) }
+
+ val finalUpdate = updateStatus
+ ApplicationManager.getApplication().invokeLater({ callback(finalUpdate) }, ModalityState.any())
+ } catch (_: Exception) {
+ PluginUpdateStatus.CheckFailed("Minecraft Development plugin update check failed")
- }
+ }
+ }
- fun installPluginUpdate(downloader: PluginDownloader) {
+ private fun checkUpdatesInMainRepo(): PluginUpdateStatus {
+ val buildNumber = ApplicationInfo.getInstance().build.asString()
+ val currentVersion = PluginUtil.pluginVersion
+ val os = URLEncoder.encode(SystemInfo.OS_NAME + " " + SystemInfo.OS_VERSION, Charsets.UTF_8)
+ val url =
+ "https://plugins.jetbrains.com/plugins/list?pluginId=8327&build=" +
+ "$buildNumber&pluginVersion=$currentVersion&os=$os"
+
+ val responseDoc = HttpRequests.request(url).connect { request ->
+ try {
+ return@connect JDOMUtil.load(request.inputStream)
+ } catch (e: JDOMException) {
+ e.printStackTrace()
+ }
+
+ null
+ } ?: return PluginUpdateStatus.CheckFailed("Unexpected plugin repository response")
+
+ if (responseDoc.name != "plugin-repository") {
+ return PluginUpdateStatus.CheckFailed("Unexpected plugin repository response")
+ }
+ if (responseDoc.children.isEmpty()) {
+ return PluginUpdateStatus.LatestVersionInstalled
+ }
+
+ val newVersion = responseDoc.getChild("category")?.getChild("idea-plugin")?.getChild("version")?.text
+ ?: return PluginUpdateStatus.CheckFailed("Couldn't find plugin version in repository response")
+
+ val plugin = PluginManagerCore.getPlugin(PluginUtil.PLUGIN_ID)!!
+ val pluginNode = PluginNode(PluginUtil.PLUGIN_ID)
+ pluginNode.version = newVersion
+ pluginNode.name = plugin.name
+ pluginNode.description = plugin.description
+
+ if (pluginNode.version == PluginUtil.pluginVersion) {
+ return PluginUpdateStatus.LatestVersionInstalled
+ }
+
+ return PluginUpdateStatus.Update(pluginNode, null)
+ }
+
+ private fun checkUpdatesInCustomRepo(host: String): PluginUpdateStatus {
+ val plugins = try {
+ RepositoryHelper.loadPluginModels(host, null, null)
+ .map { it.getDescriptor() }
+ } catch (_: IOException) {
+ return PluginUpdateStatus.CheckFailed("Checking custom plugin repository $host failed")
+ }
+
+ val minecraftPlugin = plugins.firstOrNull { plugin -> plugin.pluginId == PluginUtil.PLUGIN_ID }
+ ?: return PluginUpdateStatus.LatestVersionInstalled
+
+ return updateIfNotLatest(minecraftPlugin, host)
+ }
+
+ private fun updateIfNotLatest(plugin: IdeaPluginDescriptor, host: String): PluginUpdateStatus {
+ if (plugin.version == PluginUtil.pluginVersion) {
+ return PluginUpdateStatus.LatestVersionInstalled
+ }
+ return PluginUpdateStatus.Update(plugin, host)
+ }
+
+ fun installPluginUpdate(update: PluginUpdateStatus.Update) {
+ val plugin = update.pluginDescriptor
+ val downloader = PluginDownloader.createDownloader(plugin, update.hostToInstallFrom, null)
ProgressManager.getInstance().run(
object : Task.Backgroundable(null, "Downloading plugin", true) {
override fun run(indicator: ProgressIndicator) {