diff --git a/python/build/src/org/jetbrains/intellij/build/pycharm/pythons/pythons.kt b/python/build/src/org/jetbrains/intellij/build/pycharm/pythons/pythons.kt index 6766b2c6d4f9..d28143d7187e 100644 --- a/python/build/src/org/jetbrains/intellij/build/pycharm/pythons/pythons.kt +++ b/python/build/src/org/jetbrains/intellij/build/pycharm/pythons/pythons.kt @@ -25,7 +25,7 @@ object Pythons { "black-joblib-tenserflow", "1", listOf("black == 23.1.0", "joblib", "tensorflow")) - val CondaWithPyTorch = createPython("miniconda3-latest", + val CondaWithPyTorch = createPython("Miniconda3-latest", "conda-pytorch", "1", listOf("pytorch")) diff --git a/python/build/src/org/jetbrains/intellij/build/pycharm/pythons/setup.kt b/python/build/src/org/jetbrains/intellij/build/pycharm/pythons/setup.kt index 070548cc3229..4f8f910276c3 100644 --- a/python/build/src/org/jetbrains/intellij/build/pycharm/pythons/setup.kt +++ b/python/build/src/org/jetbrains/intellij/build/pycharm/pythons/setup.kt @@ -1,15 +1,14 @@ // Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package org.jetbrains.intellij.build.pycharm.pythons +import com.intellij.util.system.OS import org.jetbrains.intellij.build.IdeaProjectLoaderUtil import org.jetbrains.intellij.build.dependencies.BuildDependenciesCommunityRoot import org.jetbrains.intellij.build.dependencies.BuildDependenciesDownloader import org.jetbrains.intellij.build.downloadFileToCacheLocation import java.nio.file.Path import java.util.concurrent.TimeUnit -import kotlin.io.path.createDirectories -import kotlin.io.path.div -import kotlin.io.path.exists +import kotlin.io.path.* private val os: String = System.getProperty("os.name").lowercase().let { name -> when { @@ -30,6 +29,7 @@ private val arch: String = System.getProperty("os.arch").lowercase().let { arch private const val pyEnvUrl = "https://github.com/pyenv/pyenv/archive/master.zip" +private const val pyEnvWinUrl = "https://raw.githubusercontent.com/pyenv-win/pyenv-win/master/pyenv-win/install-pyenv-win.ps1" private val spaceUrl = "https://jetbrains.team/p/pyqa/packages/files/pythons" private val pipOptions = arrayOf("--trusted-host", "pypi.python.org", "--trusted-host", "pypi.org", "--trusted-host", "files.pythonhosted.org") val Python.directoryName: String @@ -55,26 +55,42 @@ fun runCommand(vararg args: String, env: Map = emptyMap()) { } -suspend fun getPyEnv(): Path { - val pyEnvPath = downloadFileToCacheLocation(pyEnvUrl, buildRoot) - val extracted = BuildDependenciesDownloader.extractFileToCacheLocation(buildRoot, pyEnvPath) - return extracted / "pyenv-master" -} +private val isWindows = OS.CURRENT == OS.Windows suspend fun setupPyEnv() { if (pyEnvHome.exists()) return println("*** Setup pyenv ***") - val pyEnv = getPyEnv() - val installSh = pyEnv / "plugins" / "python-build" / "install.sh" - pyEnv.createDirectories() - runCommand(installSh.toString(), env = mapOf("PREFIX" to pyEnvHome.toString())) + val pyEnv: Path + if (isWindows) { + val pyEnvPath = downloadFileToCacheLocation(pyEnvWinUrl, buildRoot) + runCommand("powershell", "-ExecutionPolicy", "Bypass", "-File", "$pyEnvPath", + env = mapOf("USERPROFILE" to pyEnvHome.toString())) + } else { + val pyEnvPath = downloadFileToCacheLocation(pyEnvUrl, buildRoot) + val extracted = BuildDependenciesDownloader.extractFileToCacheLocation(buildRoot, pyEnvPath) + pyEnv = extracted / "pyenv-master" + val installSh = pyEnv / "plugins" / "python-build" / "install.sh" + pyEnv.createDirectories() + runCommand(installSh.toString(), env = mapOf("PREFIX" to pyEnvHome.toString())) + } } +@OptIn(ExperimentalPathApi::class) suspend fun Python.installUsingPyEnv(): Path { setupPyEnv() val output = pythonsHome / directoryName if (output.exists()) return output - runCommand((pyEnvHome / "bin" / "python-build").toString(), pyenvDefinition, output.toString()) + if (isWindows) { + if (pyenvDefinition.lowercase().contains("miniconda")) { + val miniCondaFile = downloadFileToCacheLocation("https://repo.anaconda.com/miniconda/$pyenvDefinition-Windows-x86_64.exe", buildRoot) + runCommand(miniCondaFile.toString(), "/InstallationType=JustMe", "/AddToPath=0", "/RegisterPython=0", "/S", "/D=$output") + } else { + runCommand((pyEnvHome / ".pyenv" / "pyenv-win" / "bin" / "pyenv.bat").toString(), "install", pyenvDefinition) + (pyEnvHome / ".pyenv" / "pyenv-win" / "versions"/ pyenvDefinition).copyToRecursively(output, followLinks = false) + } + } else { + runCommand((pyEnvHome / "bin" / "python-build").toString(), pyenvDefinition, output.toString()) + } return output } @@ -82,10 +98,10 @@ suspend fun Python.installPackages() { if (packages.isEmpty()) return val output = pythonsHome / directoryName if ((output / "condabin").exists()) { - val conda = output / "condabin" / "conda" + val conda = output / "condabin" / if (isWindows) "conda.bat" else "conda" runCommand(conda.toString(), "install", "-y", *packages.toTypedArray()) } else { - val pip = output / "bin" / "pip" + val pip = if (isWindows) output / "Scripts" / "pip.exe" else output / "bin" / "pip" runCommand(pip.toString(), "install", *pipOptions, *packages.toTypedArray()) } }