mirror of
https://gitflic.ru/project/openide/openide.git
synced 2025-12-15 02:59:33 +07:00
fix uv detection for win and when creating cli; PY-75983
(cherry picked from commit f54ee351bfdceb6597a74d1fb128e000051984ba) GitOrigin-RevId: 3200c0ae179a2e4e15a9ff9691421803cd09e1af
This commit is contained in:
committed by
intellij-monorepo-bot
parent
77157d6fe2
commit
2769b5d234
@@ -14,7 +14,7 @@ import com.jetbrains.python.sdk.*
|
|||||||
import com.jetbrains.python.sdk.basePath
|
import com.jetbrains.python.sdk.basePath
|
||||||
import com.jetbrains.python.sdk.configuration.PyProjectSdkConfigurationExtension
|
import com.jetbrains.python.sdk.configuration.PyProjectSdkConfigurationExtension
|
||||||
import com.jetbrains.python.sdk.uv.PY_PROJECT_TOML
|
import com.jetbrains.python.sdk.uv.PY_PROJECT_TOML
|
||||||
import com.jetbrains.python.sdk.uv.getUvExecutable
|
import com.jetbrains.python.sdk.uv.impl.getUvExecutable
|
||||||
import com.jetbrains.python.sdk.uv.setupUvSdkUnderProgress
|
import com.jetbrains.python.sdk.uv.setupUvSdkUnderProgress
|
||||||
import java.io.FileNotFoundException
|
import java.io.FileNotFoundException
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
|
|||||||
@@ -1,13 +1,12 @@
|
|||||||
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||||
package com.jetbrains.python.sdk.add.v2
|
package com.jetbrains.python.sdk.add.v2
|
||||||
|
|
||||||
import com.intellij.ide.util.PropertiesComponent
|
|
||||||
import com.intellij.openapi.module.Module
|
import com.intellij.openapi.module.Module
|
||||||
import com.intellij.openapi.observable.properties.ObservableMutableProperty
|
import com.intellij.openapi.observable.properties.ObservableMutableProperty
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
import com.intellij.openapi.projectRoots.Sdk
|
import com.intellij.openapi.projectRoots.Sdk
|
||||||
import com.jetbrains.python.sdk.ModuleOrProject
|
import com.jetbrains.python.sdk.ModuleOrProject
|
||||||
import com.jetbrains.python.sdk.uv.uvPath
|
import com.jetbrains.python.sdk.uv.impl.setUvExecutable
|
||||||
import com.jetbrains.python.sdk.uv.setupUvSdkUnderProgress
|
import com.jetbrains.python.sdk.uv.setupUvSdkUnderProgress
|
||||||
import com.jetbrains.python.statistics.InterpreterType
|
import com.jetbrains.python.statistics.InterpreterType
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
@@ -24,7 +23,7 @@ class EnvironmentCreatorUv(model: PythonMutableTargetAddInterpreterModel, privat
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun savePathToExecutableToProperties() {
|
override fun savePathToExecutableToProperties() {
|
||||||
PropertiesComponent.getInstance().uvPath = Path.of(executable.get())
|
setUvExecutable(Path.of(executable.get()))
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun setupEnvSdk(project: Project?, module: Module?, baseSdks: List<Sdk>, projectPath: String, homePath: String?, installPackages: Boolean): Result<Sdk> {
|
override suspend fun setupEnvSdk(project: Project?, module: Module?, baseSdks: List<Sdk>, projectPath: String, homePath: String?, installPackages: Boolean): Result<Sdk> {
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ import com.jetbrains.python.sdk.flavors.conda.PyCondaEnv
|
|||||||
import com.jetbrains.python.sdk.flavors.conda.PyCondaEnvIdentity
|
import com.jetbrains.python.sdk.flavors.conda.PyCondaEnvIdentity
|
||||||
import com.jetbrains.python.sdk.pipenv.getPipEnvExecutable
|
import com.jetbrains.python.sdk.pipenv.getPipEnvExecutable
|
||||||
import com.jetbrains.python.sdk.poetry.getPoetryExecutable
|
import com.jetbrains.python.sdk.poetry.getPoetryExecutable
|
||||||
import com.jetbrains.python.sdk.uv.getUvExecutable
|
import com.jetbrains.python.sdk.uv.impl.getUvExecutable
|
||||||
import com.jetbrains.python.util.ErrorSink
|
import com.jetbrains.python.util.ErrorSink
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||||
package com.jetbrains.python.sdk.uv
|
package com.jetbrains.python.sdk.uv
|
||||||
|
|
||||||
import com.intellij.ide.util.PropertiesComponent
|
|
||||||
import com.intellij.openapi.module.Module
|
import com.intellij.openapi.module.Module
|
||||||
import com.intellij.openapi.projectRoots.Sdk
|
import com.intellij.openapi.projectRoots.Sdk
|
||||||
import com.intellij.openapi.util.NlsSafe
|
import com.intellij.openapi.util.NlsSafe
|
||||||
@@ -15,15 +14,11 @@ import com.jetbrains.python.sdk.findAmongRoots
|
|||||||
import com.jetbrains.python.sdk.setAssociationToModule
|
import com.jetbrains.python.sdk.setAssociationToModule
|
||||||
import com.jetbrains.python.sdk.uv.impl.createUvCli
|
import com.jetbrains.python.sdk.uv.impl.createUvCli
|
||||||
import com.jetbrains.python.sdk.uv.impl.createUvLowLevel
|
import com.jetbrains.python.sdk.uv.impl.createUvLowLevel
|
||||||
import com.jetbrains.python.sdk.uv.impl.detectUvExecutable
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
import kotlin.io.path.exists
|
|
||||||
import kotlin.io.path.pathString
|
import kotlin.io.path.pathString
|
||||||
|
|
||||||
internal const val UV_PATH_SETTING: String = "PyCharm.UV.Path"
|
|
||||||
|
|
||||||
internal val Sdk.isUv: Boolean
|
internal val Sdk.isUv: Boolean
|
||||||
get() = sdkAdditionalData is UvSdkAdditionalData
|
get() = sdkAdditionalData is UvSdkAdditionalData
|
||||||
|
|
||||||
@@ -50,18 +45,6 @@ val UV_LOCK: String = "uv.lock"
|
|||||||
// FIXME: move pyprojecttoml code out to common package
|
// FIXME: move pyprojecttoml code out to common package
|
||||||
val PY_PROJECT_TOML: String = "pyproject.toml"
|
val PY_PROJECT_TOML: String = "pyproject.toml"
|
||||||
|
|
||||||
var PropertiesComponent.uvPath: Path?
|
|
||||||
get() {
|
|
||||||
return getValue(UV_PATH_SETTING)?.let { Path.of(it) }
|
|
||||||
}
|
|
||||||
set(value) {
|
|
||||||
setValue(UV_PATH_SETTING, value.toString())
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getUvExecutable(): Path? {
|
|
||||||
return PropertiesComponent.getInstance().uvPath?.takeIf { it.exists() } ?: detectUvExecutable()
|
|
||||||
}
|
|
||||||
|
|
||||||
suspend fun setupUvSdkUnderProgress(
|
suspend fun setupUvSdkUnderProgress(
|
||||||
module: Module,
|
module: Module,
|
||||||
projectPath: Path,
|
projectPath: Path,
|
||||||
|
|||||||
@@ -2,7 +2,9 @@
|
|||||||
package com.jetbrains.python.sdk.uv.impl
|
package com.jetbrains.python.sdk.uv.impl
|
||||||
|
|
||||||
import com.intellij.execution.configurations.PathEnvironmentVariableUtil
|
import com.intellij.execution.configurations.PathEnvironmentVariableUtil
|
||||||
|
import com.intellij.ide.util.PropertiesComponent
|
||||||
import com.intellij.openapi.ui.ValidationInfo
|
import com.intellij.openapi.ui.ValidationInfo
|
||||||
|
import com.intellij.openapi.util.SystemInfo
|
||||||
import com.intellij.util.SystemProperties
|
import com.intellij.util.SystemProperties
|
||||||
import com.jetbrains.python.PyBundle
|
import com.jetbrains.python.PyBundle
|
||||||
import com.jetbrains.python.pathValidation.PlatformAndRoot
|
import com.jetbrains.python.pathValidation.PlatformAndRoot
|
||||||
@@ -12,20 +14,21 @@ import com.jetbrains.python.sdk.runExecutable
|
|||||||
import com.jetbrains.python.sdk.uv.UvCli
|
import com.jetbrains.python.sdk.uv.UvCli
|
||||||
import kotlinx.coroutines.CoroutineDispatcher
|
import kotlinx.coroutines.CoroutineDispatcher
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
|
|
||||||
import kotlin.io.path.exists
|
import kotlin.io.path.exists
|
||||||
import kotlin.io.path.pathString
|
import kotlin.io.path.pathString
|
||||||
|
|
||||||
internal fun detectUvExecutable(): Path? {
|
private const val UV_PATH_SETTING: String = "PyCharm.Uv.Path"
|
||||||
val name = "uv"
|
|
||||||
return PathEnvironmentVariableUtil.findInPath(name)?.toPath() ?: SystemProperties.getUserHome().let { homePath ->
|
|
||||||
Path.of(homePath, ".cargo", "bin", name).takeIf { it.exists() }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal fun validateUvExecutable(uvPath: Path?): ValidationInfo? {
|
private var PropertiesComponent.uvPath: Path?
|
||||||
|
get() {
|
||||||
|
return getValue(UV_PATH_SETTING)?.let { Path.of(it) }
|
||||||
|
}
|
||||||
|
set(value) {
|
||||||
|
setValue(UV_PATH_SETTING, value.toString())
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun validateUvExecutable(uvPath: Path?): ValidationInfo? {
|
||||||
return validateExecutableFile(ValidationRequest(
|
return validateExecutableFile(ValidationRequest(
|
||||||
path = uvPath?.pathString,
|
path = uvPath?.pathString,
|
||||||
fieldIsEmpty = PyBundle.message("python.sdk.uv.executable.not.found"),
|
fieldIsEmpty = PyBundle.message("python.sdk.uv.executable.not.found"),
|
||||||
@@ -34,15 +37,15 @@ internal fun validateUvExecutable(uvPath: Path?): ValidationInfo? {
|
|||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
internal suspend fun runUv(uv: Path, workingDir: Path, vararg args: String): Result<String> {
|
private suspend fun runUv(uv: Path, workingDir: Path, vararg args: String): Result<String> {
|
||||||
return runExecutable(uv, workingDir, *args)
|
return runExecutable(uv, workingDir, *args)
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class UvCliImpl(val dispatcher: CoroutineDispatcher, uvPath: Path?): UvCli {
|
private class UvCliImpl(val dispatcher: CoroutineDispatcher, uvPath: Path?) : UvCli {
|
||||||
val uv: Path
|
val uv: Path
|
||||||
|
|
||||||
init {
|
init {
|
||||||
val path = uvPath ?: detectUvExecutable()
|
val path = uvPath ?: getUvExecutable()
|
||||||
val error = validateUvExecutable(path)
|
val error = validateUvExecutable(path)
|
||||||
if (error != null) {
|
if (error != null) {
|
||||||
throw RuntimeException(error.message)
|
throw RuntimeException(error.message)
|
||||||
@@ -52,12 +55,31 @@ internal class UvCliImpl(val dispatcher: CoroutineDispatcher, uvPath: Path?): Uv
|
|||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun runUv(workingDir: Path, vararg args: String): Result<String> {
|
override suspend fun runUv(workingDir: Path, vararg args: String): Result<String> {
|
||||||
with(Dispatchers.IO) {
|
with(dispatcher) {
|
||||||
return runUv(uv, workingDir, *args)
|
return runUv(uv, workingDir, *args)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun detectUvExecutable(): Path? {
|
||||||
|
val name = when {
|
||||||
|
SystemInfo.isWindows -> "uv.exe"
|
||||||
|
else -> "uv"
|
||||||
|
}
|
||||||
|
|
||||||
|
return PathEnvironmentVariableUtil.findInPath(name)?.toPath() ?: SystemProperties.getUserHome().let { homePath ->
|
||||||
|
Path.of(homePath, ".local", "bin", name).takeIf { it.exists() } ?: Path.of(homePath, ".cargo", "bin", name).takeIf { it.exists() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getUvExecutable(): Path? {
|
||||||
|
return PropertiesComponent.getInstance().uvPath?.takeIf { it.exists() } ?: detectUvExecutable()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setUvExecutable(path: Path) {
|
||||||
|
PropertiesComponent.getInstance().uvPath = path
|
||||||
|
}
|
||||||
|
|
||||||
fun createUvCli(dispatcher: CoroutineDispatcher = Dispatchers.IO, uv: Path? = null): UvCli {
|
fun createUvCli(dispatcher: CoroutineDispatcher = Dispatchers.IO, uv: Path? = null): UvCli {
|
||||||
return UvCliImpl(dispatcher, uv)
|
return UvCliImpl(dispatcher, uv)
|
||||||
}
|
}
|
||||||
@@ -33,6 +33,8 @@ import com.jetbrains.python.sdk.add.addInterpretersAsync
|
|||||||
import com.jetbrains.python.sdk.basePath
|
import com.jetbrains.python.sdk.basePath
|
||||||
import com.jetbrains.python.sdk.uv.*
|
import com.jetbrains.python.sdk.uv.*
|
||||||
import com.jetbrains.python.sdk.uv.impl.detectUvExecutable
|
import com.jetbrains.python.sdk.uv.impl.detectUvExecutable
|
||||||
|
import com.jetbrains.python.sdk.uv.impl.getUvExecutable
|
||||||
|
import com.jetbrains.python.sdk.uv.impl.setUvExecutable
|
||||||
import com.jetbrains.python.statistics.InterpreterTarget
|
import com.jetbrains.python.statistics.InterpreterTarget
|
||||||
import com.jetbrains.python.statistics.InterpreterType
|
import com.jetbrains.python.statistics.InterpreterType
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
@@ -96,8 +98,10 @@ class PyAddNewUvPanel(
|
|||||||
addBrowseFolderListener(null, FileChooserDescriptorFactory.createSingleFileDescriptor())
|
addBrowseFolderListener(null, FileChooserDescriptorFactory.createSingleFileDescriptor())
|
||||||
val field = textField as? JBTextField ?: return@apply
|
val field = textField as? JBTextField ?: return@apply
|
||||||
service<PythonSdkCoroutineService>().cs.launch {
|
service<PythonSdkCoroutineService>().cs.launch {
|
||||||
detectUvExecutable()?.let { field.emptyText.text = "Auto-detected: ${it.absolutePathString()}" }
|
detectUvExecutable()?.let {
|
||||||
PropertiesComponent.getInstance().uvPath?.let {
|
field.emptyText.text = "Auto-detected: ${it.absolutePathString()}"
|
||||||
|
}
|
||||||
|
getUvExecutable()?.let {
|
||||||
field.text = it.pathString
|
field.text = it.pathString
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -153,7 +157,9 @@ class PyAddNewUvPanel(
|
|||||||
}
|
}
|
||||||
|
|
||||||
val uvPath = uvPathField.text.nullize()?.let { Path.of(it) }
|
val uvPath = uvPathField.text.nullize()?.let { Path.of(it) }
|
||||||
uvPath?.let { PropertiesComponent.getInstance().uvPath = it }
|
uvPath?.let {
|
||||||
|
setUvExecutable(it)
|
||||||
|
}
|
||||||
val sdk = runBlockingCancellable {
|
val sdk = runBlockingCancellable {
|
||||||
setupUvSdkUnderProgress(module, Path.of(path), existingSdks, Path.of(python))
|
setupUvSdkUnderProgress(module, Path.of(path), existingSdks, Path.of(python))
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user