[plugins] IJPL-211177 Send os/arch to MarketplaceUrls in POST body

(cherry picked from commit 56aedd52984dfcba466a9db410419e20457b3d02)

IJ-CR-178347

GitOrigin-RevId: bf588f74955dad22575f9ef322c08617534a373e
This commit is contained in:
Yuriy Artamonov
2025-10-15 13:54:36 +02:00
committed by intellij-monorepo-bot
parent 9e4fff44bd
commit 40be294994
13 changed files with 72 additions and 101 deletions

View File

@@ -36,23 +36,6 @@
com.intellij.ide.plugins.DynamicPluginListener
- *:beforePluginsLoaded():V
- *:pluginsLoaded():V
*e:com.intellij.ide.plugins.IdeaPluginCpuArchRequirement
- java.lang.Enum
- sf:ARM32:com.intellij.ide.plugins.IdeaPluginCpuArchRequirement
- sf:ARM64:com.intellij.ide.plugins.IdeaPluginCpuArchRequirement
- *sf:Companion:com.intellij.ide.plugins.IdeaPluginCpuArchRequirement$Companion
- sf:Unknown:com.intellij.ide.plugins.IdeaPluginCpuArchRequirement
- sf:X86:com.intellij.ide.plugins.IdeaPluginCpuArchRequirement
- sf:X86_64:com.intellij.ide.plugins.IdeaPluginCpuArchRequirement
- b:<init>(java.lang.String,I,kotlin.jvm.internal.DefaultConstructorMarker):V
- s:getEntries():kotlin.enums.EnumEntries
- f:getModuleId():com.intellij.openapi.extensions.PluginId
- a:isHostOs():Z
- s:valueOf(java.lang.String):com.intellij.ide.plugins.IdeaPluginCpuArchRequirement
- s:values():com.intellij.ide.plugins.IdeaPluginCpuArchRequirement[]
*f:com.intellij.ide.plugins.IdeaPluginCpuArchRequirement$Companion
- f:fromModuleId(com.intellij.openapi.extensions.PluginId):com.intellij.ide.plugins.IdeaPluginCpuArchRequirement
- f:getHostCpuArchModuleIds():java.util.List
*e:com.intellij.ide.plugins.IdeaPluginOsRequirement
- java.lang.Enum
- *sf:Companion:com.intellij.ide.plugins.IdeaPluginOsRequirement$Companion

View File

@@ -1,49 +0,0 @@
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.ide.plugins
import com.intellij.openapi.extensions.PluginId
import com.intellij.util.containers.Java11Shim
import com.intellij.util.system.CpuArch
import org.jetbrains.annotations.ApiStatus
private const val archModuleIdPrefix = "com.intellij.modules.arch."
@ApiStatus.Experimental
enum class IdeaPluginCpuArchRequirement {
X86 {
override fun isHostOs(): Boolean = CpuArch.CURRENT == CpuArch.X86
},
X86_64 {
override fun isHostOs(): Boolean = CpuArch.CURRENT == CpuArch.X86_64
},
ARM32 {
override fun isHostOs(): Boolean = CpuArch.CURRENT == CpuArch.ARM32
},
ARM64 {
override fun isHostOs(): Boolean = CpuArch.CURRENT == CpuArch.ARM64
},
Unknown {
override fun isHostOs(): Boolean = false
};
val moduleId: PluginId = PluginId.getId(archModuleIdPrefix + name.lowercase())
abstract fun isHostOs(): Boolean
companion object {
private val directory = HashMap<PluginId, IdeaPluginCpuArchRequirement>().let { map ->
entries.associateByTo(map) { it.moduleId }
Java11Shim.INSTANCE.copyOf(map)
}
fun getHostCpuArchModuleIds(): List<PluginId> {
return entries.mapNotNull { it.takeIf { it.isHostOs() }?.moduleId }
}
fun fromModuleId(moduleId: PluginId): IdeaPluginCpuArchRequirement? {
return directory[moduleId] ?: Unknown.takeIf { looksLikeCpuArchModuleId(moduleId.idString) }
}
private fun looksLikeCpuArchModuleId(idString: String): Boolean = idString.startsWith(archModuleIdPrefix)
}
}

View File

