mirror of
https://gitflic.ru/project/openide/openide.git
synced 2025-12-14 18:05:27 +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.configuration.PyProjectSdkConfigurationExtension
|
||||
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 java.io.FileNotFoundException
|
||||
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.
|
||||
package com.jetbrains.python.sdk.add.v2
|
||||
|
||||
import com.intellij.ide.util.PropertiesComponent
|
||||
import com.intellij.openapi.module.Module
|
||||
import com.intellij.openapi.observable.properties.ObservableMutableProperty
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.projectRoots.Sdk
|
||||
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.statistics.InterpreterType
|
||||
import java.nio.file.Path
|
||||
@@ -24,7 +23,7 @@ class EnvironmentCreatorUv(model: PythonMutableTargetAddInterpreterModel, privat
|
||||
}
|
||||
|
||||
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> {
|
||||
|
||||
@@ -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.pipenv.getPipEnvExecutable
|
||||
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 kotlinx.coroutines.Dispatchers
|
||||
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.
|
||||
package com.jetbrains.python.sdk.uv
|
||||
|
||||
import com.intellij.ide.util.PropertiesComponent
|
||||
import com.intellij.openapi.module.Module
|
||||
import com.intellij.openapi.projectRoots.Sdk
|
||||
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.uv.impl.createUvCli
|
||||
import com.jetbrains.python.sdk.uv.impl.createUvLowLevel
|
||||
import com.jetbrains.python.sdk.uv.impl.detectUvExecutable
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import java.nio.file.Path
|
||||
import kotlin.io.path.exists
|
||||
import kotlin.io.path.pathString
|
||||
|
||||
internal const val UV_PATH_SETTING: String = "PyCharm.UV.Path"
|
||||
|
||||
internal val Sdk.isUv: Boolean
|
||||
get() = sdkAdditionalData is UvSdkAdditionalData
|
||||
|
||||
@@ -50,18 +45,6 @@ val UV_LOCK: String = "uv.lock"
|
||||
// FIXME: move pyprojecttoml code out to common package
|
||||
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(
|
||||
module: Module,
|
||||
projectPath: Path,
|
||||
|
||||
@@ -2,7 +2,9 @@
|
||||
package com.jetbrains.python.sdk.uv.impl
|
||||
|
||||
import com.intellij.execution.configurations.PathEnvironmentVariableUtil
|
||||
import com.intellij.ide.util.PropertiesComponent
|
||||
import com.intellij.openapi.ui.ValidationInfo
|
||||
import com.intellij.openapi.util.SystemInfo
|
||||
import com.intellij.util.SystemProperties
|
||||
import com.jetbrains.python.PyBundle
|
||||
import com.jetbrains.python.pathValidation.PlatformAndRoot
|
||||
@@ -12,20 +14,21 @@ import com.jetbrains.python.sdk.runExecutable
|
||||
import com.jetbrains.python.sdk.uv.UvCli
|
||||
import kotlinx.coroutines.CoroutineDispatcher
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
|
||||
import java.nio.file.Path
|
||||
|
||||
import kotlin.io.path.exists
|
||||
import kotlin.io.path.pathString
|
||||
|
||||
internal fun detectUvExecutable(): Path? {
|
||||
val name = "uv"
|
||||
return PathEnvironmentVariableUtil.findInPath(name)?.toPath() ?: SystemProperties.getUserHome().let { homePath ->
|
||||
Path.of(homePath, ".cargo", "bin", name).takeIf { it.exists() }
|
||||
private const val UV_PATH_SETTING: String = "PyCharm.Uv.Path"
|
||||
|
||||
private var PropertiesComponent.uvPath: Path?
|
||||
get() {
|
||||
return getValue(UV_PATH_SETTING)?.let { Path.of(it) }
|
||||
}
|
||||
set(value) {
|
||||
setValue(UV_PATH_SETTING, value.toString())
|
||||
}
|
||||
|
||||
internal fun validateUvExecutable(uvPath: Path?): ValidationInfo? {
|
||||
private fun validateUvExecutable(uvPath: Path?): ValidationInfo? {
|
||||
return validateExecutableFile(ValidationRequest(
|
||||
path = uvPath?.pathString,
|
||||
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)
|
||||
}
|
||||
|
||||
internal class UvCliImpl(val dispatcher: CoroutineDispatcher, uvPath: Path?): UvCli {
|
||||
private class UvCliImpl(val dispatcher: CoroutineDispatcher, uvPath: Path?) : UvCli {
|
||||
val uv: Path
|
||||
|
||||
init {
|
||||
val path = uvPath ?: detectUvExecutable()
|
||||
val path = uvPath ?: getUvExecutable()
|
||||
val error = validateUvExecutable(path)
|
||||
if (error != null) {
|
||||
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> {
|
||||
with(Dispatchers.IO) {
|
||||
with(dispatcher) {
|
||||
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 {
|
||||
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.uv.*
|
||||
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.InterpreterType
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
@@ -96,8 +98,10 @@ class PyAddNewUvPanel(
|
||||
addBrowseFolderListener(null, FileChooserDescriptorFactory.createSingleFileDescriptor())
|
||||
val field = textField as? JBTextField ?: return@apply
|
||||
service<PythonSdkCoroutineService>().cs.launch {
|
||||
detectUvExecutable()?.let { field.emptyText.text = "Auto-detected: ${it.absolutePathString()}" }
|
||||
PropertiesComponent.getInstance().uvPath?.let {
|
||||
detectUvExecutable()?.let {
|
||||
field.emptyText.text = "Auto-detected: ${it.absolutePathString()}"
|
||||
}
|
||||
getUvExecutable()?.let {
|
||||
field.text = it.pathString
|
||||
}
|
||||
}
|
||||
@@ -153,7 +157,9 @@ class PyAddNewUvPanel(
|
||||
}
|
||||
|
||||
val uvPath = uvPathField.text.nullize()?.let { Path.of(it) }
|
||||
uvPath?.let { PropertiesComponent.getInstance().uvPath = it }
|
||||
uvPath?.let {
|
||||
setUvExecutable(it)
|
||||
}
|
||||
val sdk = runBlockingCancellable {
|
||||
setupUvSdkUnderProgress(module, Path.of(path), existingSdks, Path.of(python))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user