mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-03-22 06:50:54 +07:00
ASPR-3010 Recommended plugin installation on IDEA startup (fix required plugins downloads)
This commit is contained in:
@@ -1,19 +1,68 @@
|
||||
<!-- Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. -->
|
||||
<!-- Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. -->
|
||||
<!-- -->
|
||||
<!-- Modified by Nikita Iarychenko at 2025 as part of the OpenIDE project (https://openide.ru). -->
|
||||
<!-- Any modifications are available on the same license terms as the original source code. -->
|
||||
<svg width="48" height="48" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_3917_59728)">
|
||||
<path d="M44.9455 0H18.7204C17.9105 0 17.1334 0.3216 16.5604 0.894545L0.894545 16.56C0.3216 17.1329 0 17.9097 0 18.72V44.9455C0 46.6324 1.36756 48 3.05455 48H29.2791C30.0899 48 30.8675 47.6775 31.4404 47.1041L47.1055 31.4212C47.6775 30.8487 47.9987 30.072 47.9987 29.2625L48 3.05455C48 1.36756 46.6324 0 44.9455 0Z" fill="url(#paint0_radial_3917_59728)"/>
|
||||
<path d="M39 9H9V39H39V9Z" fill="black"/>
|
||||
<path d="M25 33H13V35.0001H25V33Z" fill="white"/>
|
||||
<path d="M13 22.0828H15.1845V14.9172H13V13H19.4819V14.9172H17.2975V22.0828H19.4819V24H13V22.0828Z" fill="white"/>
|
||||
<path d="M20.582 22.0202H22.1614C22.4808 22.0202 22.7652 21.9521 23.014 21.816C23.2627 21.6798 23.4551 21.4874 23.5913 21.2387C23.7274 20.9899 23.7955 20.7059 23.7955 20.3861V13H25.9404V20.5349C25.9404 21.195 25.7883 21.7882 25.4846 22.3147C25.1808 22.8412 24.7619 23.2538 24.2274 23.5521C23.693 23.8508 23.0934 24 22.4282 24H20.582V22.0202Z" fill="white"/>
|
||||
</g>
|
||||
<defs>
|
||||
<radialGradient id="paint0_radial_3917_59728" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(47.9996) rotate(135) scale(65.4071)">
|
||||
<stop offset="0.0819502" stop-color="#FE2857"/>
|
||||
<stop offset="0.72777" stop-color="#007EFF"/>
|
||||
</radialGradient>
|
||||
<clipPath id="clip0_3917_59728">
|
||||
<rect width="48" height="48" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
<g clip-path="url(#clip0_3181_719)">
|
||||
<mask id="mask0_3181_719" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="0" y="0" width="48" height="48">
|
||||
<rect width="48" height="48" rx="3.5625" fill="white"/>
|
||||
</mask>
|
||||
<g mask="url(#mask0_3181_719)">
|
||||
<g filter="url(#filter0_f_3181_719)">
|
||||
<circle cx="23.8041" cy="23.8041" r="23.8041" fill="#9B84E7"/>
|
||||
</g>
|
||||
<g filter="url(#filter1_f_3181_719)">
|
||||
<ellipse cx="43.5" cy="22.125" rx="24" ry="41.625" fill="#9B84E7"/>
|
||||
</g>
|
||||
<g filter="url(#filter2_f_3181_719)">
|
||||
<ellipse cx="17.5349" cy="54.5633" rx="21.0612" ry="21.8449" fill="#F24E4E"/>
|
||||
</g>
|
||||
<g filter="url(#filter3_f_3181_719)">
|
||||
<ellipse cx="-2.05727" cy="46.8245" rx="14.0082" ry="20.3755" fill="#9B84E7"/>
|
||||
</g>
|
||||
<g filter="url(#filter4_f_3181_719)">
|
||||
<ellipse cx="49.5" cy="51" rx="12.75" ry="22.5" fill="white"/>
|
||||
</g>
|
||||
<g filter="url(#filter5_f_3181_719)">
|
||||
<ellipse cx="8.62019" cy="8.13063" rx="23.7061" ry="27.5265" fill="#4D409B"/>
|
||||
</g>
|
||||
</g>
|
||||
<path d="M30.2595 16.9275H38.3003C40.1579 16.9275 41.6633 15.514 41.6633 13.7722V10.2923C41.6633 8.55051 40.1579 7.13702 38.3003 7.13702H30.2595C28.4019 7.13702 26.8965 8.55051 26.8965 10.2923V13.7722C26.8965 15.514 28.4019 16.9275 30.2595 16.9275Z" fill="white"/>
|
||||
<path d="M38.686 19.5119H29.8753C28.0449 19.5119 26.5613 21.002 26.5613 22.8404V34.0881C26.5613 34.7775 26.0438 35.3812 25.3592 35.4232C24.6165 35.4688 23.9991 34.8778 23.9991 34.1374V8.27327C23.9991 6.8999 22.7933 5.8293 21.4405 6.02263C12.7097 7.27015 6 14.81 6 23.9219C6.00182 33.8966 14.0698 42 24.0009 42C33.932 42 42 33.9057 42 23.9183V22.8386C42 21.0001 40.5164 19.51 38.686 19.51V19.5119Z" fill="white"/>
|
||||
</g>
|
||||
<defs>
|
||||
<filter id="filter0_f_3181_719" x="-5.49551" y="-5.49551" width="58.5994" height="58.5992" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
|
||||
<feGaussianBlur stdDeviation="2.74776" result="effect1_foregroundBlur_3181_719"/>
|
||||
</filter>
|
||||
<filter id="filter1_f_3181_719" x="14.0045" y="-24.9955" width="58.991" height="94.241" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
|
||||
<feGaussianBlur stdDeviation="2.74776" result="effect1_foregroundBlur_3181_719"/>
|
||||
</filter>
|
||||
<filter id="filter2_f_3181_719" x="-9.25698" y="26.9878" width="53.5838" height="55.151" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
|
||||
<feGaussianBlur stdDeviation="2.86531" result="effect1_foregroundBlur_3181_719"/>
|
||||
</filter>
|
||||
<filter id="filter3_f_3181_719" x="-21.5609" y="20.9535" width="39.0071" height="51.7421" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
|
||||
<feGaussianBlur stdDeviation="2.74776" result="effect1_foregroundBlur_3181_719"/>
|
||||
</filter>
|
||||
<filter id="filter4_f_3181_719" x="28.6488" y="20.3988" width="41.7024" height="61.2024" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
|
||||
<feGaussianBlur stdDeviation="4.05061" result="effect1_foregroundBlur_3181_719"/>
|
||||
</filter>
|
||||
<filter id="filter5_f_3181_719" x="-22.6876" y="-26.9975" width="62.6154" height="70.2563" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
|
||||
<feGaussianBlur stdDeviation="3.80082" result="effect1_foregroundBlur_3181_719"/>
|
||||
</filter>
|
||||
<clipPath id="clip0_3181_719">
|
||||
<rect width="48" height="48" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 4.4 KiB |
@@ -94,7 +94,7 @@ plugins.page.ok.button.continue.without = Продолжить без Плаги
|
||||
plugins.page.ok.button.install = Установить Выбранные
|
||||
plugins.page.choose.counter.no = Нет плагинов для установки
|
||||
plugins.page.choose.counter.one = 1 плагин выбран для установки
|
||||
plugins.page.choose.counter.multiple = {0} плагина выбрано для установки
|
||||
plugins.page.choose.counter.multiple = Выбрано плагинов для установки: {0}
|
||||
plugins.page.list.item.bundled = Предустановлен
|
||||
|
||||
# Plugin descriptions
|
||||
|
||||
@@ -143,12 +143,12 @@ class OpenIdeStartupWizardService(private val coroutineScope: CoroutineScope) :
|
||||
name = "CSV Editor",
|
||||
description = ImportSettingsBundle.message("plugin.description.csvEditor"),
|
||||
),
|
||||
WizardPluginImpl(
|
||||
id = "com.koxudaxi.pydantic",
|
||||
icon = AllIcons.Plugins.PluginLogo,
|
||||
name = "Pydantic",
|
||||
description = ImportSettingsBundle.message("plugin.description.pydantic"),
|
||||
),
|
||||
//WizardPluginImpl(
|
||||
// id = "com.koxudaxi.pydantic",
|
||||
// icon = AllIcons.Plugins.PluginLogo,
|
||||
// name = "Pydantic",
|
||||
// description = ImportSettingsBundle.message("plugin.description.pydantic"),
|
||||
//),
|
||||
)
|
||||
),
|
||||
WizardPluginGroupImpl(
|
||||
|
||||
@@ -7,11 +7,11 @@ package com.intellij.ide.startup.importSettings.jb
|
||||
import com.intellij.configurationStore.getPerOsSettingsStorageFolderName
|
||||
import com.intellij.ide.GeneralSettings
|
||||
import com.intellij.ide.plugins.*
|
||||
import com.intellij.ide.plugins.marketplace.MarketplaceRequests
|
||||
import com.intellij.ide.startup.importSettings.ImportSettingsBundle
|
||||
import com.intellij.ide.startup.importSettings.StartupImportIcons
|
||||
import com.intellij.ide.startup.importSettings.chooser.ui.SettingsImportOrigin
|
||||
import com.intellij.ide.startup.importSettings.data.*
|
||||
import com.intellij.ide.startup.importSettings.openide.utils.PluginInstallationUtil
|
||||
import com.intellij.ide.startup.importSettings.statistics.ImportSettingsEventsCollector
|
||||
import com.intellij.ide.startup.importSettings.transfer.TransferSettingsProgress
|
||||
import com.intellij.l10n.LocalizationStateService
|
||||
@@ -402,6 +402,8 @@ class JbImportServiceImpl(private val coroutineScope: CoroutineScope) : JbServic
|
||||
filteredCategories.add(SettingsCategory.PLUGINS)
|
||||
plugins2import = productInfo.getPluginsDescriptors().filter {
|
||||
setting.selectedChildIds?.contains(it.key.idString) ?: false
|
||||
}.filter { (_, descriptor) ->
|
||||
PluginManagerCore.isCompatible(descriptor) && descriptor.namespace?.lowercase() != "jetbrains"
|
||||
}
|
||||
unselectedPlugins = setting.unselectedChildIds
|
||||
logger.info("Will import ${setting.selectedChildIds?.size} custom plugins: ${setting.selectedChildIds?.joinToString()}\n" +
|
||||
@@ -650,11 +652,9 @@ private suspend fun calculatePluginsToInstall(alreadyInstalled: Set<PluginId>, t
|
||||
if (pluginsToAttemptInstallation.isEmpty()) return emptyList()
|
||||
|
||||
reporter.text(ImportSettingsBundle.message("plugin-installation.progress.determining-plugins-to-download"))
|
||||
val loadedPlugins = withContext(Dispatchers.IO) {
|
||||
MarketplaceRequests.loadLastCompatiblePluginDescriptors(pluginsToAttemptInstallation.toSet(), null, true)
|
||||
}
|
||||
val loadedPlugins = PluginInstallationUtil.getPluginsToInstall(pluginsToAttemptInstallation)
|
||||
|
||||
return loadedPlugins
|
||||
return loadedPlugins.filter { it.pluginId !in alreadyInstalled }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ package com.intellij.ide.startup.importSettings.openide.utils
|
||||
|
||||
import com.intellij.ide.plugins.IdeaPluginDescriptor
|
||||
import com.intellij.ide.plugins.PluginManagerCore
|
||||
import com.intellij.ide.plugins.PluginNode
|
||||
import com.intellij.ide.plugins.marketplace.MarketplaceRequests
|
||||
import com.intellij.ide.startup.importSettings.ImportSettingsBundle
|
||||
import com.intellij.ide.startup.importSettings.openide.service.PluginIconService
|
||||
@@ -57,9 +58,7 @@ object PluginInstallationUtil {
|
||||
progressIndicator.text = ImportSettingsBundle.message("plugin-installation.progress.determining-plugins-to-download")
|
||||
progressIndicator.fraction = 0.05
|
||||
|
||||
val pluginsToInstall: List<IdeaPluginDescriptor> = withContext(Dispatchers.IO) {
|
||||
MarketplaceRequests.Companion.loadLastCompatiblePluginDescriptors(idsToInstall.toSet(), null, true)
|
||||
}
|
||||
val pluginsToInstall: List<IdeaPluginDescriptor> = getPluginsToInstall(idsToInstall)
|
||||
|
||||
if (pluginsToInstall.isEmpty()) {
|
||||
progressIndicator.fraction = 1.0
|
||||
@@ -67,20 +66,12 @@ object PluginInstallationUtil {
|
||||
}
|
||||
|
||||
var shouldRestart = false
|
||||
val installedDuringSession = mutableSetOf<PluginId>()
|
||||
val queue = ArrayDeque(pluginsToInstall)
|
||||
val progressPerPlugin = 0.9 / pluginsToInstall.size.coerceAtLeast(1)
|
||||
var currentProgress = 0.1
|
||||
|
||||
while (queue.isNotEmpty()) {
|
||||
for (plugin in pluginsToInstall) {
|
||||
if (progressIndicator.isCanceled) break
|
||||
|
||||
val plugin = queue.removeFirst()
|
||||
if (plugin.pluginId in installedDuringSession || PluginManagerCore.isPluginInstalled(plugin.pluginId)) {
|
||||
continue
|
||||
}
|
||||
|
||||
val progressPerPlugin = 0.9 / (queue.size + 1).coerceAtLeast(1)
|
||||
|
||||
progressIndicator.text = ImportSettingsBundle.message("plugin-installation.progress.downloading", plugin.name)
|
||||
|
||||
// Load and set plugin icon
|
||||
@@ -102,28 +93,13 @@ object PluginInstallationUtil {
|
||||
}
|
||||
|
||||
withContext(Dispatchers.IO) {
|
||||
val prepareToInstall = downloader.prepareToInstall(null)
|
||||
if (prepareToInstall) {
|
||||
|
||||
val depIds = downloader.descriptor
|
||||
.dependencies
|
||||
.filter { !it.isOptional }
|
||||
.map { it.pluginId }
|
||||
.filter { it !in installedDuringSession && !PluginManagerCore.isPluginInstalled(it) }
|
||||
|
||||
if (depIds.isNotEmpty()) {
|
||||
val depDescriptors = MarketplaceRequests.loadLastCompatiblePluginDescriptors(depIds.toSet(), null, true)
|
||||
queue.addAll(depDescriptors)
|
||||
}
|
||||
}
|
||||
downloader.prepareToInstall(null)
|
||||
}
|
||||
|
||||
val appliedWithoutRestart = withContext(Dispatchers.EDT + ModalityState.any().asContextElement()) {
|
||||
downloader.installDynamically(null)
|
||||
}
|
||||
|
||||
installedDuringSession.add(plugin.pluginId)
|
||||
|
||||
if (!appliedWithoutRestart) {
|
||||
shouldRestart = true
|
||||
}
|
||||
@@ -139,4 +115,20 @@ object PluginInstallationUtil {
|
||||
progressIndicator.text = null
|
||||
return shouldRestart
|
||||
}
|
||||
|
||||
suspend fun getPluginsToInstall(idsToInstall: List<PluginId>): List<PluginNode> = withContext(Dispatchers.IO) {
|
||||
val directPlugins = MarketplaceRequests.loadLastCompatiblePluginDescriptors(idsToInstall.toSet(), null, true)
|
||||
|
||||
val dependencyIds = directPlugins
|
||||
.asSequence()
|
||||
.flatMap { it.dependencies }
|
||||
.filter { !it.isOptional }
|
||||
.map { it.pluginId }
|
||||
.filter { it !in idsToInstall && !PluginManagerCore.isPluginInstalled(it) }
|
||||
.toSet()
|
||||
|
||||
val dependencyPlugins = MarketplaceRequests.loadLastCompatiblePluginDescriptors(dependencyIds, null, true)
|
||||
|
||||
(directPlugins + dependencyPlugins).distinctBy { it.pluginId }
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user