208f30bb0097e8489a2948663236ea80d64b708c
[idea/community.git] / python / src / com / jetbrains / python / run / PythonScriptCommandLineState.java
1 /*
2  * Copyright 2000-2016 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.run;
17
18 import com.google.common.collect.Lists;
19 import com.intellij.execution.DefaultExecutionResult;
20 import com.intellij.execution.ExecutionException;
21 import com.intellij.execution.ExecutionResult;
22 import com.intellij.execution.Executor;
23 import com.intellij.execution.configurations.GeneralCommandLine;
24 import com.intellij.execution.configurations.ParametersList;
25 import com.intellij.execution.configurations.ParamsGroup;
26 import com.intellij.execution.console.ConsoleExecuteAction;
27 import com.intellij.execution.executors.DefaultDebugExecutor;
28 import com.intellij.execution.runners.ExecutionEnvironment;
29 import com.intellij.openapi.actionSystem.AnAction;
30 import com.intellij.openapi.project.Project;
31 import com.intellij.openapi.projectRoots.Sdk;
32 import com.intellij.openapi.util.text.StringUtil;
33 import com.intellij.util.ArrayUtil;
34 import com.jetbrains.python.PythonHelper;
35 import com.jetbrains.python.console.PyConsoleOptions;
36 import com.jetbrains.python.console.PyConsoleType;
37 import com.jetbrains.python.console.PydevConsoleRunnerImpl;
38 import com.jetbrains.python.console.actions.ShowVarsAction;
39 import com.jetbrains.python.sdk.PythonEnvUtil;
40 import org.jetbrains.annotations.NotNull;
41 import org.jetbrains.annotations.Nullable;
42
43 import java.util.List;
44 import java.util.Map;
45
46 import static com.intellij.execution.runners.AbstractConsoleRunnerWithHistory.registerActionShortcuts;
47
48 /**
49  * @author yole
50  */
51 public class PythonScriptCommandLineState extends PythonCommandLineState {
52   private final PythonRunConfiguration myConfig;
53
54   public PythonScriptCommandLineState(PythonRunConfiguration runConfiguration, ExecutionEnvironment env) {
55     super(runConfiguration, env);
56     myConfig = runConfiguration;
57   }
58
59   @Override
60   public ExecutionResult execute(Executor executor, final CommandLinePatcher... patchers) throws ExecutionException {
61     if (myConfig.showCommandLineAfterwards()) {
62       if (executor.getId() == DefaultDebugExecutor.EXECUTOR_ID) {
63         return super.execute(executor, ArrayUtil.append(patchers, new CommandLinePatcher() {
64           @Override
65           public void patchCommandLine(GeneralCommandLine commandLine) {
66             commandLine.getParametersList().getParamsGroup(PythonCommandLineState.GROUP_DEBUGGER).addParameterAt(1, "--cmd-line");
67           }
68         }));
69       }
70
71       PythonScriptWithConsoleRunner runner =
72         new PythonScriptWithConsoleRunner(myConfig.getProject(), myConfig.getSdk(), PyConsoleType.PYTHON, myConfig.getWorkingDirectory(),
73                                           myConfig.getEnvs(), patchers,
74                                           PyConsoleOptions.getInstance(myConfig.getProject()).getPythonConsoleSettings());
75
76       runner.setEnableAfterConnection(false);
77       runner.runSync();
78       // runner.getProcessHandler() would be null if execution error occurred
79       if (runner.getProcessHandler() == null) {
80         return null;
81       }
82       runner.getPydevConsoleCommunication().setConsoleView(runner.getConsoleView());
83       List<AnAction> actions = Lists.newArrayList(createActions(runner.getConsoleView(), runner.getProcessHandler()));
84       actions.add(new ShowVarsAction(runner.getConsoleView(), runner.getPydevConsoleCommunication()));
85
86       return new DefaultExecutionResult(runner.getConsoleView(), runner.getProcessHandler(), actions.toArray(new AnAction[actions.size()]));
87     }
88     else {
89       return super.execute(executor, patchers);
90     }
91   }
92
93   @Override
94   protected void buildCommandLineParameters(GeneralCommandLine commandLine) {
95     ParametersList parametersList = commandLine.getParametersList();
96     ParamsGroup exe_options = parametersList.getParamsGroup(GROUP_EXE_OPTIONS);
97     assert exe_options != null;
98     exe_options.addParametersString(myConfig.getInterpreterOptions());
99
100     ParamsGroup script_parameters = parametersList.getParamsGroup(GROUP_SCRIPT);
101     assert script_parameters != null;
102     if (!StringUtil.isEmptyOrSpaces(myConfig.getScriptName())) {
103       script_parameters.addParameter(myConfig.getScriptName());
104     }
105
106     final String script_options_string = myConfig.getScriptParameters();
107     if (script_options_string != null) script_parameters.addParametersString(script_options_string);
108
109     if (!StringUtil.isEmptyOrSpaces(myConfig.getWorkingDirectory())) {
110       commandLine.setWorkDirectory(myConfig.getWorkingDirectory());
111     }
112   }
113
114   /**
115    * @author traff
116    */
117   public class PythonScriptWithConsoleRunner extends PydevConsoleRunnerImpl {
118
119     private CommandLinePatcher[] myPatchers;
120     private String PYDEV_RUN_IN_CONSOLE_PY = "pydev/pydev_run_in_console.py";
121
122     public PythonScriptWithConsoleRunner(@NotNull Project project,
123                                          @NotNull Sdk sdk,
124                                          @NotNull PyConsoleType consoleType,
125                                          @Nullable String workingDir,
126                                          Map<String, String> environmentVariables,
127                                          CommandLinePatcher[] patchers,
128                                          PyConsoleOptions.PyConsoleSettings consoleSettings,
129                                          String... statementsToExecute) {
130       super(project, sdk, consoleType, workingDir, environmentVariables, consoleSettings, (s) -> {}, statementsToExecute);
131       myPatchers = patchers;
132     }
133
134     @Override
135     protected void createContentDescriptorAndActions() {
136       AnAction a = new ConsoleExecuteAction(super.getConsoleView(), myConsoleExecuteActionHandler,
137                                             myConsoleExecuteActionHandler.getEmptyExecuteAction(), myConsoleExecuteActionHandler);
138       registerActionShortcuts(Lists.newArrayList(a), getConsoleView().getConsoleEditor().getComponent());
139     }
140
141     @Override
142     protected String getRunnerFileFromHelpers() {
143       return PYDEV_RUN_IN_CONSOLE_PY;
144     }
145
146     @Override
147     protected GeneralCommandLine createCommandLine(@NotNull Sdk sdk,
148                                                    @NotNull Map<String, String> environmentVariables,
149                                                    String workingDir, int[] ports) {
150       GeneralCommandLine consoleCmdLine = doCreateConsoleCmdLine(sdk, environmentVariables, workingDir, ports, PythonHelper.RUN_IN_CONSOLE);
151
152       final GeneralCommandLine cmd = generateCommandLine(myPatchers);
153
154       ParamsGroup group = consoleCmdLine.getParametersList().getParamsGroup(PythonCommandLineState.GROUP_SCRIPT);
155       assert group != null;
156       group.addParameters(cmd.getParametersList().getList());
157
158       PythonEnvUtil.mergePythonPath(consoleCmdLine.getEnvironment(), cmd.getEnvironment());
159
160       consoleCmdLine.getEnvironment().putAll(cmd.getEnvironment());
161
162       return consoleCmdLine;
163     }
164   }
165 }