1 package com.jetbrains.edu.learning.checker;
3 import com.intellij.execution.process.CapturingProcessHandler;
4 import com.intellij.execution.process.ProcessOutput;
5 import com.intellij.ide.projectView.ProjectView;
6 import com.intellij.openapi.application.ApplicationManager;
7 import com.intellij.openapi.diagnostic.Logger;
8 import com.intellij.openapi.progress.ProgressIndicator;
9 import com.intellij.openapi.project.Project;
10 import com.intellij.openapi.ui.MessageType;
11 import com.intellij.openapi.util.Ref;
12 import com.intellij.openapi.util.text.StringUtil;
13 import com.intellij.openapi.vfs.VirtualFile;
14 import com.jetbrains.edu.learning.core.EduUtils;
15 import com.jetbrains.edu.learning.courseFormat.StudyStatus;
16 import com.jetbrains.edu.learning.courseFormat.Task;
17 import com.jetbrains.edu.learning.StudyPluginConfigurator;
18 import com.jetbrains.edu.learning.StudyState;
19 import com.jetbrains.edu.learning.StudyTaskManager;
20 import com.jetbrains.edu.learning.StudyUtils;
21 import com.jetbrains.edu.learning.actions.StudyAfterCheckAction;
22 import com.jetbrains.edu.learning.EduStepicConnector;
23 import com.jetbrains.edu.learning.stepic.StudySettings;
24 import org.jetbrains.annotations.NotNull;
26 public class StudyCheckTask extends com.intellij.openapi.progress.Task.Backgroundable {
28 private static final Logger LOG = Logger.getInstance(StudyCheckTask.class);
29 private final Project myProject;
30 protected final StudyState myStudyState;
31 protected final Task myTask;
32 protected final VirtualFile myTaskDir;
33 protected final StudyTaskManager myTaskManger;
34 private final StudyStatus myStatusBeforeCheck;
35 private Ref<Boolean> myCheckInProcess;
36 private final Process myTestProcess;
37 private final String myCommandLine;
39 public StudyCheckTask(Project project, StudyState studyState, Ref<Boolean> checkInProcess, Process testProcess, String commandLine) {
40 super(project, "Checking Task");
42 myStudyState = studyState;
43 myCheckInProcess = checkInProcess;
44 myTestProcess = testProcess;
45 myCommandLine = commandLine;
46 myTask = studyState.getTask();
47 myTaskDir = studyState.getTaskDir();
48 myTaskManger = StudyTaskManager.getInstance(myProject);
49 myStatusBeforeCheck = myTaskManger.getStatus(myTask);
53 public void onSuccess() {
54 StudyUtils.updateToolWindows(myProject);
55 StudyCheckUtils.drawAllPlaceholders(myProject, myTask, myTaskDir);
56 ProjectView.getInstance(myProject).refresh();
60 protected void clearState() {
61 EduUtils.deleteWindowDescriptions(myTask, myTaskDir);
62 myCheckInProcess.set(false);
66 public void onCancel() {
67 myTaskManger.setStatus(myTask, myStatusBeforeCheck);
72 public void run(@NotNull ProgressIndicator indicator) {
73 final CapturingProcessHandler handler = new CapturingProcessHandler(myTestProcess, null, myCommandLine);
74 final ProcessOutput output = handler.runProcessWithProgressIndicator(indicator);
75 if (indicator.isCanceled()) {
76 ApplicationManager.getApplication().invokeLater(
77 () -> StudyCheckUtils.showTestResultPopUp("Check cancelled", MessageType.WARNING.getPopupBackground(), myProject));
82 final StudyTestsOutputParser.TestsOutput testsOutput = StudyTestsOutputParser.getTestsOutput(output);
83 String stderr = output.getStderr();
84 if (!stderr.isEmpty()) {
85 ApplicationManager.getApplication().invokeLater(() ->
86 StudyCheckUtils.showTestResultPopUp("Failed to launch checking",
87 MessageType.WARNING.getPopupBackground(),
89 //log error output of tests
90 LOG.info("#educational " + stderr);
94 postAttemptToStepic(testsOutput);
97 if (testsOutput.isSuccess()) {
98 onTaskSolved(testsOutput);
101 onTaskFailed(testsOutput);
103 runAfterTaskSolvedActions();
106 protected void onTaskFailed(StudyTestsOutputParser.TestsOutput testsOutput) {
107 myTaskManger.setStatus(myTask, StudyStatus.Failed);
108 ApplicationManager.getApplication().invokeLater(
109 () -> StudyCheckUtils.showTestResultPopUp(testsOutput.getMessage(), MessageType.ERROR.getPopupBackground(), myProject));
112 protected void onTaskSolved(StudyTestsOutputParser.TestsOutput testsOutput) {
113 myTaskManger.setStatus(myTask, StudyStatus.Solved);
114 ApplicationManager.getApplication().invokeLater(
115 () -> StudyCheckUtils.showTestResultPopUp(testsOutput.getMessage(), MessageType.INFO.getPopupBackground(), myProject));
118 private void runAfterTaskSolvedActions() {
119 StudyPluginConfigurator configurator = StudyUtils.getConfigurator(myProject);
120 if (configurator != null) {
121 StudyAfterCheckAction[] checkActions = configurator.getAfterCheckActions();
122 if (checkActions != null) {
123 for (StudyAfterCheckAction action: checkActions) {
124 action.run(myProject, myTask, myStatusBeforeCheck);
130 protected void postAttemptToStepic(StudyTestsOutputParser.TestsOutput testsOutput) {
131 final StudySettings studySettings = StudySettings.getInstance();
132 final String login = studySettings.getLogin();
133 final String password = StringUtil.isEmptyOrSpaces(login) ? "" : studySettings.getPassword();
134 EduStepicConnector.postAttempt(myTask, testsOutput.isSuccess(), login, password);