diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactManagerImpl.java b/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactManagerImpl.java index ccaa173503f9..476bb87449a3 100644 --- a/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactManagerImpl.java +++ b/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactManagerImpl.java @@ -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.packaging.impl.artifacts; import com.intellij.compiler.server.BuildManager; @@ -265,7 +265,7 @@ public final class ArtifactManagerImpl extends ArtifactManager implements Persis @Nls(capitalization = Nls.Capitalization.Sentence) String errorMessage) { final InvalidArtifactImpl artifact = new InvalidArtifactImpl(state, errorMessage, externalSource); ProjectLoadingErrorsNotifier.getInstance(myProject).registerError(new ArtifactLoadingErrorDescription(myProject, artifact)); - UnknownFeaturesCollector.getInstance(myProject).registerUnknownFeature(FEATURE_TYPE, state.getArtifactType(), "Artifact"); + UnknownFeaturesCollector.getInstance(myProject).registerUnknownFeature(FEATURE_TYPE, state.getArtifactType(), JavaCompilerBundle.message("plugins.advertiser.feature.artifact")); return artifact; } diff --git a/java/compiler/openapi/resources/messages/JavaCompilerBundle.properties b/java/compiler/openapi/resources/messages/JavaCompilerBundle.properties index a26ac2e345b8..0b9d59977b3b 100644 --- a/java/compiler/openapi/resources/messages/JavaCompilerBundle.properties +++ b/java/compiler/openapi/resources/messages/JavaCompilerBundle.properties @@ -321,3 +321,4 @@ notification.title.cpu.snapshot.build.has.been.captured=Build CPU snapshot has b action.show.snapshot.location.text=Show Snapshot Location dialog.message.failed.to.determine.host.ip.for.wsl.jdk=Failed to determine host IP for WSL JDK progress.preparing.wsl.build.environment=Preparing WSL build environment... +plugins.advertiser.feature.artifact=artifact diff --git a/java/java-impl/src/META-INF/JavaPlugin.xml b/java/java-impl/src/META-INF/JavaPlugin.xml index 9fcd12a81073..aa76191420e2 100644 --- a/java/java-impl/src/META-INF/JavaPlugin.xml +++ b/java/java-impl/src/META-INF/JavaPlugin.xml @@ -2154,6 +2154,8 @@ + + diff --git a/java/java-impl/src/com/intellij/ide/JavaDependencyCollector.kt b/java/java-impl/src/com/intellij/ide/JavaDependencyCollector.kt new file mode 100644 index 000000000000..142deff5c9f2 --- /dev/null +++ b/java/java-impl/src/com/intellij/ide/JavaDependencyCollector.kt @@ -0,0 +1,35 @@ +// 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 + +import com.intellij.openapi.module.ModuleManager +import com.intellij.openapi.project.Project +import com.intellij.openapi.project.rootManager +import com.intellij.openapi.roots.LibraryOrderEntry +import com.intellij.openapi.roots.impl.libraries.LibraryEx +import com.intellij.openapi.roots.libraries.LibraryTablesRegistrar +import com.intellij.ide.plugins.DependencyCollector +import org.jetbrains.idea.maven.utils.library.RepositoryLibraryProperties + +class JavaDependencyCollector : DependencyCollector { + override val dependencyKind: String + get() = "java" + + override fun collectDependencies(project: Project): List { + val projectLibraryTable = LibraryTablesRegistrar.getInstance().getLibraryTable(project) + val result = mutableSetOf() + for (library in projectLibraryTable.libraries) { + val properties = (library as? LibraryEx)?.properties as? RepositoryLibraryProperties ?: continue + result.add(properties.groupId + ":" + properties.artifactId) + } + for (module in ModuleManager.getInstance(project).modules) { + for (orderEntry in module.rootManager.orderEntries) { + if (orderEntry is LibraryOrderEntry && orderEntry.isModuleLevel) { + val library = orderEntry.library + val properties = (library as? LibraryEx)?.properties as? RepositoryLibraryProperties ?: continue + result.add(properties.groupId + ":" + properties.artifactId) + } + } + } + return result.toList() + } +} \ No newline at end of file diff --git a/platform/execution-impl/src/com/intellij/execution/impl/RunManagerImpl.kt b/platform/execution-impl/src/com/intellij/execution/impl/RunManagerImpl.kt index 6a0e46211eff..a116cd1ed4ce 100644 --- a/platform/execution-impl/src/com/intellij/execution/impl/RunManagerImpl.kt +++ b/platform/execution-impl/src/com/intellij/execution/impl/RunManagerImpl.kt @@ -8,6 +8,7 @@ import com.intellij.execution.configurations.* import com.intellij.execution.runners.ExecutionEnvironment import com.intellij.execution.runners.ExecutionUtil import com.intellij.execution.runners.ProgramRunner +import com.intellij.ide.IdeBundle import com.intellij.ide.plugins.DynamicPluginListener import com.intellij.ide.plugins.IdeaPluginDescriptor import com.intellij.ide.util.PropertiesComponent @@ -999,7 +1000,7 @@ open class RunManagerImpl @JvmOverloads constructor(val project: Project, shared if (checkUnknown && typeId != null) { UnknownFeaturesCollector.getInstance(project).registerUnknownFeature( CONFIGURATION_TYPE_FEATURE_ID, - "Run Configuration", + ExecutionBundle.message("plugins.advertiser.feature.run.configuration"), typeId, factoryId ?: typeId, ) diff --git a/platform/lang-api/resources/messages/ExecutionBundle.properties b/platform/lang-api/resources/messages/ExecutionBundle.properties index 5f70f703a1f3..19e850f8623a 100644 --- a/platform/lang-api/resources/messages/ExecutionBundle.properties +++ b/platform/lang-api/resources/messages/ExecutionBundle.properties @@ -604,4 +604,6 @@ startup.tasks.confirmation.notification.action.review=Review edit.configuration.templates=Edit configuration templates... progress.title.patch.java.command.line.parameters=Patch Java command line parameters status.text.add.new.run.configuration=Add new run configuration... -status.text.or.select.run.configuration.to.edit=or select run configuration to edit \ No newline at end of file +status.text.or.select.run.configuration.to.edit=or select run configuration to edit + +plugins.advertiser.feature.run.configuration=run configuration diff --git a/platform/lang-impl/src/com/intellij/facet/FacetManagerBase.java b/platform/lang-impl/src/com/intellij/facet/FacetManagerBase.java index 8e9fed11aa0a..0d6b34d7fa9c 100644 --- a/platform/lang-impl/src/com/intellij/facet/FacetManagerBase.java +++ b/platform/lang-impl/src/com/intellij/facet/FacetManagerBase.java @@ -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.facet; import com.intellij.facet.impl.FacetEventsPublisher; @@ -11,6 +11,7 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ProjectLoadingErrorsNotifier; import com.intellij.openapi.project.Project; +import com.intellij.openapi.project.ProjectBundle; import com.intellij.openapi.updateSettings.impl.pluginsAdvertisement.UnknownFeaturesCollector; import com.intellij.openapi.util.NlsContexts; import com.intellij.openapi.util.text.StringUtil; @@ -140,7 +141,7 @@ public abstract class FacetManagerBase extends FacetManager { FacetLoadingErrorDescription description = new FacetLoadingErrorDescription(facet); ProjectLoadingErrorsNotifier.getInstance(project).registerError(description); if (unknownType) { - UnknownFeaturesCollector.getInstance(project).registerUnknownFeature(FEATURE_TYPE, state.getFacetType(), "Facet"); + UnknownFeaturesCollector.getInstance(project).registerUnknownFeature(FEATURE_TYPE, state.getFacetType(), ProjectBundle.message("plugins.advertiser.feature.facet")); } } } diff --git a/platform/platform-api/resources/messages/IdeBundle.properties b/platform/platform-api/resources/messages/IdeBundle.properties index eaf2cc6d456a..5fd02d35110d 100644 --- a/platform/platform-api/resources/messages/IdeBundle.properties +++ b/platform/platform-api/resources/messages/IdeBundle.properties @@ -1629,6 +1629,7 @@ plugins.advertiser.action.ignore.ultimate=Do not suggest Ultimate plugins.advertiser.ultimate.features.detected=Features covered by IntelliJ IDEA Ultimate {0} are detected plugins.advertiser.missing.feature={0,choice,1#Plugin|2#Plugins} supporting {1} ''{2}'' {0,choice,1#is|2#are} currently {3,choice,0#disabled|1#not installed}. plugins.advertiser.missing.features={0,choice,1#Plugin|2#Plugins} supporting features ({1}) {0,choice,1#is|2#are} currently {2,choice,0#disabled|1#not installed}. +plugins.advertiser.feature.dependency=dependency do.not.ask.me.again=Don't ask again diff --git a/platform/platform-api/resources/messages/ProjectBundle.properties b/platform/platform-api/resources/messages/ProjectBundle.properties index b46dc8ac15a8..157b9c7ca0ae 100644 --- a/platform/platform-api/resources/messages/ProjectBundle.properties +++ b/platform/platform-api/resources/messages/ProjectBundle.properties @@ -283,3 +283,4 @@ list.item.group.by.type=Type list.item.group.by.directory=Directory label.directory.will.be.excluded.from.framework.detection=''{0}'' directory will be excluded from framework detection label.framework.detection.will.be.disabled=''{0}'' framework detection will be disabled. +plugins.advertiser.feature.facet=facet diff --git a/platform/platform-api/src/com/intellij/ide/plugins/PluginFeatureService.kt b/platform/platform-api/src/com/intellij/ide/plugins/PluginFeatureService.kt index fbd137fa7b60..b4278f1a181f 100644 --- a/platform/platform-api/src/com/intellij/ide/plugins/PluginFeatureService.kt +++ b/platform/platform-api/src/com/intellij/ide/plugins/PluginFeatureService.kt @@ -15,9 +15,6 @@ import com.intellij.util.xmlb.annotations.XMap storages = [Storage(StoragePathMacros.CACHE_FILE, roamingType = RoamingType.DISABLED)], ) class PluginFeatureService : SimplePersistentStateComponent(State()) { - - private val featureMappingsCollected = mutableSetOf() - @Tag("features") class FeaturePluginsList : BaseState() { @@ -65,8 +62,6 @@ class PluginFeatureService : SimplePersistentStateComponent String, displayNameMapping: (T) -> String, ) { - if (!featureMappingsCollected.add(featureType)) return - val pluginsList = state[featureType] ep.processWithPluginDescriptor { ext, descriptor -> pluginsList[idMapping(ext)] = FeaturePluginData( diff --git a/platform/platform-api/src/com/intellij/ide/plugins/advertiser/data.kt b/platform/platform-api/src/com/intellij/ide/plugins/advertiser/data.kt index 0fb4ef500d61..abd319492760 100644 --- a/platform/platform-api/src/com/intellij/ide/plugins/advertiser/data.kt +++ b/platform/platform-api/src/com/intellij/ide/plugins/advertiser/data.kt @@ -14,7 +14,7 @@ class PluginData @JvmOverloads constructor( @Attribute("fromCustomRepository") val isFromCustomRepository: Boolean = false, ) : Comparable { - val pluginId: PluginId = PluginId.getId(pluginIdString) + val pluginId: PluginId get() = PluginId.getId(pluginIdString) val pluginName = nullablePluginName ?: pluginIdString diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/DependencyCollector.kt b/platform/platform-impl/src/com/intellij/ide/plugins/DependencyCollector.kt new file mode 100644 index 000000000000..301a36f18f4d --- /dev/null +++ b/platform/platform-impl/src/com/intellij/ide/plugins/DependencyCollector.kt @@ -0,0 +1,44 @@ +// 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.plugins + +import com.intellij.openapi.extensions.ExtensionPointName +import com.intellij.openapi.project.Project +import com.intellij.openapi.startup.StartupActivity +import com.intellij.util.xmlb.annotations.Attribute + +interface DependencyCollector { + val dependencyKind: String + + fun collectDependencies(project: Project): List + + companion object { + val EP_NAME = ExtensionPointName.create("com.intellij.dependencyCollector") + } +} + +class DependencySupportBean { + @Attribute("kind") + @JvmField + var kind: String = "" + + @Attribute("coordinate") + @JvmField + var coordinate: String = "" + + companion object { + val EP_NAME = ExtensionPointName.create("com.intellij.dependencySupport") + } +} + +const val DEPENDENCY_SUPPORT_FEATURE = "dependencySupport" + +class DependencyFeatureCollector : StartupActivity.Background { + override fun runActivity(project: Project) { + PluginFeatureService.instance.collectFeatureMapping( + DEPENDENCY_SUPPORT_FEATURE, + DependencySupportBean.EP_NAME, + { bean -> bean.kind + ":" + bean.coordinate }, + { bean -> bean.kind + ":" + bean.coordinate } + ) + } +} diff --git a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/pluginsAdvertisement/PluginAdvertiserService.kt b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/pluginsAdvertisement/PluginAdvertiserService.kt index 99ce5727a70d..56c3a97a311b 100644 --- a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/pluginsAdvertisement/PluginAdvertiserService.kt +++ b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/pluginsAdvertisement/PluginAdvertiserService.kt @@ -29,7 +29,7 @@ open class PluginAdvertiserService { fun run( project: Project, customPlugins: List, - unknownFeatures: Set, + unknownFeatures: Collection, ) { val features = MultiMap.createSet() val disabledPlugins = HashMap() diff --git a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/pluginsAdvertisement/PluginsAdvertiserStartupActivity.kt b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/pluginsAdvertisement/PluginsAdvertiserStartupActivity.kt index 2ed5bff408d0..0ed9a153092a 100644 --- a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/pluginsAdvertisement/PluginsAdvertiserStartupActivity.kt +++ b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/pluginsAdvertisement/PluginsAdvertiserStartupActivity.kt @@ -1,6 +1,9 @@ // 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.pluginsAdvertisement +import com.intellij.ide.IdeBundle +import com.intellij.ide.plugins.DEPENDENCY_SUPPORT_FEATURE +import com.intellij.ide.plugins.DependencyCollector import com.intellij.ide.plugins.advertiser.KnownExtensions import com.intellij.ide.plugins.advertiser.KnownExtensionsService import com.intellij.ide.plugins.advertiser.PluginData @@ -9,7 +12,6 @@ import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.fileTypes.FileTypeFactory import com.intellij.openapi.project.Project import com.intellij.openapi.startup.StartupActivity -import com.intellij.openapi.updateSettings.impl.UpdateSettings import com.intellij.ui.EditorNotifications internal class PluginsAdvertiserStartupActivity : StartupActivity.Background { @@ -17,8 +19,7 @@ internal class PluginsAdvertiserStartupActivity : StartupActivity.Background { override fun runActivity(project: Project) { val application = ApplicationManager.getApplication() if (application.isUnitTestMode || - application.isHeadlessEnvironment || - !UpdateSettings.getInstance().isPluginsCheckNeeded) { + application.isHeadlessEnvironment) { return } @@ -29,7 +30,10 @@ internal class PluginsAdvertiserStartupActivity : StartupActivity.Background { val extensionsService = KnownExtensionsService.instance val extensions = extensionsService.extensions - val unknownFeatures = UnknownFeaturesCollector.getInstance(project).unknownFeatures + + val unknownFeatures = UnknownFeaturesCollector.getInstance(project).unknownFeatures.toMutableList() + unknownFeatures.addAll(collectDependencyUnknownFeatures(project)) + if (extensions != null && unknownFeatures.isEmpty()) { return } @@ -54,6 +58,17 @@ internal class PluginsAdvertiserStartupActivity : StartupActivity.Background { } } + private fun collectDependencyUnknownFeatures(project: Project): List { + return DependencyCollector.EP_NAME.extensions.flatMap { dependencyCollector -> + dependencyCollector.collectDependencies(project).map { coordinate -> + UnknownFeature(DEPENDENCY_SUPPORT_FEATURE, + IdeBundle.message("plugins.advertiser.feature.dependency"), + dependencyCollector.dependencyKind + ":" + coordinate, + coordinate) + } + } + } + companion object { @JvmStatic diff --git a/platform/platform-resources/src/META-INF/PlatformExtensionPoints.xml b/platform/platform-resources/src/META-INF/PlatformExtensionPoints.xml index 51ddaa4e5e83..6393604ba038 100644 --- a/platform/platform-resources/src/META-INF/PlatformExtensionPoints.xml +++ b/platform/platform-resources/src/META-INF/PlatformExtensionPoints.xml @@ -420,5 +420,8 @@ + + + diff --git a/platform/platform-resources/src/META-INF/PlatformExtensions.xml b/platform/platform-resources/src/META-INF/PlatformExtensions.xml index bcfa5d15a158..3bcfcc9b44fb 100644 --- a/platform/platform-resources/src/META-INF/PlatformExtensions.xml +++ b/platform/platform-resources/src/META-INF/PlatformExtensions.xml @@ -1228,7 +1228,9 @@ - + + +/