mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[IFT] Add another type of sdk for Python learning project: virtual environment.
Venv will be used if "ide.features.trainer.use.venv" registry option set to true. This flag was added because venv doesn't work properly in master due to classpath problems. IDEA-CR-69125 GitOrigin-RevId: a16c5c2943a8fc19d331e00660a0ebdee8e178ae
This commit is contained in:
committed by
intellij-monorepo-bot
parent
18fb6cb193
commit
8076cfc8dd
@@ -1,6 +1,7 @@
|
||||
// Copyright 2000-2019 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 training.lang
|
||||
|
||||
import com.intellij.ide.impl.OpenProjectTask
|
||||
import com.intellij.ide.impl.ProjectUtil
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.command.CommandProcessor
|
||||
@@ -25,7 +26,9 @@ abstract class AbstractLangSupport : LangSupport {
|
||||
override fun installAndOpenLearningProject(projectPath: Path,
|
||||
projectToClose: Project?,
|
||||
postInitCallback: (learnProject: Project) -> Unit) {
|
||||
ProjectUtils.simpleInstallAndOpenLearningProject(projectPath, projectToClose, this, postInitCallback)
|
||||
ProjectUtils.simpleInstallAndOpenLearningProject(projectPath, this,
|
||||
OpenProjectTask(projectToClose = projectToClose),
|
||||
postInitCallback)
|
||||
}
|
||||
|
||||
override fun getSdkForProject(project: Project): Sdk? {
|
||||
|
||||
@@ -173,7 +173,9 @@ internal object OpenLessonActivities {
|
||||
|
||||
//open next lesson if current is passed
|
||||
LOG.debug("${project.name}: Set lesson view")
|
||||
LearningUiManager.activeToolWindow?.setLearnPanel()
|
||||
LearningUiManager.activeToolWindow = LearnToolWindowFactory.learnWindowPerProject[project]?.also {
|
||||
it.setLearnPanel()
|
||||
}
|
||||
LOG.debug("${project.name}: XmlLesson onStart()")
|
||||
lesson.onStart()
|
||||
|
||||
@@ -269,9 +271,9 @@ internal object OpenLessonActivities {
|
||||
val learnToolWindow = toolWindowManager.getToolWindow(LearnToolWindowFactory.LEARN_TOOL_WINDOW)
|
||||
if (learnToolWindow != null) {
|
||||
val runnable = if (lesson.properties.showLearnToolwindowAtStart) null else Runnable { learnToolWindow.hide() }
|
||||
learnToolWindow.show(runnable)
|
||||
DumbService.getInstance(myLearnProject).runWhenSmart {
|
||||
// Try to fix PyChar double startup indexing :(
|
||||
learnToolWindow.show(runnable)
|
||||
// Try to fix PyCharm double startup indexing :(
|
||||
val openWhenSmart = {
|
||||
DumbService.getInstance(myLearnProject).runWhenSmart {
|
||||
openLessonForPreparedProject(myLearnProject, lesson)
|
||||
|
||||
@@ -106,8 +106,8 @@ object ProjectUtils {
|
||||
}
|
||||
|
||||
fun simpleInstallAndOpenLearningProject(projectPath: Path,
|
||||
projectToClose: Project?,
|
||||
langSupport: LangSupport,
|
||||
openProjectTask: OpenProjectTask,
|
||||
postInitCallback: (learnProject: Project) -> Unit) {
|
||||
val copied = copyLearningProjectFiles(projectPath, langSupport)
|
||||
if (!copied) return
|
||||
@@ -115,7 +115,7 @@ object ProjectUtils {
|
||||
val projectDirectoryVirtualFile = LocalFileSystem.getInstance().refreshAndFindFileByNioFile(projectPath)
|
||||
?: error("Copied Learn project folder is null")
|
||||
invokeLater {
|
||||
val project = ProjectUtil.openOrImport(projectDirectoryVirtualFile.toNioPath(), OpenProjectTask(projectToClose = projectToClose))
|
||||
val project = ProjectUtil.openOrImport(projectDirectoryVirtualFile.toNioPath(), openProjectTask)
|
||||
?: error("Could not create project for ${langSupport.primaryLanguage}")
|
||||
PropertiesComponent.getInstance(project).setValue(LEARNING_PROJECT_MODIFICATION, System.currentTimeMillis().toString())
|
||||
postInitCallback(project)
|
||||
|
||||
@@ -16,6 +16,5 @@
|
||||
<orderEntry type="module" module-name="intellij.platform.debugger" />
|
||||
<orderEntry type="module" module-name="intellij.platform.testGuiFramework" />
|
||||
<orderEntry type="module" module-name="intellij.platform.lang.impl" />
|
||||
<orderEntry type="module" module-name="intellij.pycharm.community.customization.impl" />
|
||||
</component>
|
||||
</module>
|
||||
|
||||
@@ -4,4 +4,9 @@
|
||||
<ift.language.extension language="Python" implementationClass="com.jetbrains.python.ift.PythonLangSupport"/>
|
||||
<ift.learning.course language="Python" implementationClass="com.jetbrains.python.ift.PythonLearningCourse"/>
|
||||
</extensions>
|
||||
|
||||
<extensions defaultExtensionNs="com.intellij">
|
||||
<registryKey defaultValue="true" description="Initialize Python learning project with virtual environment."
|
||||
key="ide.features.trainer.use.venv"/>
|
||||
</extensions>
|
||||
</idea-plugin>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// 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.
|
||||
package com.jetbrains.python.ift
|
||||
|
||||
import com.intellij.ide.impl.OpenProjectTask
|
||||
import com.intellij.openapi.application.runWriteAction
|
||||
import com.intellij.openapi.progress.ProgressManager
|
||||
import com.intellij.openapi.project.Project
|
||||
@@ -8,17 +9,23 @@ import com.intellij.openapi.projectRoots.Sdk
|
||||
import com.intellij.openapi.projectRoots.impl.SdkConfigurationUtil
|
||||
import com.intellij.openapi.roots.ModuleRootManager
|
||||
import com.intellij.openapi.roots.ex.ProjectRootManagerEx
|
||||
import com.intellij.openapi.util.io.FileUtil
|
||||
import com.intellij.openapi.util.registry.Registry
|
||||
import com.intellij.openapi.vfs.LocalFileSystem
|
||||
import com.intellij.openapi.vfs.VfsUtilCore
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import com.jetbrains.python.configuration.PyConfigurableInterpreterList
|
||||
import com.jetbrains.python.psi.LanguageLevel
|
||||
import com.jetbrains.python.sdk.*
|
||||
import com.jetbrains.python.sdk.configuration.PyProjectSdkConfiguration.setReadyToUseSdk
|
||||
import com.jetbrains.python.sdk.configuration.PyProjectVirtualEnvConfiguration
|
||||
import com.jetbrains.python.sdk.flavors.PythonSdkFlavor
|
||||
import com.jetbrains.python.statistics.modules
|
||||
import training.lang.AbstractLangSupport
|
||||
import training.learn.LearnBundle
|
||||
import training.learn.exceptons.NoSdkException
|
||||
import training.learn.lesson.kimpl.LessonUtil
|
||||
import training.project.ProjectUtils
|
||||
import java.nio.file.Path
|
||||
|
||||
class PythonLangSupport : AbstractLangSupport() {
|
||||
@@ -51,7 +58,26 @@ class PythonLangSupport : AbstractLangSupport() {
|
||||
}
|
||||
}
|
||||
|
||||
override fun installAndOpenLearningProject(projectPath: Path,
|
||||
projectToClose: Project?,
|
||||
postInitCallback: (learnProject: Project) -> Unit) {
|
||||
// if we open project with isProjectCreatedFromWizard flag as true, PythonSdkConfigurator will not run and configure our sdks
|
||||
// and we will configure it individually without any race conditions
|
||||
val openProjectTask = OpenProjectTask(projectToClose = projectToClose, isProjectCreatedWithWizard = true)
|
||||
ProjectUtils.simpleInstallAndOpenLearningProject(projectPath, this, openProjectTask, postInitCallback)
|
||||
}
|
||||
|
||||
override fun getSdkForProject(project: Project): Sdk? {
|
||||
if (project.pythonSdk != null) return null // sdk already configured
|
||||
return if (useVenv) {
|
||||
createVenv(project)
|
||||
}
|
||||
else {
|
||||
findSystemWideSdk(project)
|
||||
}
|
||||
}
|
||||
|
||||
private fun findSystemWideSdk(project: Project): Sdk? {
|
||||
val sdkList = ProgressManager.getInstance().runProcessWithProgressSynchronously<List<Sdk>, Exception>(
|
||||
{ findAllPythonSdks(Path.of(project.basePath)) },
|
||||
LearnBundle.message("learn.project.initializing.python.sdk.finding.progress.title"),
|
||||
@@ -74,6 +100,37 @@ class PythonLangSupport : AbstractLangSupport() {
|
||||
return preferredSdk
|
||||
}
|
||||
|
||||
private fun createVenv(project: Project): Sdk? {
|
||||
val module = project.modules.first()
|
||||
val existingSdks = getExistingSdks()
|
||||
val baseSdks = findBaseSdks(existingSdks, module, project)
|
||||
val preferredSdk = PyProjectVirtualEnvConfiguration.findPreferredVirtualEnvBaseSdk(baseSdks)
|
||||
val venvRoot = FileUtil.toSystemDependentName(PySdkSettings.instance.getPreferredVirtualEnvBasePath(project.basePath))
|
||||
val venvSdk = PyProjectVirtualEnvConfiguration.createVirtualEnvSynchronously(preferredSdk, existingSdks, venvRoot,
|
||||
project.basePath, project, module, project)
|
||||
return venvSdk?.also {
|
||||
SdkConfigurationUtil.addSdk(it)
|
||||
}
|
||||
}
|
||||
|
||||
override fun applyProjectSdk(sdk: Sdk, project: Project) {
|
||||
setReadyToUseSdk(project, project.modules.first(), sdk)
|
||||
if (!useVenv && LessonUtil.productName != defaultProductName) {
|
||||
// This is a workaround for IDEA SetupJavaProjectFromSourcesActivity that replaces our SDK with Java SDK
|
||||
val rootManager = ProjectRootManagerEx.getInstanceEx(project)
|
||||
rootManager.addProjectJdkListener {
|
||||
if (rootManager.projectSdk?.sdkType !is PythonSdkType) {
|
||||
setReadyToUseSdk(project, project.modules.first(), sdk)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun getExistingSdks(): List<Sdk> {
|
||||
return PyConfigurableInterpreterList.getInstance(null).allPythonSdks
|
||||
.sortedWith(PreferredSdkComparator.INSTANCE)
|
||||
}
|
||||
|
||||
private fun isNoOlderThan27(sdk: Sdk): Boolean {
|
||||
val languageLevel = if (sdk is PyDetectedSdk) {
|
||||
sdk.guessedLanguageLevel
|
||||
@@ -84,15 +141,8 @@ class PythonLangSupport : AbstractLangSupport() {
|
||||
return languageLevel?.isAtLeast(LanguageLevel.PYTHON27) ?: false
|
||||
}
|
||||
|
||||
override fun applyProjectSdk(sdk: Sdk, project: Project) {
|
||||
setReadyToUseSdk(project, project.modules.first(), sdk)
|
||||
val rootManager = ProjectRootManagerEx.getInstanceEx(project)
|
||||
rootManager.addProjectJdkListener {
|
||||
if (rootManager.projectSdk?.sdkType !is PythonSdkType) {
|
||||
setReadyToUseSdk(project, project.modules.first(), sdk)
|
||||
}
|
||||
}
|
||||
}
|
||||
private val useVenv: Boolean
|
||||
get() = Registry.`is`("ide.features.trainer.use.venv")
|
||||
|
||||
override fun checkSdk(sdk: Sdk?, project: Project) {
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user