mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[platform] skipping irrelevant IDE update data
GitOrigin-RevId: 91c4baaeb3a1b12bd854579e748d1f21a861d64e
This commit is contained in:
committed by
intellij-monorepo-bot
parent
1e8e201eb6
commit
d7be3e5675
+12
-15
@@ -208,11 +208,10 @@ object UpdateChecker {
|
||||
|
||||
@JvmStatic
|
||||
@Throws(IOException::class, JDOMException::class)
|
||||
fun loadProductData(indicator: ProgressIndicator?): Product? {
|
||||
fun loadProductData(indicator: ProgressIndicator?): Product? =
|
||||
productDataLock.withLock {
|
||||
SoftReference.dereference(productDataCache)?.let {
|
||||
return it.getOrThrow()
|
||||
}
|
||||
val cached = SoftReference.dereference(productDataCache)
|
||||
if (cached != null) return@withLock cached.getOrThrow()
|
||||
|
||||
val result = runCatching {
|
||||
var url = Urls.newFromEncoded(updateUrl)
|
||||
@@ -220,15 +219,13 @@ object UpdateChecker {
|
||||
url = UpdateRequestParameters.amendUpdateRequest(url)
|
||||
}
|
||||
LOG.debug { "loading ${url}" }
|
||||
val updates = HttpRequests.request(url).connect { UpdatesInfo(JDOMUtil.load(it.getReader(indicator))) }
|
||||
updates.get(ApplicationInfo.getInstance().build.productCode)
|
||||
parseUpdateData(HttpRequests.request(url).connect { JDOMUtil.load(it.getReader(indicator)) })
|
||||
}
|
||||
|
||||
productDataCache = SoftReference(result)
|
||||
AppExecutorUtil.getAppScheduledExecutorService().schedule(this::clearProductDataCache, PRODUCT_DATA_TTL_MS, TimeUnit.MILLISECONDS)
|
||||
return result.getOrThrow()
|
||||
return@withLock result.getOrThrow()
|
||||
}
|
||||
}
|
||||
|
||||
private fun clearProductDataCache() {
|
||||
if (productDataLock.tryLock(1, TimeUnit.MILLISECONDS)) { // longer means loading now, no much sense in clearing
|
||||
@@ -666,8 +663,7 @@ object UpdateChecker {
|
||||
if (!ourHasFailedPlugins) {
|
||||
val app = ApplicationManager.getApplication()
|
||||
if (app != null && !app.isDisposed && UpdateSettings.getInstance().isPluginsCheckNeeded) {
|
||||
val pluginDescriptor = PluginManagerCore.getPlugin(
|
||||
PluginUtil.getInstance().findPluginId(event.throwable))
|
||||
val pluginDescriptor = PluginManagerCore.getPlugin(PluginUtil.getInstance().findPluginId(event.throwable))
|
||||
if (pluginDescriptor != null && !pluginDescriptor.isBundled) {
|
||||
ourHasFailedPlugins = true
|
||||
updateAndShowResult()
|
||||
@@ -678,7 +674,7 @@ object UpdateChecker {
|
||||
|
||||
/** A helper method for manually testing platform updates (see [com.intellij.internal.ShowUpdateInfoDialogAction]). */
|
||||
@ApiStatus.Internal
|
||||
fun testPlatformUpdate(project: Project?, updateInfoText: String, patchFilePath: String?, forceUpdate: Boolean) {
|
||||
fun testPlatformUpdate(project: Project?, updateDataText: String, patchFilePath: String?, forceUpdate: Boolean) {
|
||||
if (!ApplicationManager.getApplication().isInternal) {
|
||||
throw IllegalStateException()
|
||||
}
|
||||
@@ -686,15 +682,16 @@ object UpdateChecker {
|
||||
val channel: UpdateChannel?
|
||||
val newBuild: BuildInfo?
|
||||
val patches: UpdateChain?
|
||||
val currentBuild = ApplicationInfo.getInstance().build
|
||||
if (forceUpdate) {
|
||||
val node = JDOMUtil.load(updateInfoText).getChild("product")?.getChild("channel") ?: throw IllegalArgumentException("//channel missing")
|
||||
channel = UpdateChannel(node)
|
||||
val node = JDOMUtil.load(updateDataText).getChild("product")?.getChild("channel") ?: throw IllegalArgumentException("//channel missing")
|
||||
channel = UpdateChannel(node, currentBuild.productCode)
|
||||
newBuild = channel.builds.firstOrNull() ?: throw IllegalArgumentException("//build missing")
|
||||
patches = newBuild.patches.firstOrNull()?.let { UpdateChain(listOf(it.fromBuild, newBuild.number), it.size) }
|
||||
}
|
||||
else {
|
||||
val updateInfo = UpdatesInfo(JDOMUtil.load(updateInfoText))
|
||||
val strategy = UpdateStrategy(ApplicationInfo.getInstance().build, updateInfo, UpdateSettings.getInstance())
|
||||
val product = parseUpdateData(JDOMUtil.load(updateDataText), currentBuild.productCode)
|
||||
val strategy = UpdateStrategy(currentBuild, product, UpdateSettings.getInstance())
|
||||
val checkForUpdateResult = strategy.checkForUpdates()
|
||||
channel = checkForUpdateResult.updatedChannel
|
||||
newBuild = checkForUpdateResult.newBuild
|
||||
|
||||
@@ -1,32 +1,33 @@
|
||||
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
// Copyright 2000-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
@file:JvmName("UpdateData")
|
||||
package com.intellij.openapi.updateSettings.impl
|
||||
|
||||
import com.intellij.openapi.application.impl.ApplicationInfoImpl
|
||||
import com.intellij.openapi.diagnostic.Logger
|
||||
import com.intellij.openapi.application.ApplicationInfo
|
||||
import com.intellij.openapi.diagnostic.logger
|
||||
import com.intellij.openapi.util.BuildNumber
|
||||
import com.intellij.openapi.util.BuildRange
|
||||
import com.intellij.openapi.util.NlsSafe
|
||||
import com.intellij.openapi.util.SystemInfo
|
||||
import org.jdom.Element
|
||||
import org.jdom.JDOMException
|
||||
import org.jetbrains.annotations.ApiStatus
|
||||
import java.text.ParseException
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.*
|
||||
|
||||
class UpdatesInfo(node: Element) {
|
||||
private val products = node.getChildren("product").map(::Product)
|
||||
operator fun get(code: String): Product? = products.find { code in it.codes }
|
||||
}
|
||||
fun parseUpdateData(node: Element, productCode: String = ApplicationInfo.getInstance().build.productCode): Product? =
|
||||
node.getChildren("product")
|
||||
.find { it.getChildren("code").any { code -> code.value.trim() == productCode } }
|
||||
?.let { Product(it, productCode) }
|
||||
|
||||
class Product internal constructor(node: Element) {
|
||||
class Product internal constructor(node: Element, private val productCode: String) {
|
||||
@NlsSafe val name: String = node.getMandatoryAttributeValue("name")
|
||||
val codes: Set<String> = node.getChildren("code").map { it.value.trim() }.toSet()
|
||||
val channels: List<UpdateChannel> = node.getChildren("channel").map(::UpdateChannel)
|
||||
val channels: List<UpdateChannel> = node.getChildren("channel").map { UpdateChannel(it, productCode) }
|
||||
|
||||
override fun toString(): String = codes.firstOrNull() ?: "-"
|
||||
override fun toString(): String = productCode
|
||||
}
|
||||
|
||||
class UpdateChannel internal constructor(node: Element) {
|
||||
class UpdateChannel internal constructor(node: Element, productCode: String) {
|
||||
enum class Licensing { EAP, RELEASE; }
|
||||
|
||||
val id: String = node.getMandatoryAttributeValue("id")
|
||||
@@ -34,13 +35,13 @@ class UpdateChannel internal constructor(node: Element) {
|
||||
val licensing: Licensing = if (node.getAttributeValue("licensing") == "eap") Licensing.EAP else Licensing.RELEASE
|
||||
val evalDays: Int = node.getAttributeValue("evalDays")?.toInt() ?: 30
|
||||
val url: String? = node.getAttributeValue("url")
|
||||
val builds: List<BuildInfo> = node.getChildren("build").map(::BuildInfo)
|
||||
val builds: List<BuildInfo> = node.getChildren("build").map { BuildInfo(it, productCode) }
|
||||
|
||||
override fun toString(): String = id
|
||||
}
|
||||
|
||||
class BuildInfo internal constructor(node: Element) {
|
||||
val number: BuildNumber = parseBuildNumber(node.getMandatoryAttributeValue("fullNumber", "number"))
|
||||
class BuildInfo internal constructor(node: Element, productCode: String) {
|
||||
val number: BuildNumber = parseBuildNumber(node.getMandatoryAttributeValue("fullNumber", "number"), productCode)
|
||||
val apiVersion: BuildNumber = node.getAttributeValue("apiVersion")?.let { BuildNumber.fromStringWithProductCode(it, number.productCode) } ?: number
|
||||
val version: String = node.getAttributeValue("version") ?: ""
|
||||
@NlsSafe val message: String = node.getChild("message")?.value ?: ""
|
||||
@@ -48,15 +49,11 @@ class BuildInfo internal constructor(node: Element) {
|
||||
val releaseDate: Date? = parseDate(node.getAttributeValue("releaseDate"))
|
||||
val target: BuildRange? = BuildRange.fromStrings(node.getAttributeValue("targetSince"), node.getAttributeValue("targetUntil"))
|
||||
val patches: List<PatchInfo> = node.getChildren("patch").map(::PatchInfo)
|
||||
val downloadUrl: String? = node.getChildren("button").find { it.getAttributeValue("download") != null }?.getMandatoryAttributeValue("url")
|
||||
|
||||
private val buttons: List<ButtonInfo> = node.getChildren("button").map(::ButtonInfo)
|
||||
|
||||
private fun parseBuildNumber(value: String): BuildNumber {
|
||||
var buildNumber = BuildNumber.fromString(value)!!
|
||||
if (buildNumber.productCode.isEmpty()) {
|
||||
buildNumber = BuildNumber(ApplicationInfoImpl.getShadowInstance().build.productCode, *buildNumber.components)
|
||||
}
|
||||
return buildNumber
|
||||
private fun parseBuildNumber(value: String, productCode: String): BuildNumber {
|
||||
val buildNumber = BuildNumber.fromString(value)!!
|
||||
return if (buildNumber.productCode.isNotEmpty()) buildNumber else BuildNumber(productCode, *buildNumber.components)
|
||||
}
|
||||
|
||||
private fun parseDate(value: String?): Date? =
|
||||
@@ -65,20 +62,11 @@ class BuildInfo internal constructor(node: Element) {
|
||||
SimpleDateFormat("yyyyMMdd", Locale.US).parse(value) // same as the 'majorReleaseDate' in ApplicationInfo.xml
|
||||
}
|
||||
catch (e: ParseException) {
|
||||
Logger.getInstance(BuildInfo::class.java).info("invalid build release date: $value")
|
||||
logger<BuildInfo>().info("invalid build release date: ${value}")
|
||||
null
|
||||
}
|
||||
|
||||
val downloadUrl: String?
|
||||
get() = buttons.find(ButtonInfo::isDownload)?.url
|
||||
|
||||
override fun toString(): String = "${number}/${version}"
|
||||
|
||||
private class ButtonInfo constructor(node: Element) {
|
||||
// "name" is no longer used
|
||||
val url: String = node.getMandatoryAttributeValue("url")
|
||||
val isDownload: Boolean = node.getAttributeValue("download") != null
|
||||
}
|
||||
}
|
||||
|
||||
class PatchInfo internal constructor(node: Element) {
|
||||
@@ -96,3 +84,11 @@ private fun Element.getMandatoryAttributeValue(attribute: String) =
|
||||
|
||||
private fun Element.getMandatoryAttributeValue(attribute: String, fallback: String) =
|
||||
getAttributeValue(attribute) ?: getMandatoryAttributeValue(fallback)
|
||||
|
||||
//<editor-fold desc="Deprecated stuff.">
|
||||
@Deprecated("Please use `parseUpdateData` instead")
|
||||
@ApiStatus.ScheduledForRemoval(inVersion = "2022.2")
|
||||
class UpdatesInfo(node: Element) {
|
||||
val product: Product? = parseUpdateData(node)
|
||||
}
|
||||
//</editor-fold>
|
||||
|
||||
+6
-2
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
// Copyright 2000-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.openapi.updateSettings.impl
|
||||
|
||||
import com.intellij.openapi.updateSettings.UpdateStrategyCustomization
|
||||
@@ -6,13 +6,17 @@ import com.intellij.openapi.util.BuildNumber
|
||||
import com.intellij.util.containers.MultiMap
|
||||
import com.intellij.util.graph.GraphAlgorithms
|
||||
import com.intellij.util.graph.InboundSemiGraph
|
||||
import org.jetbrains.annotations.ApiStatus
|
||||
import java.util.*
|
||||
|
||||
private val NUMBER = Regex("\\d+")
|
||||
|
||||
class UpdateStrategy(private val currentBuild: BuildNumber, private val product: Product?, private val settings: UpdateSettings) {
|
||||
@Deprecated("Please use `UpdateStrategy(BuildNumber, Product, UpdateSettings)` instead")
|
||||
@ApiStatus.ScheduledForRemoval(inVersion = "2022.2")
|
||||
@Suppress("DEPRECATION")
|
||||
constructor(currentBuild: BuildNumber, updates: UpdatesInfo, settings: UpdateSettings) :
|
||||
this(currentBuild, updates[currentBuild.productCode], settings)
|
||||
this(currentBuild, updates.product, settings)
|
||||
|
||||
private val customization = UpdateStrategyCustomization.getInstance()
|
||||
|
||||
|
||||
@@ -1,11 +1,8 @@
|
||||
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
// Copyright 2000-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.ide.updates
|
||||
|
||||
import com.intellij.openapi.updateSettings.impl.ChannelStatus
|
||||
import com.intellij.openapi.updateSettings.impl.UpdateChannel
|
||||
import com.intellij.openapi.updateSettings.impl.UpdatesInfo
|
||||
import com.intellij.openapi.updateSettings.impl.*
|
||||
import com.intellij.openapi.util.JDOMUtil
|
||||
import com.intellij.testFramework.fixtures.BareTestFixtureTestCase
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Assert.assertNotNull
|
||||
import org.junit.Assume.assumeTrue
|
||||
@@ -14,11 +11,10 @@ import java.io.IOException
|
||||
import java.net.URL
|
||||
import java.text.SimpleDateFormat
|
||||
|
||||
class UpdateInfoParsingTest : BareTestFixtureTestCase() {
|
||||
class UpdateInfoParsingTest {
|
||||
@Test fun liveJetBrainsUpdateFile() {
|
||||
try {
|
||||
val info = load(URL("https://www.jetbrains.com/updates/updates.xml").readText())
|
||||
assertNotNull(info["IC"])
|
||||
assertNotNull(load(URL("https://www.jetbrains.com/updates/updates.xml").readText(), "IC"))
|
||||
}
|
||||
catch (e: IOException) {
|
||||
assumeTrue(e.toString(), false)
|
||||
@@ -27,8 +23,7 @@ class UpdateInfoParsingTest : BareTestFixtureTestCase() {
|
||||
|
||||
@Test fun liveAndroidUpdateFile() {
|
||||
try {
|
||||
val info = load(URL("https://dl.google.com/android/studio/patches/updates.xml").readText())
|
||||
assertNotNull(info["AI"])
|
||||
assertNotNull(load(URL("https://dl.google.com/android/studio/patches/updates.xml").readText(), "AI"))
|
||||
}
|
||||
catch (e: IOException) {
|
||||
assumeTrue(e.toString(), false)
|
||||
@@ -36,21 +31,23 @@ class UpdateInfoParsingTest : BareTestFixtureTestCase() {
|
||||
}
|
||||
|
||||
@Test fun emptyChannels() {
|
||||
val info = load("""
|
||||
val updates = """
|
||||
<products>
|
||||
<product name="IntelliJ IDEA">
|
||||
<code>IU</code>
|
||||
<code>IC</code>
|
||||
</product>
|
||||
</products>""".trimIndent())
|
||||
val product = info["IU"]!!
|
||||
assertEquals("IntelliJ IDEA", product.name)
|
||||
assertEquals(0, product.channels.size)
|
||||
assertEquals(product, info["IC"])
|
||||
</products>""".trimIndent()
|
||||
val ultimate = load(updates, "IU")!!
|
||||
assertEquals("IntelliJ IDEA", ultimate.name)
|
||||
assertEquals(0, ultimate.channels.size)
|
||||
val community = load(updates, "IC")!!
|
||||
assertEquals("IntelliJ IDEA", community.name)
|
||||
assertEquals(0, community.channels.size)
|
||||
}
|
||||
|
||||
@Test fun oneProductOnly() {
|
||||
val info = load("""
|
||||
val product = load("""
|
||||
<products>
|
||||
<product name="IntelliJ IDEA">
|
||||
<code>IU</code>
|
||||
@@ -69,9 +66,8 @@ class UpdateInfoParsingTest : BareTestFixtureTestCase() {
|
||||
</build>
|
||||
</channel>
|
||||
</product>
|
||||
</products>""".trimIndent())
|
||||
</products>""".trimIndent(), "IU")!!
|
||||
|
||||
val product = info["IU"]!!
|
||||
assertEquals("IntelliJ IDEA", product.name)
|
||||
assertEquals(2, product.channels.size)
|
||||
|
||||
@@ -90,7 +86,7 @@ class UpdateInfoParsingTest : BareTestFixtureTestCase() {
|
||||
}
|
||||
|
||||
@Test fun targetRanges() {
|
||||
val info = load("""
|
||||
val product = load("""
|
||||
<products>
|
||||
<product name="IntelliJ IDEA">
|
||||
<code>IU</code>
|
||||
@@ -100,12 +96,12 @@ class UpdateInfoParsingTest : BareTestFixtureTestCase() {
|
||||
<build number="2016.1.11" version="2016.1"/>
|
||||
</channel>
|
||||
</product>
|
||||
</products>""".trimIndent())
|
||||
assertEquals(2, info["IU"]!!.channels[0].builds.count { it.target != null })
|
||||
</products>""".trimIndent(), "IU")
|
||||
assertEquals(2, product!!.channels[0].builds.count { it.target != null })
|
||||
}
|
||||
|
||||
@Test fun fullBuildNumbers() {
|
||||
val info = load("""
|
||||
val buildInfo = load("""
|
||||
<products>
|
||||
<product name="IntelliJ IDEA">
|
||||
<code>IU</code>
|
||||
@@ -115,11 +111,10 @@ class UpdateInfoParsingTest : BareTestFixtureTestCase() {
|
||||
</build>
|
||||
</channel>
|
||||
</product>
|
||||
</products>""".trimIndent())
|
||||
val buildInfo = info["IU"]!!.channels[0].builds[0]
|
||||
</products>""".trimIndent(), "IU")!!.channels[0].builds[0]
|
||||
assertEquals("162.100.1", buildInfo.number.asStringWithoutProductCode())
|
||||
assertEquals("162.99.2", buildInfo.patches[0].fromBuild.asStringWithoutProductCode())
|
||||
}
|
||||
|
||||
private fun load(text: String) = UpdatesInfo(JDOMUtil.load(text))
|
||||
private fun load(text: String, productCode: String): Product? = parseUpdateData(JDOMUtil.load(text), productCode)
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
// Copyright 2000-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.ide.updates
|
||||
|
||||
import com.intellij.openapi.updateSettings.impl.*
|
||||
@@ -272,28 +272,25 @@ class UpdateStrategyTest : BareTestFixtureTestCase() {
|
||||
assertThat(result.patches?.chain).isEqualTo(listOf("183.3795.13", "183.3975.18", "183.4139.22").map(BuildNumber::fromString))
|
||||
}
|
||||
|
||||
//<editor-fold desc="Helpers.">
|
||||
private fun check(currentBuild: String,
|
||||
selectedChannel: ChannelStatus,
|
||||
testData: String,
|
||||
ignoredBuilds: List<String> = emptyList()): CheckForUpdateResult {
|
||||
val updates = UpdatesInfo(JDOMUtil.load("""
|
||||
val product = parseUpdateData(JDOMUtil.load("""
|
||||
<products>
|
||||
<product name="IntelliJ IDEA">
|
||||
<code>IU</code>
|
||||
$testData
|
||||
${testData}
|
||||
</product>
|
||||
</products>"""))
|
||||
</products>"""), "IU")
|
||||
val settings = UpdateSettings()
|
||||
settings.selectedChannelStatus = selectedChannel
|
||||
settings.ignoredBuildNumbers += ignoredBuilds
|
||||
val result = UpdateStrategy(BuildNumber.fromString(currentBuild)!!, updates, settings).checkForUpdates()
|
||||
val result = UpdateStrategy(BuildNumber.fromString(currentBuild)!!, product, settings).checkForUpdates()
|
||||
assertEquals(UpdateStrategy.State.LOADED, result.state)
|
||||
return result
|
||||
}
|
||||
|
||||
private fun assertBuild(expected: String, build: BuildInfo?) {
|
||||
private fun assertBuild(expected: String, build: BuildInfo?) =
|
||||
assertEquals(expected, build?.number?.asStringWithoutProductCode())
|
||||
}
|
||||
//</editor-fold>
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user