Merge remote-tracking branch 'origin/master' into pycharm/docker
[idea/community.git] / python / src / com / jetbrains / python / remote / PythonRemoteInterpreterManager.java
1 /*
2  * Copyright 2000-2014 JetBrains s.r.o.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.jetbrains.python.remote;
17
18 import com.google.common.base.Function;
19 import com.intellij.execution.ExecutionException;
20 import com.intellij.execution.configurations.GeneralCommandLine;
21 import com.intellij.execution.configurations.ParamsGroup;
22 import com.intellij.execution.process.ProcessHandler;
23 import com.intellij.execution.process.ProcessOutput;
24 import com.intellij.openapi.extensions.ExtensionPointName;
25 import com.intellij.openapi.project.Project;
26 import com.intellij.openapi.projectRoots.Sdk;
27 import com.intellij.openapi.projectRoots.SdkAdditionalData;
28 import com.intellij.openapi.projectRoots.SdkModificator;
29 import com.intellij.openapi.util.Key;
30 import com.intellij.openapi.util.io.FileUtil;
31 import com.intellij.openapi.vfs.VirtualFile;
32 import com.intellij.remote.*;
33 import com.intellij.util.NullableConsumer;
34 import com.intellij.util.PathMapper;
35 import com.intellij.util.PathMappingSettings;
36 import com.jetbrains.python.PythonHelpersLocator;
37 import com.jetbrains.python.console.PyConsoleProcessHandler;
38 import com.jetbrains.python.console.PydevConsoleCommunication;
39 import com.jetbrains.python.console.PythonConsoleView;
40 import com.jetbrains.python.remote.PyRemotePathMapper.PyPathMappingType;
41 import com.jetbrains.python.sdk.skeletons.PySkeletonGenerator;
42 import org.jdom.Element;
43 import org.jetbrains.annotations.NotNull;
44 import org.jetbrains.annotations.Nullable;
45
46 import java.awt.*;
47 import java.nio.charset.Charset;
48 import java.util.Collection;
49 import java.util.List;
50
51 /**
52  * @author traff
53  */
54 public abstract class PythonRemoteInterpreterManager {
55   public final static ExtensionPointName<PythonRemoteInterpreterManager> EP_NAME =
56     ExtensionPointName.create("Pythonid.remoteInterpreterManager");
57   public static final String WEB_DEPLOYMENT_PLUGIN_IS_DISABLED =
58     "Remote interpreter can't be executed. Please enable the Remote Hosts Access plugin."; //TODO: this message is incorrect
59
60   public final static Key<PathMapper> PATH_MAPPING_SETTINGS_KEY = Key.create("PATH_MAPPING_SETTINGS_KEY");
61
62   /**
63    * @deprecated use {@link com.jetbrains.python.run.PyRemoteProcessStarterManager#startRemoteProcess(Project, GeneralCommandLine, PythonRemoteInterpreterManager, PyRemoteSdkAdditionalDataBase, PyRemotePathMapper)}
64    */
65   @Deprecated
66   public abstract ProcessHandler startRemoteProcess(@Nullable Project project,
67                                                     @NotNull PyRemoteSdkCredentials data,
68                                                     @NotNull GeneralCommandLine commandLine,
69                                                     @NotNull PyRemotePathMapper pathMapper)
70     throws RemoteSdkException;
71
72   /**
73    * @deprecated use {@link com.jetbrains.python.run.PyRemoteProcessStarterManager#startRemoteProcess(Project, GeneralCommandLine, PythonRemoteInterpreterManager, PyRemoteSdkAdditionalDataBase, PyRemotePathMapper)}
74    */
75   @Deprecated
76   public abstract ProcessHandler startRemoteProcessWithPid(@Nullable Project project,
77                                                            @NotNull PyRemoteSdkCredentials data,
78                                                            @NotNull GeneralCommandLine commandLine,
79                                                            @NotNull PyRemotePathMapper pathMapper)
80     throws RemoteSdkException;
81
82   public abstract void addRemoteSdk(Project project, Component parentComponent, Collection<Sdk> existingSdks,
83                                     NullableConsumer<Sdk> sdkCallback);
84
85
86   /**
87    * @deprecated use {@link com.jetbrains.python.run.PyRemoteProcessStarterManager#executeRemoteProcess(Project, String[], String, PythonRemoteInterpreterManager, PyRemoteSdkAdditionalDataBase, PyRemotePathMapper, boolean)}
88    */
89   public abstract ProcessOutput runRemoteProcess(@Nullable Project project,
90                                                  RemoteSdkCredentials data,
91                                                  @NotNull PyRemotePathMapper pathMapper,
92                                                  String[] command,
93                                                  @Nullable String workingDir,
94                                                  boolean askForSudo)
95     throws RemoteSdkException;
96
97   /**
98    * @deprecated use {@link com.jetbrains.python.run.PyRemoteProcessStarterManager#executeRemoteProcess(Project, String[], String, PythonRemoteInterpreterManager, PyRemoteSdkAdditionalDataBase, PyRemotePathMapper, boolean)}
99    */
100   @Deprecated
101   public abstract ProcessOutput runRemoteProcess(@Nullable Project project,
102                                                  RemoteSdkCredentials data,
103                                                  @NotNull PyRemotePathMapper pathMapper,
104                                                  String[] command,
105                                                  @Nullable String workingDir,
106                                                  boolean askForSudo, String sdkHomePath)
107     throws RemoteSdkException;
108
109   @NotNull
110   public abstract RemoteSshProcess createRemoteProcess(@Nullable Project project,
111                                                        @NotNull PyRemoteSdkCredentials data,
112                                                        @NotNull PyRemotePathMapper pathMapper,
113                                                        @NotNull GeneralCommandLine commandLine, boolean allocatePty)
114     throws RemoteSdkException;
115
116   public abstract boolean editSdk(@NotNull Project project, @NotNull SdkModificator sdkModificator, Collection<Sdk> existingSdks);
117
118   public abstract PySkeletonGenerator createRemoteSkeletonGenerator(@Nullable Project project,
119                                                                     @Nullable Component ownerComponent,
120                                                                     @NotNull Sdk sdk,
121                                                                     String path) throws ExecutionException;
122
123   public abstract boolean ensureCanWrite(@Nullable Object projectOrComponent, RemoteSdkCredentials data, String path);
124
125   @Nullable
126   public abstract RemoteProjectSettings showRemoteProjectSettingsDialog(VirtualFile baseDir, RemoteSdkCredentials data);
127
128   public abstract void createDeployment(Project project,
129                                         VirtualFile projectDir,
130                                         RemoteProjectSettings settings,
131                                         RemoteSdkCredentials data);
132
133   public abstract void copyFromRemote(Sdk sdk, @NotNull Project project,
134                                       RemoteSdkCredentials data,
135                                       List<PathMappingSettings.PathMapping> mappings);
136
137   @Nullable
138   public static PythonRemoteInterpreterManager getInstance() {
139     if (EP_NAME.getExtensions().length > 0) {
140       return EP_NAME.getExtensions()[0];
141     }
142     else {
143       return null;
144     }
145   }
146
147   public static void addUnbuffered(ParamsGroup exeGroup) {
148     for (String param : exeGroup.getParametersList().getParameters()) {
149       if ("-u".equals(param)) {
150         return;
151       }
152     }
153     exeGroup.addParameter("-u");
154   }
155
156   public static String toSystemDependent(String path, boolean isWin) {
157     char separator = isWin ? '\\' : '/';
158     return FileUtil.toSystemIndependentName(path).replace('/', separator);
159   }
160
161   public static void addHelpersMapping(@NotNull RemoteSdkProperties data, @NotNull PyRemotePathMapper pathMapper) {
162     pathMapper.addMapping(PythonHelpersLocator.getHelpersRoot().getPath(), data.getHelpersPath(), PyPathMappingType.HELPERS);
163   }
164
165   @NotNull
166   public abstract PyRemotePathMapper setupMappings(@Nullable Project project,
167                                                    @NotNull PyRemoteSdkAdditionalDataBase data,
168                                                    @Nullable PyRemotePathMapper pathMapper);
169
170   public abstract SdkAdditionalData loadRemoteSdkData(Sdk sdk, Element additional);
171
172   public abstract PyConsoleProcessHandler createConsoleProcessHandler(Process process,
173                                                                       PyRemoteSdkCredentials data,
174                                                                       PythonConsoleView view,
175                                                                       PydevConsoleCommunication consoleCommunication,
176                                                                       String commandLine, Charset charset, PyRemotePathMapper pathMapper);
177
178   @NotNull
179   public abstract RemoteSdkCredentialsProducer<PyRemoteSdkCredentials> getRemoteSdkCredentialsProducer(Function<RemoteCredentials, PyRemoteSdkCredentials> credentialsTransformer,
180                                                                                                        RemoteConnectionCredentialsWrapper connectionWrapper);
181
182   public abstract String getInterpreterVersion(@Nullable Project project, PyRemoteSdkAdditionalDataBase data) throws RemoteSdkException;
183
184   public static class PyRemoteInterpreterExecutionException extends ExecutionException {
185
186     public PyRemoteInterpreterExecutionException() {
187       super(WEB_DEPLOYMENT_PLUGIN_IS_DISABLED);
188     }
189   }
190
191   public static class PyRemoteInterpreterRuntimeException extends RuntimeException {
192
193     public PyRemoteInterpreterRuntimeException() {
194       super(WEB_DEPLOYMENT_PLUGIN_IS_DISABLED);
195     }
196   }
197
198   public abstract void runVagrant(@NotNull String vagrantFolder, @Nullable String machineName) throws ExecutionException;
199 }