From a79ea7edfd0240da8c3a4136315bca34fbfe1416 Mon Sep 17 00:00:00 2001 From: Aleksandr Sorotskii Date: Fri, 18 Jul 2025 21:01:44 +0200 Subject: [PATCH] support system pythons provided by asdf; PY-32643 Ready for Merge GitOrigin-RevId: 926ee14228644c33ab4a17247a07cdf71799b265 --- .../intellij.python.community.impl.xml | 4 +- ...honCommunityServicesSystemPythonIcons.java | 1 + .../community/system/providers/expui/asdf.svg | 27 ++++++++ .../impl/providers/AsdfSystemProvider.kt | 64 +++++++++++++++++++ 4 files changed, 95 insertions(+), 1 deletion(-) create mode 100644 python/services/system-python/resources/icons/com/intellij/python/community/system/providers/expui/asdf.svg create mode 100644 python/services/system-python/src/com/intellij/python/community/services/systemPython/impl/providers/AsdfSystemProvider.kt diff --git a/python/pluginResources/intellij.python.community.impl.xml b/python/pluginResources/intellij.python.community.impl.xml index 064722fd2ef2..ec44c81bb654 100644 --- a/python/pluginResources/intellij.python.community.impl.xml +++ b/python/pluginResources/intellij.python.community.impl.xml @@ -891,8 +891,10 @@ + - + + diff --git a/python/services/system-python/gen/com/intellij/python/community/services/systemPython/PythonCommunityServicesSystemPythonIcons.java b/python/services/system-python/gen/com/intellij/python/community/services/systemPython/PythonCommunityServicesSystemPythonIcons.java index 1a842014212c..0a02da9a5a6a 100644 --- a/python/services/system-python/gen/com/intellij/python/community/services/systemPython/PythonCommunityServicesSystemPythonIcons.java +++ b/python/services/system-python/gen/com/intellij/python/community/services/systemPython/PythonCommunityServicesSystemPythonIcons.java @@ -14,6 +14,7 @@ public final class PythonCommunityServicesSystemPythonIcons { private static @NotNull Icon load(@NotNull String path, int cacheKey, int flags) { return IconManager.getInstance().loadRasterizedIcon(path, PythonCommunityServicesSystemPythonIcons.class.getClassLoader(), cacheKey, flags); } + /** 16x16 */ public static final @NotNull Icon Asdf = load("icons/com/intellij/python/community/system/providers/expui/asdf.svg", 1124514615, 0); /** 16x16 */ public static final @NotNull Icon Homebrew = load("icons/com/intellij/python/community/system/providers/expui/homebrew.svg", -2104807435, 0); /** 16x16 */ public static final @NotNull Icon Pyenv = load("icons/com/intellij/python/community/system/providers/expui/pyenv.svg", -770384196, 0); } diff --git a/python/services/system-python/resources/icons/com/intellij/python/community/system/providers/expui/asdf.svg b/python/services/system-python/resources/icons/com/intellij/python/community/system/providers/expui/asdf.svg new file mode 100644 index 000000000000..4d5c85c54cc9 --- /dev/null +++ b/python/services/system-python/resources/icons/com/intellij/python/community/system/providers/expui/asdf.svg @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + asdf + + + + + \ No newline at end of file diff --git a/python/services/system-python/src/com/intellij/python/community/services/systemPython/impl/providers/AsdfSystemProvider.kt b/python/services/system-python/src/com/intellij/python/community/services/systemPython/impl/providers/AsdfSystemProvider.kt new file mode 100644 index 000000000000..d1b821a48188 --- /dev/null +++ b/python/services/system-python/src/com/intellij/python/community/services/systemPython/impl/providers/AsdfSystemProvider.kt @@ -0,0 +1,64 @@ +// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +package com.intellij.python.community.services.systemPython.impl.providers + +import com.intellij.openapi.diagnostic.Logger +import com.intellij.platform.eel.EelApi +import com.intellij.platform.eel.getOrNull +import com.intellij.platform.eel.path.EelPath +import com.intellij.platform.eel.provider.asNioPath +import com.intellij.python.community.services.shared.UICustomization +import com.intellij.python.community.services.systemPython.PythonCommunityServicesSystemPythonIcons +import com.intellij.python.community.services.systemPython.SystemPythonProvider +import com.jetbrains.python.PythonBinary +import com.jetbrains.python.errorProcessing.PyResult +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext + + +private class AsdfSystemPythonProvider : SystemPythonProvider { + private val LOGGER: Logger = Logger.getInstance(AsdfSystemPythonProvider::class.java) + + override suspend fun findSystemPythons(eelApi: EelApi): PyResult> { + if (useLegacyPythonProvider()) { + return PyResult.success(emptySet()) + } + + val pythons = withContext(Dispatchers.IO) { + try { + val env = eelApi.exec.fetchLoginShellEnvVariables() + val asdfRoot = if ("ASDF_DATA_DIR" in env) { + EelPath.parse(env["ASDF_DATA_DIR"]!!, eelApi.descriptor) + } + else { + eelApi.userInfo.home.resolve(".asdf") + } + + val versionsDir = asdfRoot.resolve("installs").resolve("python") + val entries = eelApi.fs.listDirectory(versionsDir) + .getOrNull() + + if (entries == null) { + return@withContext emptySet() + } + + val paths = entries + .map { versionsDir.resolve(it).resolve("bin").asNioPath() } + + return@withContext collectPythonsInPaths(eelApi, paths, listOf(python3NamePattern)) + } + catch (e: RuntimeException) { + LOGGER.error("failed to discover asdf pythons", e) + } + + return@withContext emptySet() + } + + return PyResult.success(pythons) + } + + override val uiCustomization: UICustomization? + get() { + // TODO: proper icon + return UICustomization(title = "asdf", icon = PythonCommunityServicesSystemPythonIcons.Asdf) + } +} \ No newline at end of file