@@ -0,0 +1,49 @@
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.ide.plugins
import com.intellij.openapi.extensions.PluginId
import com.intellij.util.containers.Java11Shim
import com.intellij.util.system.CpuArch
import org.jetbrains.annotations.ApiStatus
private const val archPluginAliasIdPrefix = "com.intellij.modules.arch."
@ApiStatus.Internal
enum class PluginCpuArchRequirement {
X86 {
override fun isHostArch(): Boolean = CpuArch.CURRENT == CpuArch.X86
},
X86_64 {
override fun isHostArch(): Boolean = CpuArch.CURRENT == CpuArch.X86_64
},
ARM32 {
override fun isHostArch(): Boolean = CpuArch.CURRENT == CpuArch.ARM32
},
ARM64 {
override fun isHostArch(): Boolean = CpuArch.CURRENT == CpuArch.ARM64
},
Unknown {
override fun isHostArch(): Boolean = false
};
val pluginAliasId: PluginId = PluginId.getId(archPluginAliasIdPrefix + name.lowercase())
abstract fun isHostArch(): Boolean
companion object {
private val directory = HashMap<PluginId, PluginCpuArchRequirement>().let { map ->
entries.associateByTo(map) { it.pluginAliasId }
Java11Shim.INSTANCE.copyOf(map)
}
fun getHostCpuArchModuleIds(): List<PluginId> {
return entries.mapNotNull { it.takeIf { it.isHostArch() }?.pluginAliasId }
}
fun fromPluginId(pluginId: PluginId): PluginCpuArchRequirement? {
return directory[pluginId] ?: Unknown.takeIf { looksLikeCpuArchModuleId(pluginId.idString) }
}
private fun looksLikeCpuArchModuleId(idString: String): Boolean = idString.startsWith(archPluginAliasIdPrefix)
}
}

View File

@@ -433,7 +433,7 @@ class PluginMainDescriptor(
}
return pluginAliases +
IdeaPluginOsRequirement.getHostOsModuleIds() +
IdeaPluginCpuArchRequirement.getHostCpuArchModuleIds() +
PluginCpuArchRequirement.getHostCpuArchModuleIds() +
productModeAliasesForCorePlugin()
}

View File

