Prevent calls to onFirstRun default implementation for gradle rc

This is temporary until we get compatible API from IDEA
    to support gradle run configurations for MPP projects in IDEA 191+
This commit is contained in:
Pavel V. Talanov
2019-02-27 17:02:38 +01:00
parent 25dc81c2bd
commit 853e9a2aa0
@@ -0,0 +1,241 @@
/*
* Copyright 2010-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.idea.run
import com.intellij.execution.actions.ConfigurationContext
import com.intellij.execution.actions.ConfigurationFromContext
import com.intellij.execution.actions.RunConfigurationProducer
import com.intellij.execution.junit.PatternConfigurationProducer
import com.intellij.ide.plugins.PluginManager
import com.intellij.openapi.extensions.PluginId.getId
import com.intellij.openapi.externalSystem.service.execution.ExternalSystemRunConfiguration
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil
import com.intellij.openapi.util.Ref
import com.intellij.openapi.util.component1
import com.intellij.openapi.util.component2
import com.intellij.psi.PsiClass
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiMethod
import org.jetbrains.kotlin.idea.caches.project.isMPPModule
import org.jetbrains.plugins.gradle.execution.test.runner.TestClassGradleConfigurationProducer
import org.jetbrains.plugins.gradle.execution.test.runner.TestMethodGradleConfigurationProducer
import org.jetbrains.plugins.gradle.util.GradleConstants
private val IS_JUNIT_ENABLED by lazy { isPluginEnabled("JUnit") }
private val IS_TESTNG_ENABLED by lazy { isPluginEnabled("TestNG-J") }
private val IS_TEST_FRAMEWORK_PLUGIN_ENABLED by lazy { IS_JUNIT_ENABLED || IS_TESTNG_ENABLED }
private fun isPluginEnabled(id: String): Boolean {
return PluginManager.isPluginInstalled(getId(id)) && id !in PluginManager.getDisabledPlugins()
}
private fun getTestClass(leaf: PsiElement): PsiClass? {
if (IS_JUNIT_ENABLED) {
KotlinJUnitRunConfigurationProducer.getTestClass(leaf)?.let { return it }
}
if (IS_TESTNG_ENABLED) {
KotlinTestNgConfigurationProducer.getTestClassAndMethod(leaf)?.let { (testClass, testMethod) ->
return if (testMethod == null) testClass else null
}
}
return null
}
private fun getTestMethod(leaf: PsiElement): PsiMethod? {
if (IS_JUNIT_ENABLED) {
KotlinJUnitRunConfigurationProducer.getTestMethod(leaf)?.let { return it }
}
if (IS_TESTNG_ENABLED) {
KotlinTestNgConfigurationProducer.getTestClassAndMethod(leaf)?.second?.let { return it }
}
return null
}
class KotlinTestClassGradleConfigurationProducer : TestClassGradleConfigurationProducer() {
override fun doSetupConfigurationFromContext(
configuration: ExternalSystemRunConfiguration,
context: ConfigurationContext,
sourceElement: Ref<PsiElement>
): Boolean {
if (!IS_TEST_FRAMEWORK_PLUGIN_ENABLED) return false
val contextLocation = context.location ?: return false
val module = context.module?.asJvmModule() ?: return false
if (RunConfigurationProducer.getInstance(PatternConfigurationProducer::class.java).isMultipleElementsSelected(context)) {
return false
}
val leaf = context.location?.psiElement ?: return false
val testClass = getTestClass(leaf) ?: return false
sourceElement.set(testClass)
if (!ExternalSystemApiUtil.isExternalSystemAwareModule(GradleConstants.SYSTEM_ID, module)) return false
val projectPath = resolveProjectPath(module) ?: return false
val tasksToRun = getTasksToRun(module)
if (tasksToRun.isEmpty()) return false
configuration.settings.externalProjectPath = projectPath
configuration.settings.taskNames = tasksToRun
configuration.settings.scriptParameters = String.format("--tests \"%s\"", testClass.qualifiedName)
configuration.name = testClass.name ?: "unknown"
JavaRunConfigurationExtensionManagerUtil.getInstance().extendCreatedConfiguration(configuration, contextLocation)
return true
}
override fun onFirstRun(fromContext: ConfigurationFromContext, context: ConfigurationContext, performRunnable: Runnable) {
if (context.location?.module?.isMPPModule == true) {
// TODO: remove hack when IDEA has new API
performRunnable.run()
} else {
super.onFirstRun(fromContext, context, performRunnable)
}
}
override fun doIsConfigurationFromContext(configuration: ExternalSystemRunConfiguration, context: ConfigurationContext): Boolean {
if (!IS_TEST_FRAMEWORK_PLUGIN_ENABLED) return false
val leaf = context.location?.psiElement ?: return false
val module = context.module?.asJvmModule() ?: return false
if (RunConfigurationProducer.getInstance(PatternConfigurationProducer::class.java).isMultipleElementsSelected(context)) {
return false
}
if (getTestMethod(leaf) != null) return false
val testClass = getTestClass(leaf)
if (testClass == null || testClass.qualifiedName == null) return false
val projectPath = resolveProjectPath(module) ?: return false
if (projectPath != configuration.settings.externalProjectPath) {
return false
}
if (!configuration.settings.taskNames.containsAll(getTasksToRun(module))) return false
val scriptParameters = configuration.settings.scriptParameters + ' '
val i = scriptParameters.indexOf("--tests ")
if (i == -1) return false
val str = scriptParameters.substringAfter("--tests ").trim() + ' '
return str.startsWith("\"" + testClass.qualifiedName + "\"" + ' ') && !str.contains("--tests")
}
}
class KotlinTestMethodGradleConfigurationProducer : TestMethodGradleConfigurationProducer() {
override fun doSetupConfigurationFromContext(
configuration: ExternalSystemRunConfiguration,
context: ConfigurationContext,
sourceElement: Ref<PsiElement>
): Boolean {
if (!IS_TEST_FRAMEWORK_PLUGIN_ENABLED) return false
val contextLocation = context.location ?: return false
context.module?.asJvmModule() ?: return false
if (RunConfigurationProducer.getInstance(PatternConfigurationProducer::class.java).isMultipleElementsSelected(context)) {
return false
}
val psiMethod = getTestMethod(contextLocation.psiElement) ?: return false
sourceElement.set(psiMethod)
val containingClass = psiMethod.containingClass ?: return false
if (!applyTestMethodConfiguration(configuration, context, psiMethod, containingClass)) return false
JavaRunConfigurationExtensionManagerUtil.getInstance().extendCreatedConfiguration(configuration, contextLocation)
return true
}
override fun onFirstRun(fromContext: ConfigurationFromContext, context: ConfigurationContext, performRunnable: Runnable) {
if (context.location?.module?.isMPPModule == true) {
// TODO: remove hack when IDEA has new API
performRunnable.run()
} else {
super.onFirstRun(fromContext, context, performRunnable)
}
}
override fun doIsConfigurationFromContext(configuration: ExternalSystemRunConfiguration, context: ConfigurationContext): Boolean {
if (!IS_TEST_FRAMEWORK_PLUGIN_ENABLED) return false
if (RunConfigurationProducer.getInstance(PatternConfigurationProducer::class.java).isMultipleElementsSelected(context)) {
return false
}
val contextLocation = context.location ?: return false
val module = context.module?.asJvmModule() ?: return false
val psiMethod = getTestMethod(contextLocation.psiElement) ?: return false
val containingClass = psiMethod.containingClass ?: return false
val projectPath = resolveProjectPath(module) ?: return false
if (projectPath != configuration.settings.externalProjectPath) {
return false
}
if (!configuration.settings.taskNames.containsAll(getTasksToRun(module))) return false
val scriptParameters = configuration.settings.scriptParameters + ' '
val testFilter = createTestFilter(containingClass, psiMethod)
return scriptParameters.contains(testFilter!!)
}
private fun applyTestMethodConfiguration(
configuration: ExternalSystemRunConfiguration,
context: ConfigurationContext,
psiMethod: PsiMethod,
vararg containingClasses: PsiClass
): Boolean {
val module = context.module ?: return false
if (!ExternalSystemApiUtil.isExternalSystemAwareModule(GradleConstants.SYSTEM_ID, module)) return false
val projectPath = resolveProjectPath(module) ?: return false
val tasksToRun = getTasksToRun(module)
if (tasksToRun.isEmpty()) return false
configuration.settings.externalProjectPath = projectPath
configuration.settings.taskNames = tasksToRun
val params = containingClasses.joinToString("") { aClass -> createTestFilter(aClass, psiMethod) ?: "" }
configuration.settings.scriptParameters = params.trim()
configuration.name = (if (containingClasses.size == 1) containingClasses[0].name + "." else "") + psiMethod.name
return true
}
companion object {
private fun createTestFilter(aClass: PsiClass, psiMethod: PsiMethod): String? {
return createTestFilter(aClass.qualifiedName, psiMethod.name)
}
fun createTestFilter(aClass: String?, method: String?): String? {
if (aClass == null) return null
val testFilterPattern = aClass + if (method == null) "" else '.' + method
return "--tests \"$testFilterPattern\" "
}
}
}