EDU-667 Wrong working directory for "Run Study Tests" configuration
[idea/community.git] / python / educational-python / course-creator-python / src / com / jetbrains / edu / coursecreator / run / PyCCCommandLineState.java
1 package com.jetbrains.edu.coursecreator.run;
2
3 import com.intellij.execution.ExecutionException;
4 import com.intellij.execution.ExecutionResult;
5 import com.intellij.execution.Executor;
6 import com.intellij.execution.configurations.GeneralCommandLine;
7 import com.intellij.execution.configurations.ParamsGroup;
8 import com.intellij.execution.process.ProcessAdapter;
9 import com.intellij.execution.process.ProcessEvent;
10 import com.intellij.execution.process.ProcessHandler;
11 import com.intellij.execution.runners.ExecutionEnvironment;
12 import com.intellij.openapi.application.ApplicationManager;
13 import com.intellij.openapi.fileEditor.impl.text.TextEditorProvider;
14 import com.intellij.openapi.project.Project;
15 import com.intellij.openapi.util.io.FileUtil;
16 import com.intellij.openapi.vfs.LocalFileSystem;
17 import com.intellij.openapi.vfs.VirtualFile;
18 import com.jetbrains.edu.coursecreator.CCUtils;
19 import com.jetbrains.edu.learning.StudyTaskManager;
20 import com.jetbrains.edu.learning.StudyUtils;
21 import com.jetbrains.edu.learning.checker.StudyCheckUtils;
22 import com.jetbrains.edu.learning.core.EduNames;
23 import com.jetbrains.edu.learning.core.EduUtils;
24 import com.jetbrains.edu.learning.courseFormat.Course;
25 import com.jetbrains.edu.learning.courseFormat.Task;
26 import com.jetbrains.edu.learning.courseFormat.TaskFile;
27 import com.jetbrains.python.run.CommandLinePatcher;
28 import com.jetbrains.python.run.PythonCommandLineState;
29 import org.jetbrains.annotations.Nullable;
30
31 import java.io.File;
32 import java.util.Map;
33
34 public class PyCCCommandLineState extends PythonCommandLineState {
35   private final PyCCRunTestConfiguration myRunConfiguration;
36   private final VirtualFile myTaskDir;
37   private final Task myTask;
38
39   public PyCCCommandLineState(PyCCRunTestConfiguration runConfiguration,
40                               ExecutionEnvironment env) {
41     super(runConfiguration, env);
42     myRunConfiguration = runConfiguration;
43
44     VirtualFile testsFile = LocalFileSystem.getInstance().findFileByPath(myRunConfiguration.getPathToTest());
45     assert testsFile != null;
46     myTaskDir = StudyUtils.getTaskDir(testsFile);
47     assert myTaskDir != null;
48     myTask = StudyUtils.getTask(myRunConfiguration.getProject(), myTaskDir);
49     assert myTask != null;
50   }
51
52   @Override
53   protected void buildCommandLineParameters(GeneralCommandLine commandLine) {
54     commandLine.setWorkDirectory(myTaskDir.getPath());
55     ParamsGroup group = commandLine.getParametersList().getParamsGroup(GROUP_SCRIPT);
56     assert group != null;
57
58     Project project = myRunConfiguration.getProject();
59     Course course = StudyTaskManager.getInstance(project).getCourse();
60     assert course != null;
61
62     group.addParameter(myRunConfiguration.getPathToTest());
63     group.addParameter(new File(course.getCourseDirectory()).getPath());
64
65     String path = getFirstTaskFilePath();
66     if (path != null) {
67       group.addParameter(path);
68     }
69   }
70
71   @Nullable
72   private String getFirstTaskFilePath() {
73     for (Map.Entry<String, TaskFile> entry : myTask.getTaskFiles().entrySet()) {
74       String path = getTaskFilePath(entry.getKey());
75       if (!entry.getValue().getAnswerPlaceholders().isEmpty()) {
76         return path;
77       }
78       VirtualFile virtualFile = LocalFileSystem.getInstance().findFileByPath(path);
79       if (virtualFile == null) {
80         continue;
81       }
82       if (TextEditorProvider.isTextFile(virtualFile)) {
83         return path;
84       }
85     }
86     return null;
87   }
88
89
90   private String getTaskFilePath(String name) {
91     String taskDirPath = FileUtil.toSystemDependentName(myTaskDir.getPath());
92     return myTaskDir.findChild(EduNames.SRC) != null ?
93            FileUtil.join(taskDirPath, EduNames.SRC, name) :
94            FileUtil.join(taskDirPath, name);
95   }
96
97   @Override
98   public ExecutionResult execute(Executor executor, CommandLinePatcher... patchers) throws ExecutionException {
99     CCUtils.createResources(myRunConfiguration.getProject(), myTask, myTaskDir);
100     ApplicationManager.getApplication().runWriteAction(() -> StudyCheckUtils.flushWindows(myTask, myTaskDir));
101
102     return super.execute(executor, patchers);
103   }
104
105   @Override
106   protected ProcessHandler doCreateProcess(GeneralCommandLine commandLine) throws ExecutionException {
107     ProcessHandler handler = super.doCreateProcess(commandLine);
108     handler.addProcessListener(new ProcessAdapter() {
109       @Override
110       public void processTerminated(ProcessEvent event) {
111         ApplicationManager.getApplication().invokeLater(() -> EduUtils.deleteWindowDescriptions(myTask, myTaskDir));
112       }
113     });
114     return handler;
115   }
116 }