@@ -457,10 +457,10 @@ object PluginManagerCore {
}
@ApiStatus.Internal
fun getUnfulfilledCpuArchRequirement(descriptor: IdeaPluginDescriptor): IdeaPluginCpuArchRequirement? {
fun getUnfulfilledCpuArchRequirement(descriptor: IdeaPluginDescriptor): PluginCpuArchRequirement? {
return descriptor.getDependencies().asSequence()
.mapNotNull { dep -> IdeaPluginCpuArchRequirement.fromModuleId(dep.pluginId).takeIf { !dep.isOptional } }
.firstOrNull { osReq -> !osReq.isHostOs() }
.mapNotNull { dep -> PluginCpuArchRequirement.fromPluginId(dep.pluginId).takeIf { !dep.isOptional } }
.firstOrNull { osReq -> !osReq.isHostArch() }
}
@JvmStatic

View File

@@ -119,7 +119,7 @@ class PluginIsIncompatibleWithHostPlatform(
@ApiStatus.Internal
class PluginIsIncompatibleWithHostCpu(
override val plugin: IdeaPluginDescriptor,
val requiredCpuArch: IdeaPluginCpuArchRequirement,
val requiredCpuArch: PluginCpuArchRequirement,
val hostCpu: @NlsSafe CpuArch,
): PluginNonLoadReason {
override val detailedMessage: @NlsContexts.DetailedDescription String

View File

@@ -24,7 +24,7 @@ class PluginDto(
override var version: String? = null
override var isBundled: Boolean = false
override var isDeleted: Boolean = false
override var isIncompatibleWithCurrentOs: Boolean = false
override var isIncompatibleWithCurrentPlatform: Boolean = false
override var isIncompatible: Boolean = false
override var canBeEnabled: Boolean = true
override var requiresUpgrade: Boolean = false
@@ -115,7 +115,7 @@ class PluginDto(
version = model.version
isBundled = model.isBundled
isDeleted = model.isDeleted
isIncompatibleWithCurrentOs = model.isIncompatibleWithCurrentOs
isIncompatibleWithCurrentPlatform = model.isIncompatibleWithCurrentPlatform
isIncompatible = model.isIncompatible
canBeEnabled = model.canBeEnabled
requiresUpgrade = model.requiresUpgrade

View File

@@ -9,7 +9,6 @@ import com.intellij.ide.plugins.PluginInfoProvider
import com.intellij.ide.plugins.PluginNode
import com.intellij.ide.plugins.auth.PluginRepositoryAuthService
import com.intellij.ide.plugins.marketplace.utils.MarketplaceUrls
import com.intellij.ide.plugins.marketplace.utils.buildEncodedArchParameter
import com.intellij.ide.plugins.marketplace.utils.buildEncodedOsParameter
import com.intellij.ide.plugins.newui.PluginUiModel
import com.intellij.ide.plugins.newui.PluginUiModelAdapter
@@ -40,6 +39,8 @@ import com.intellij.util.io.HttpRequests
import com.intellij.util.io.RequestBuilder
import com.intellij.util.io.computeDetached
import com.intellij.util.io.write
import com.intellij.util.system.CpuArch
import com.intellij.util.system.OS
import com.intellij.util.ui.IoErrorText
import com.intellij.util.withQuery
import kotlinx.coroutines.CoroutineScope
@@ -154,7 +155,7 @@ class MarketplaceRequests(private val coroutineScope: CoroutineScope) : PluginIn
allIds: Set<PluginId>,
buildNumber: BuildNumber? = null,
throwExceptions: Boolean = false,
updateCheck: Boolean = false
updateCheck: Boolean = false,
): List<IdeCompatibleUpdate> {
val chunks = mutableListOf<MutableList<PluginId>>()
chunks.add(ArrayList(100))
@@ -217,12 +218,12 @@ class MarketplaceRequests(private val coroutineScope: CoroutineScope) : PluginIn
val machineId = if (LoadingState.COMPONENTS_LOADED.isOccurred) {
MachineIdManager.getAnonymizedMachineId("JetBrainsUpdates") // same as regular updates
.takeIf { !PropertiesComponent.getInstance().getBoolean(UpdateCheckerFacade.MACHINE_ID_DISABLED_PROPERTY, false) }
} else null
}
else null
val query = buildString {
append("build=${ApplicationInfoImpl.orFromPluginCompatibleBuild(buildNumber)}")
append("&os=${buildEncodedOsParameter()}")
append("&arch=${buildEncodedArchParameter()}")
if (machineId != null && updateCheck) {
append("&mid=$machineId")
}
@@ -267,14 +268,7 @@ class MarketplaceRequests(private val coroutineScope: CoroutineScope) : PluginIn
if (ids.isEmpty()) return emptyList()
val data = objectMapper.writeValueAsString(CompatibleUpdateRequest(ids, buildNumber))
val baseUrl = URI(MarketplaceUrls.getSearchNearestUpdate())
val query = buildString {
append("os=${buildEncodedOsParameter()}")
append("&arch=${buildEncodedArchParameter()}")
}
val url = baseUrl.withQuery(query).toString()
return HttpRequests.post(url, HttpRequests.JSON_CONTENT_TYPE).run {
return HttpRequests.post(MarketplaceUrls.getSearchNearestUpdate(), HttpRequests.JSON_CONTENT_TYPE).run {
productNameAsUserAgent()
throwStatusCodeException(throwExceptions)
connect {
@@ -752,14 +746,7 @@ class MarketplaceRequests(private val coroutineScope: CoroutineScope) : PluginIn
val data = objectMapper.writeValueAsString(CompatibleUpdateForModuleRequest(module))
@Suppress("DEPRECATION")
val baseUrl = URI(MarketplaceUrls.getSearchCompatibleUpdatesUrl())
val query = buildString {
append("os=${buildEncodedOsParameter()}")
append("&arch=${buildEncodedArchParameter()}")
}
val url = baseUrl.withQuery(query).toString()
return HttpRequests.post(url, HttpRequests.JSON_CONTENT_TYPE)
return HttpRequests.post(MarketplaceUrls.getSearchCompatibleUpdatesUrl(), HttpRequests.JSON_CONTENT_TYPE)
.productNameAsUserAgent()
.throwStatusCodeException(false)
.connect {
@@ -963,6 +950,8 @@ private fun isNotModified(urlConnection: URLConnection, file: Path?): Boolean {
private data class CompatibleUpdateRequest(
val build: String,
val pluginXMLIds: List<String>,
val os: String = OS.CURRENT.name,
val arch: String = CpuArch.CURRENT.name,
) {
@JvmOverloads
@@ -978,6 +967,8 @@ private data class CompatibleUpdateRequest(
private data class CompatibleUpdateForModuleRequest(
val module: String,
val build: String,
val os: String = OS.CURRENT.name,
val arch: String = CpuArch.CURRENT.name,
) {
@JvmOverloads

View File

@@ -117,7 +117,7 @@ public final class ListPluginComponent extends JPanel {
myCoroutineScope = coroutineScope;
myInstalledDescriptorForMarketplace = listModel.getInstalledModels().get(pluginUiModel.getPluginId());
PluginId pluginId = myPlugin.getPluginId();
boolean compatible = !myPlugin.isIncompatibleWithCurrentOs();
boolean compatible = !myPlugin.isIncompatibleWithCurrentPlatform();
PluginInstallationState pluginInstallationState = listModel.getPluginInstallationStates().get(pluginId);
myIsAvailable = (compatible || isInstalledAndEnabled(pluginInstallationState)) && pluginUiModel.getCanBeEnabled();
UiPluginManager pluginManager = UiPluginManager.getInstance();

View File

@@ -872,7 +872,7 @@ class PluginDetailsPageComponent @JvmOverloads constructor(
suspend fun showPluginImpl(pluginUiModel: PluginUiModel, updateDescriptor: PluginUiModel?) {
plugin = pluginUiModel
this.updateDescriptor = if (updateDescriptor != null && updateDescriptor.canBeEnabled) updateDescriptor else null
isPluginCompatible = !pluginUiModel.isIncompatibleWithCurrentOs
isPluginCompatible = !pluginUiModel.isIncompatibleWithCurrentPlatform
isPluginAvailable = isPluginCompatible && updateDescriptor?.canBeEnabled ?: true
if (isMarketplace) {
withContext(Dispatchers.IO) {

View File

@@ -12,14 +12,11 @@ import com.intellij.openapi.updateSettings.impl.pluginsAdvertisement.FUSEventSou
import com.intellij.openapi.util.IntellijInternalApi
import com.intellij.openapi.util.NlsSafe
import com.intellij.openapi.util.text.StringUtil
import com.intellij.ui.LicensingFacade
import com.intellij.util.PlatformUtils
import com.intellij.util.containers.ContainerUtil
import kotlinx.serialization.Serializable
import org.jetbrains.annotations.ApiStatus
import java.text.DecimalFormat
import java.util.*
import kotlin.text.startsWith
/**
* A lightweight model for representing plugin information in the UI.
@@ -33,7 +30,7 @@ interface PluginUiModel {
@get:NlsSafe
val version: String?
val isBundled: Boolean
val isIncompatibleWithCurrentOs: Boolean
val isIncompatibleWithCurrentPlatform: Boolean
val isIncompatible: Boolean
val canBeEnabled: Boolean

View File

@@ -23,7 +23,7 @@ class PluginUiModelAdapter(
get() = pluginDescriptor.version
override val isBundled: Boolean
get() = pluginDescriptor.isBundled
override val isIncompatibleWithCurrentOs: Boolean
override val isIncompatibleWithCurrentPlatform: Boolean
get() {
return getUnfulfilledOsRequirement(pluginDescriptor) != null
|| getUnfulfilledCpuArchRequirement(pluginDescriptor) != null

View File

@@ -414,7 +414,7 @@ class PluginDescriptorTest {
plugin(PluginManagerCore.CORE_PLUGIN_ID) {}.buildDir(pluginDirPath)
val descriptor = loadDescriptorInTest(pluginDirPath)
assertThat(descriptor).isNotNull
val hostIds = IdeaPluginCpuArchRequirement.getHostCpuArchModuleIds()
val hostIds = PluginCpuArchRequirement.getHostCpuArchModuleIds()
if (hostIds.isEmpty()) {
logger<PluginDescriptorTest>().warn("No host arch plugin aliases")
}