PY-22514: Do not use RunConfigurationProducerService to prevent

runConfigurations.xml changes
* We need to exclude some producers some how. We used
 RunConfigurationProducerService, but it persists itself leading to
   PY-22514. We now unregister beans explicitly
This commit is contained in:
Ilya.Kazakevich
2017-02-02 20:03:05 +03:00
parent bec191620e
commit 85b7ff7814
4 changed files with 39 additions and 47 deletions
@@ -63,10 +63,6 @@ public class RunConfigurationProducerService implements PersistentStateComponent
myState.ignoredProducers.add(ignoredProducer.getName());
}
public void removeIgnoredProducer(@NotNull Class<? extends RunConfigurationProducer<?>> ignoredProducer) {
myState.ignoredProducers.remove(ignoredProducer.getName());
}
public boolean isIgnored(RunConfigurationProducer<?> producer) {
return myState.ignoredProducers.contains(producer.getClass().getName());
}
@@ -29,6 +29,7 @@ import com.intellij.psi.codeStyle.CodeStyleSettings;
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
import com.intellij.util.messages.MessageBus;
import com.jetbrains.python.codeInsight.PyCodeInsightSettings;
import com.jetbrains.python.testing.universalTests.PyUniversalTestLegacyInteropKt;
import org.jetbrains.annotations.NonNls;
import javax.swing.*;
@@ -84,6 +85,12 @@ public class PyCharmInitialConfigurator {
}
Registry.get("ide.scratch.enabled").setValue(true);
/*
According to PyUniversalTestLegacyInteropKt we need to call "init"
*/
PyUniversalTestLegacyInteropKt.init(bus);
}
private static void showInitialConfigurationDialog() {
@@ -56,20 +56,6 @@ public final class PythonTestConfigurationType implements ConfigurationType {
}
public PythonTestConfigurationType() {
/*
According to PyUniversalTestLegacyInteropKt we need to call "projectInitialized" when it is initialized
*/
ApplicationManager.getApplication().getMessageBus().connect().subscribe(ProjectLifecycleListener.TOPIC, new ProjectLifecycleListener() {
@Override
public void projectComponentsInitialized(@NotNull
final Project project) {
if (project.isInitialized()) {
PyUniversalTestLegacyInteropKt.projectInitialized(project);
return;
}
StartupManager.getInstance(project).runWhenProjectIsInitialized(() -> PyUniversalTestLegacyInteropKt.projectInitialized(project));
}
});
}
@Override
@@ -1,17 +1,20 @@
package com.jetbrains.python.testing.universalTests
import com.intellij.execution.RunConfigurationProducerService
import com.intellij.execution.RunManager
import com.intellij.execution.actions.RunConfigurationProducer
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.diagnostic.Logger
import com.intellij.openapi.extensions.Extensions
import com.intellij.openapi.fileEditor.FileDocumentManager
import com.intellij.openapi.project.Project
import com.intellij.openapi.project.impl.ProjectLifecycleListener
import com.intellij.openapi.startup.StartupManager
import com.intellij.openapi.util.JDOMExternalizable
import com.intellij.openapi.util.registry.Registry
import com.intellij.openapi.vfs.LocalFileSystem
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.psi.PsiDocumentManager
import com.intellij.util.messages.MessageBus
import com.jetbrains.python.psi.PyFile
import com.jetbrains.python.psi.PyQualifiedNameOwner
import com.jetbrains.python.psi.PyUtil
@@ -25,7 +28,6 @@ import com.jetbrains.python.testing.nosetest.PythonNoseTestRunConfiguration
import com.jetbrains.python.testing.pytest.PyTestRunConfiguration
import com.jetbrains.python.testing.unittest.PythonUnitTestRunConfiguration
import org.jdom.Element
import org.picocontainer.MutablePicoContainer
/**
* Module to support legacy configurations.
@@ -42,46 +44,47 @@ import org.picocontainer.MutablePicoContainer
*/
fun isNewTestsModeEnabled(): Boolean = Registry.`is`("python.tests.enableUniversalTests")
/**
* Call when container is ready
*/
fun init(bus: MessageBus) {
disableUnneededConfigurationProducer()
// Delegate to project initialization
bus.connect().subscribe(ProjectLifecycleListener.TOPIC, object : ProjectLifecycleListener {
override fun projectComponentsInitialized(project: Project) {
if (project.isInitialized) {
projectInitialized(project)
return
}
StartupManager.getInstance(project).runWhenProjectIsInitialized { projectInitialized(project) }
}
})
}
/**
* To be called when project initialized to copy old configs to new one
*/
fun projectInitialized(project: Project) {
private fun projectInitialized(project: Project) {
assert(project.isInitialized, { "Project is not initialized yet" })
RunManager.getInstance(project).allConfigurationsList.filterIsInstance(PyUniversalTestConfiguration::class.java).forEach {
it.legacyConfigurationAdapter.copyFromLegacyIfNeeded()
}
disableUnneededConfigurationProducer(project)
}
/**
* It is impossible to have 2 producers for one type (class cast exception may take place), so we need to disable either old or new one
*/
private fun disableUnneededConfigurationProducer(project: Project) {
val container = ApplicationManager.getApplication().picoContainer as MutablePicoContainer
private fun disableUnneededConfigurationProducer() {
val extensionPoint = Extensions.getArea(null).getExtensionPoint(RunConfigurationProducer.EP_NAME)
@Suppress("UNCHECKED_CAST")
val newProducers = container.getComponentInstancesOfType(
PyUniversalTestsConfigurationProducer::class.java) as List<RunConfigurationProducer<*>>
@Suppress("UNCHECKED_CAST")
val legacyProducers = container.getComponentInstancesOfType(
PythonTestLegacyConfigurationProducer::class.java) as List<RunConfigurationProducer<*>>
val producersToRemove = if (isNewTestsModeEnabled()) {
legacyProducers
val newMode = isNewTestsModeEnabled()
extensionPoint.extensions.forEach {
if ((it is PyUniversalTestsConfigurationProducer && !newMode) ||
(it is PythonTestLegacyConfigurationProducer<*> && newMode)) {
extensionPoint.unregisterExtension(it)
}
}
else {
newProducers
}
val configurationProducerService = RunConfigurationProducerService.getInstance(project)
// First, enable all
(legacyProducers + newProducers).forEach { configurationProducerService.removeIgnoredProducer(it.javaClass) }
// Then, disable one that need to be disabled
producersToRemove.forEach { configurationProducerService.addIgnoredProducer(it.javaClass) }
}
private fun getVirtualFileByPath(path: String): VirtualFile? {
@@ -162,7 +165,7 @@ class PyUniversalTestLegacyConfigurationAdapter<in T : PyUniversalTestConfigurat
}
fun copyFromLegacyIfNeeded() {
assert(project.isInitialized, {"Initialized project required"})
assert(project.isInitialized, { "Initialized project required" })
if (containsLegacyInformation ?: return && !(legacyInformationCopiedToNew ?: false)) {
configManager.copyFromLegacy()
legacyInformationCopiedToNew = true