fixed PY-17789, PY-17777, PY-17723

Do not store sdk cache before it's setup, clear package cache on sdk editing
This commit is contained in:
Ekaterina Tuzova
2015-11-25 16:49:39 +03:00
parent 32719842e5
commit 51cc16fa13
6 changed files with 51 additions and 45 deletions
@@ -51,6 +51,7 @@ import com.intellij.util.NullableFunction;
import com.intellij.util.PathMappingSettings;
import com.intellij.util.containers.FactoryMap;
import com.jetbrains.python.PyBundle;
import com.jetbrains.python.packaging.PyPackageManagers;
import com.jetbrains.python.remote.PyRemoteSdkAdditionalDataBase;
import com.jetbrains.python.remote.PyRemoteSourceItem;
import com.jetbrains.python.remote.PythonRemoteInterpreterManager;
@@ -229,7 +230,9 @@ public class PythonSdkDetailsDialog extends DialogWrapper {
myModificators.clear();
myModifiedModificators.clear();
mySdkListChanged = false;
myShowMoreCallback.consume(getSelectedSdk());
final Sdk sdk = getSelectedSdk();
myShowMoreCallback.consume(sdk);
PyPackageManagers.getInstance().clearCache(sdk);
Disposer.dispose(getDisposable());
}
@@ -35,4 +35,6 @@ public abstract class PyPackageManagers {
public abstract PyPackageManager forSdk(Sdk sdk);
public abstract PackageManagementService getManagementService(Project project, Sdk sdk);
public abstract void clearCache(@NotNull final Sdk sdk);
}
@@ -38,8 +38,8 @@ import java.util.*;
public class PyCondaPackageManagerImpl extends PyPackageManagerImpl {
public static final String PYTHON = "python";
PyCondaPackageManagerImpl(@NotNull final String sdkHomePath) {
super(sdkHomePath);
PyCondaPackageManagerImpl(@NotNull final Sdk sdk) {
super(sdk);
}
@Override
@@ -50,9 +50,6 @@ public class PyCondaPackageManagerImpl extends PyPackageManagerImpl {
@Override
public boolean hasManagement(boolean cachedOnly) throws ExecutionException {
final Sdk sdk = getSdk();
if (sdk == null) {
throw new ExecutionException("Failed to find interpreter \"" + mySdkHomePath + "\"");
}
return isCondaVEnv(sdk);
}
@@ -78,14 +75,12 @@ public class PyCondaPackageManagerImpl extends PyPackageManagerImpl {
private ProcessOutput getCondaOutput(@NotNull final String command, List<String> arguments) throws ExecutionException {
final Sdk sdk = getSdk();
if (sdk == null) {
throw new ExecutionException("Failed to find interpreter \"" + mySdkHomePath + "\"");
}
final String condaExecutable = PyCondaPackageService.getCondaExecutable(sdk.getHomeDirectory());
if (condaExecutable == null) throw new PyExecutionException("Cannot find conda", "Conda", Collections.<String>emptyList(), new ProcessOutput());
final String path = getCondaDirectory();
if (path == null) throw new PyExecutionException("Empty conda name for \"" + mySdkHomePath + "\"", command, arguments);
if (path == null) throw new PyExecutionException("Empty conda name for " + sdk.getHomePath(), command, arguments);
final ArrayList<String> parameters = Lists.newArrayList(condaExecutable, command, "-p", path);
parameters.addAll(arguments);
@@ -114,11 +109,7 @@ public class PyCondaPackageManagerImpl extends PyPackageManagerImpl {
@Nullable
private String getCondaDirectory() {
final Sdk sdk = getSdk();
if (sdk == null) {
return null;
}
final VirtualFile homeDirectory = sdk.getHomeDirectory();
final VirtualFile homeDirectory = getSdk().getHomeDirectory();
if (homeDirectory == null) return null;
if (SystemInfo.isWindows) return homeDirectory.getParent().getPath();
return homeDirectory.getParent().getParent().getPath();
@@ -85,7 +85,7 @@ public class PyPackageManagerImpl extends PyPackageManager {
private List<PyPackage> myPackagesCache = null;
private ExecutionException myExceptionCache = null;
protected final String mySdkHomePath;
@NotNull final private Sdk mySdk;
@Override
public void refresh() {
@@ -94,7 +94,6 @@ public class PyPackageManagerImpl extends PyPackageManager {
@Override
public void run() {
final Sdk sdk = getSdk();
if (sdk == null) return;
application.runWriteAction(new Runnable() {
@Override
public void run() {
@@ -111,9 +110,6 @@ public class PyPackageManagerImpl extends PyPackageManager {
@Override
public void installManagement() throws ExecutionException {
final Sdk sdk = getSdk();
if (sdk == null) {
throw new ExecutionException("Cannot install management packages for invalid interpreter " + mySdkHomePath);
}
final boolean pre26 = PythonSdkType.getLanguageLevelForSdk(sdk).isOlderThan(LanguageLevel.PYTHON26);
if (!hasSetuptools(false)) {
final String name = SETUPTOOLS + "-" + (pre26 ? SETUPTOOLS_PRE_26_VERSION : SETUPTOOLS_VERSION);
@@ -170,8 +166,8 @@ public class PyPackageManagerImpl extends PyPackageManager {
return findPackage(name, cachedOnly) != null;
}
PyPackageManagerImpl(@NotNull final String sdkHomePath) {
mySdkHomePath = sdkHomePath;
PyPackageManagerImpl(@NotNull final Sdk sdk) {
mySdk = sdk;
subscribeToLocalChanges();
}
@@ -181,9 +177,9 @@ public class PyPackageManagerImpl extends PyPackageManager {
connection.subscribe(VirtualFileManager.VFS_CHANGES, new MySdkRootWatcher());
}
@Nullable
@NotNull
public Sdk getSdk() {
return PythonSdkType.findSdkByPath(mySdkHomePath);
return mySdk;
}
@Override
@@ -334,8 +330,6 @@ public class PyPackageManagerImpl extends PyPackageManager {
public String createVirtualEnv(@NotNull String destinationDir, boolean useGlobalSite) throws ExecutionException {
final List<String> args = new ArrayList<String>();
final Sdk sdk = getSdk();
if (sdk == null) throw new ExecutionException("Cannot create virtual env in \"" + destinationDir +
"\". Invalid base interpreter " + mySdkHomePath);
final LanguageLevel languageLevel = PythonSdkType.getLanguageLevelForSdk(sdk);
final boolean usePyVenv = languageLevel.isAtLeast(LanguageLevel.PYTHON33);
if (usePyVenv) {
@@ -461,20 +455,23 @@ public class PyPackageManagerImpl extends PyPackageManager {
@NotNull
protected ProcessOutput getPythonProcessOutput(@NotNull String helperPath, @NotNull List<String> args, boolean askForSudo,
boolean showProgress, @Nullable String workingDir) throws ExecutionException {
final String homePath = getSdk().getHomePath();
if (homePath == null) {
throw new ExecutionException("Cannot find Python interpreter for SDK " + mySdk.getName());
}
if (workingDir == null) {
workingDir = new File(mySdkHomePath).getParent();
workingDir = new File(homePath).getParent();
}
final List<String> cmdline = new ArrayList<String>();
cmdline.add(mySdkHomePath);
cmdline.add(homePath);
cmdline.add(helperPath);
cmdline.addAll(args);
LOG.info("Running packaging tool: " + StringUtil.join(cmdline, " "));
final boolean canCreate = FileUtil.ensureCanCreateFile(new File(mySdkHomePath));
final boolean canCreate = FileUtil.ensureCanCreateFile(new File(homePath));
final boolean useSudo = !canCreate && !SystemInfo.isWindows && askForSudo;
try {
final Process process;
final Map<String, String> environment = new HashMap<String, String>(System.getenv());
PythonEnvUtil.setPythonUnbuffered(environment);
PythonEnvUtil.setPythonDontWriteBytecode(environment);
@@ -553,9 +550,6 @@ public class PyPackageManagerImpl extends PyPackageManager {
@Override
public void after(@NotNull List<? extends VFileEvent> events) {
final Sdk sdk = getSdk();
if (sdk == null) {
return;
}
final VirtualFile[] roots = sdk.getRootProvider().getFiles(OrderRootType.CLASSES);
for (VFileEvent event : events) {
final VirtualFile file = event.getFile();
@@ -19,6 +19,8 @@ import com.intellij.execution.ExecutionException;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.roots.OrderRootType;
import com.intellij.openapi.vfs.VirtualFile;
import com.jetbrains.python.packaging.ui.PyCondaManagementService;
import com.jetbrains.python.packaging.ui.PyPackageManagementService;
import com.jetbrains.python.psi.LanguageLevel;
@@ -47,19 +49,25 @@ public class PyPackageManagersImpl extends PyPackageManagers {
PyPackageManagerImpl manager = myInstances.get(homePath);
if (manager == null) {
if (PythonSdkType.isRemote(sdk)) {
manager = new PyRemotePackageManagerImpl(homePath);
manager = new PyRemotePackageManagerImpl(sdk);
}
else if (PyCondaPackageManagerImpl.isCondaVEnv(sdk) && PyCondaPackageService.getCondaExecutable(sdk.getHomeDirectory()) != null) {
manager = new PyCondaPackageManagerImpl(homePath);
manager = new PyCondaPackageManagerImpl(sdk);
}
else {
manager = new PyPackageManagerImpl(homePath);
manager = new PyPackageManagerImpl(sdk);
}
myInstances.put(homePath, manager);
if (sdkIsSetUp(sdk))
myInstances.put(homePath, manager);
}
return manager;
}
private static boolean sdkIsSetUp(@NotNull final Sdk sdk) {
final VirtualFile[] roots = sdk.getRootProvider().getFiles(OrderRootType.CLASSES);
return roots.length != 0;
}
public PyPackageManagementService getManagementService(Project project, Sdk sdk) {
if (PyCondaPackageManagerImpl.isCondaVEnv(sdk)) {
return new PyCondaManagementService(project, sdk);
@@ -67,6 +75,13 @@ public class PyPackageManagersImpl extends PyPackageManagers {
return new PyPackageManagementService(project, sdk);
}
@Override
public void clearCache(@NotNull Sdk sdk) {
if (myInstances.containsKey(sdk.getHomePath())) {
myInstances.remove(sdk.getHomePath());
}
}
static class DummyPackageManager extends PyPackageManager {
private final String myName;
private final LanguageLevel myLanguageLevel;
@@ -142,5 +157,5 @@ public class PyPackageManagersImpl extends PyPackageManagers {
throw new ExecutionException(getErrorMessage());
}
}
}
@@ -44,15 +44,15 @@ import java.util.List;
public class PyRemotePackageManagerImpl extends PyPackageManagerImpl {
private static final Logger LOG = Logger.getInstance(PyRemotePackageManagerImpl.class);
PyRemotePackageManagerImpl(@NotNull final String sdkHomePath) {
super(sdkHomePath);
PyRemotePackageManagerImpl(@NotNull final Sdk sdk) {
super(sdk);
}
@Nullable
@Override
protected String getHelperPath(String helper) throws ExecutionException {
final Sdk sdk = getSdk();
if (sdk == null) throw new ExecutionException("Failed to find helpers for invalid interpreter \"" + mySdkHomePath + "\"");
final SdkAdditionalData sdkData = sdk.getSdkAdditionalData();
if (sdkData instanceof PyRemoteSdkAdditionalDataBase) {
final PyRemoteSdkAdditionalDataBase remoteSdkData = (PyRemoteSdkAdditionalDataBase) sdkData;
@@ -89,8 +89,9 @@ public class PyRemotePackageManagerImpl extends PyPackageManagerImpl {
boolean askForSudo,
boolean showProgress, @Nullable final String workingDir) throws ExecutionException {
final Sdk sdk = getSdk();
if (sdk == null) {
throw new ExecutionException("Cannot find Python interpreter \"" + mySdkHomePath + "\"");
final String homePath = sdk.getHomePath();
if (homePath == null) {
throw new ExecutionException("Cannot find Python interpreter for SDK " + sdk.getName());
}
final SdkAdditionalData sdkData = sdk.getSdkAdditionalData();
if (sdkData instanceof PyRemoteSdkAdditionalDataBase) { //remote interpreter
@@ -120,8 +121,8 @@ public class PyRemotePackageManagerImpl extends PyPackageManagerImpl {
if (manager != null) {
final List<String> cmdline = new ArrayList<String>();
cmdline.add(mySdkHomePath);
cmdline.add(RemoteFile.detectSystemByPath(mySdkHomePath).createRemoteFile(helperPath).getPath());
cmdline.add(homePath);
cmdline.add(RemoteFile.detectSystemByPath(homePath).createRemoteFile(helperPath).getPath());
cmdline.addAll(Collections2.transform(args, new Function<String, String>() {
@Override
public String apply(@Nullable String input) {