From bee7e763ed941938400ea982d276dd71f50667a0 Mon Sep 17 00:00:00 2001 From: Andrey Vlasovskikh Date: Wed, 17 Aug 2016 19:53:10 +0300 Subject: [PATCH] Use SDK name as key for maps of Python SDKs during paths update (PY-20263) The name of SDK is unique while home path previously used for lookup in String to Sdk maps isn't. We cannot disable adding several interpreters with the same home path since it should work at least for the Python plugin the way it works for Java SDKs. --- .../jetbrains/python/sdk/PythonSdkType.java | 11 ++- .../python/sdk/PythonSdkUpdater.java | 67 ++++++++++--------- 2 files changed, 45 insertions(+), 33 deletions(-) diff --git a/python/src/com/jetbrains/python/sdk/PythonSdkType.java b/python/src/com/jetbrains/python/sdk/PythonSdkType.java index 0168643ea879..f4c026c3f6a9 100644 --- a/python/src/com/jetbrains/python/sdk/PythonSdkType.java +++ b/python/src/com/jetbrains/python/sdk/PythonSdkType.java @@ -118,7 +118,6 @@ public final class PythonSdkType extends SdkType { super("Python SDK"); } - public Icon getIcon() { return PythonIcons.Python.Python; } @@ -906,5 +905,15 @@ public final class PythonSdkType extends SdkType { } return ModuleRootManager.getInstance(module).getSdk(); } + + @NotNull + public static String getSdkKey(@NotNull Sdk sdk) { + return sdk.getName(); + } + + @Nullable + public static Sdk findSdkByKey(@NotNull String key) { + return ProjectJdkTable.getInstance().findJdk(key); + } } diff --git a/python/src/com/jetbrains/python/sdk/PythonSdkUpdater.java b/python/src/com/jetbrains/python/sdk/PythonSdkUpdater.java index 2b83cca6486d..a9d7b5b7fd9f 100644 --- a/python/src/com/jetbrains/python/sdk/PythonSdkUpdater.java +++ b/python/src/com/jetbrains/python/sdk/PythonSdkUpdater.java @@ -36,7 +36,6 @@ import com.intellij.openapi.projectRoots.SdkModificator; import com.intellij.openapi.roots.OrderRootType; import com.intellij.openapi.startup.StartupActivity; import com.intellij.openapi.ui.Messages; -import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.io.FileUtilRt; import com.intellij.openapi.vfs.StandardFileSystems; import com.intellij.openapi.vfs.VirtualFile; @@ -112,9 +111,9 @@ public class PythonSdkUpdater implements StartupActivity { */ public static boolean update(@NotNull Sdk sdk, @Nullable SdkModificator sdkModificator, @Nullable final Project project, @Nullable final Component ownerComponent) { - final String homePath = sdk.getHomePath(); + final String key = PythonSdkType.getSdkKey(sdk); synchronized (ourLock) { - ourScheduledToRefresh.add(homePath); + ourScheduledToRefresh.add(key); } if (!updateLocalSdkPaths(sdk, sdkModificator)) { return false; @@ -132,34 +131,35 @@ public class PythonSdkUpdater implements StartupActivity { @SuppressWarnings("ThrowableInstanceNeverThrown") final Throwable methodCallStacktrace = new Throwable(); application.invokeLater(() -> { synchronized (ourLock) { - if (!ourScheduledToRefresh.contains(homePath)) { + if (!ourScheduledToRefresh.contains(key)) { return; } - ourScheduledToRefresh.remove(homePath); + ourScheduledToRefresh.remove(key); } ProgressManager.getInstance().run(new Task.Backgroundable(project, PyBundle.message("sdk.gen.updating.interpreter"), false) { @Override public void run(@NotNull ProgressIndicator indicator) { final Project project1 = getProject(); - final Sdk sdk12 = PythonSdkType.findSdkByPath(homePath); - if (sdk12 != null) { - ourUnderRefresh.put(homePath); + final Sdk sdkInsideTask = PythonSdkType.findSdkByKey(key); + if (sdkInsideTask != null) { + ourUnderRefresh.put(key); try { - final String skeletonsPath = getBinarySkeletonsPath(homePath); + final String skeletonsPath = getBinarySkeletonsPath(key); try { - if (PythonSdkType.isRemote(sdk12) && project1 == null && ownerComponent == null) { + if (PythonSdkType.isRemote(sdkInsideTask) && project1 == null && ownerComponent == null) { LOG.error("For refreshing skeletons of remote SDK, either project or owner component must be specified"); } - LOG.info("Performing background update of skeletons for SDK " + sdk12.getHomePath()); + final String sdkPresentableName = getSdkPresentableName(sdk); + LOG.info("Performing background update of skeletons for SDK " + sdkPresentableName); indicator.setText("Updating skeletons..."); - PySkeletonRefresher.refreshSkeletonsOfSdk(project1, ownerComponent, skeletonsPath, sdk12); - updateRemoteSdkPaths(sdk12); + PySkeletonRefresher.refreshSkeletonsOfSdk(project1, ownerComponent, skeletonsPath, sdkInsideTask); + updateRemoteSdkPaths(sdkInsideTask); indicator.setIndeterminate(true); indicator.setText("Scanning installed packages..."); indicator.setText2(""); - LOG.info("Performing background scan of packages for SDK " + sdk12.getHomePath()); + LOG.info("Performing background scan of packages for SDK " + sdkPresentableName); try { - PyPackageManager.getInstance(sdk12).refreshAndGetPackages(true); + PyPackageManager.getInstance(sdkInsideTask).refreshAndGetPackages(true); } catch (ExecutionException e) { if (LOG.isDebugEnabled()) { @@ -172,28 +172,28 @@ public class PythonSdkUpdater implements StartupActivity { } } catch (InvalidSdkException e) { - if (PythonSdkType.isVagrant(sdk12) + if (PythonSdkType.isVagrant(sdkInsideTask) || new CredentialsTypeExChecker() { @Override protected boolean checkLanguageContribution(PyCredentialsContribution languageContribution) { return languageContribution.shouldNotifySdkSkeletonFail(); } - }.check(sdk12)) { + }.check(sdkInsideTask)) { PythonSdkType.notifyRemoteSdkSkeletonsFail(e, () -> { - final Sdk sdk1 = PythonSdkType.findSdkByPath(homePath); - if (sdk1 != null) { - update(sdk1, null, project1, ownerComponent); + final Sdk sdkInsideNotify = PythonSdkType.findSdkByKey(key); + if (sdkInsideNotify != null) { + update(sdkInsideNotify, null, project1, ownerComponent); } }); } - else if (!PythonSdkType.isInvalid(sdk12)) { + else if (!PythonSdkType.isInvalid(sdkInsideTask)) { LOG.error(e); } } } finally { try { - ourUnderRefresh.remove(homePath); + ourUnderRefresh.remove(key); } catch (IllegalStateException e) { LOG.error(e); @@ -215,10 +215,8 @@ public class PythonSdkUpdater implements StartupActivity { @Nullable Component ownerComponent) { final boolean success = update(sdk, sdkModificator, project, ownerComponent); if (!success) { - final String homePath = sdk.getHomePath(); - final String sdkName = homePath != null ? homePath : sdk.getName(); Messages.showErrorDialog(project, - PyBundle.message("MSG.cant.setup.sdk.$0", FileUtil.toSystemDependentName(sdkName)), + PyBundle.message("MSG.cant.setup.sdk.$0", getSdkPresentableName(sdk)), PyBundle.message("MSG.title.bad.sdk")); } } @@ -363,19 +361,24 @@ public class PythonSdkUpdater implements StartupActivity { final VirtualFile skeletonsDir = StandardFileSystems.local().refreshAndFindFileByPath(skeletonsPath); if (skeletonsDir != null) { results.add(skeletonsDir); - LOG.info("Binary skeletons directory for SDK \"" + sdk.getName() + "\" (" + sdk.getHomePath() + "): " + - skeletonsDir.getPath()); + LOG.info("Binary skeletons directory for SDK " + getSdkPresentableName(sdk) + "): " + skeletonsDir.getPath()); } } final VirtualFile userSkeletonsDir = PyUserSkeletonsUtil.getUserSkeletonsDirectory(); if (userSkeletonsDir != null) { results.add(userSkeletonsDir); - LOG.info("User skeletons directory for SDK \"" + sdk.getName() + "\" (" + sdk.getHomePath() + "): " + - userSkeletonsDir.getPath()); + LOG.info("User skeletons directory for SDK " + getSdkPresentableName(sdk) + "): " + userSkeletonsDir.getPath()); } return results; } + @NotNull + private static String getSdkPresentableName(@NotNull Sdk sdk) { + final String homePath = sdk.getHomePath(); + final String name = sdk.getName(); + return homePath != null ? name + " (" + homePath + ")" : name; + } + @Nullable private static String getBinarySkeletonsPath(@Nullable String path) { return path != null ? PythonSdkType.getSkeletonsPath(PathManager.getSystemPath(), path) : null; @@ -406,14 +409,14 @@ public class PythonSdkUpdater implements StartupActivity { @Nullable final SdkModificator sdkModificator, @NotNull final List sdkPaths, boolean forceCommit) { - final String homePath = sdk.getHomePath(); + final String key = PythonSdkType.getSdkKey(sdk); final SdkModificator modificatorToGetRoots = sdkModificator != null ? sdkModificator : sdk.getSdkModificator(); final List currentSdkPaths = Arrays.asList(modificatorToGetRoots.getRoots(OrderRootType.CLASSES)); if (forceCommit || !Sets.newHashSet(sdkPaths).equals(Sets.newHashSet(currentSdkPaths))) { ApplicationManager.getApplication().invokeAndWait(() -> { - final Sdk sdk1 = PythonSdkType.findSdkByPath(homePath); + final Sdk sdkInsideInvoke = PythonSdkType.findSdkByKey(key); final SdkModificator modificatorToCommit = sdkModificator != null ? sdkModificator : - sdk1 != null ? sdk1.getSdkModificator() : modificatorToGetRoots; + sdkInsideInvoke != null ? sdkInsideInvoke.getSdkModificator() : modificatorToGetRoots; modificatorToCommit.removeAllRoots(); for (VirtualFile sdkPath : sdkPaths) { modificatorToCommit.addRoot(PythonSdkType.getSdkRootVirtualFile(sdkPath), OrderRootType.CLASSES);