protected void doRun( @NotNull final ExecutionEnvironment environment, @NotNull final Runnable startRunnable) { Boolean allowSkipRun = environment.getUserData(EXECUTION_SKIP_RUN); if (allowSkipRun != null && allowSkipRun) { environment .getProject() .getMessageBus() .syncPublisher(EXECUTION_TOPIC) .processNotStarted(environment.getExecutor().getId(), environment); } else { // important! Do not use DumbService.smartInvokeLater here because it depends on modality // state // and execution of startRunnable could be skipped if modality state check fails //noinspection SSBasedInspection SwingUtilities.invokeLater( () -> { if (!myProject.isDisposed()) { if (!Registry.is("dumb.aware.run.configurations")) { DumbService.getInstance(myProject).runWhenSmart(startRunnable); } else { try { DumbService.getInstance(myProject).setAlternativeResolveEnabled(true); startRunnable.run(); } catch (IndexNotReadyException ignored) { ExecutionUtil.handleExecutionError( environment, new ExecutionException("cannot start while indexing is in progress.")); } finally { DumbService.getInstance(myProject).setAlternativeResolveEnabled(false); } } } }); } }
private boolean checkRunConfiguration( Executor executor, Project project, RunnerAndConfigurationSettings configuration) { ExecutionTarget target = ExecutionTargetManager.getActiveTarget(project); if (!ExecutionTargetManager.canRun(configuration, target)) { ExecutionUtil.handleExecutionError( project, executor.getToolWindowId(), configuration.getConfiguration(), new ExecutionException( StringUtil.escapeXml( "Cannot run '" + configuration.getName() + "' on '" + target.getDisplayName() + "'"))); return false; } if (!RunManagerImpl.canRunConfiguration(configuration, executor) || configuration.isEditBeforeRun()) { if (!RunDialog.editConfiguration(project, configuration, "Edit configuration", executor)) { return false; } while (!RunManagerImpl.canRunConfiguration(configuration, executor)) { if (0 == Messages.showYesNoDialog( project, "Configuration is still incorrect. Do you want to edit it again?", "Change Configuration Settings", "Edit", "Continue Anyway", Messages.getErrorIcon())) { if (!RunDialog.editConfiguration( project, configuration, "Edit configuration", executor)) { break; } } else { break; } } } return true; }
private void runConfigurations( final Executor executor, final List<RunConfiguration> runConfigurations, final int index) { if (index >= runConfigurations.size()) { stopRunningMultirunConfiguration.doneStaringConfigurations(); return; } if (!stopRunningMultirunConfiguration.canContinueStartingConfigurations()) { stopRunningMultirunConfiguration.doneStaringConfigurations(); // don't start more configurations if user stopped the plugin work. return; } final RunConfiguration runConfiguration = runConfigurations.get(index); final Project project = runConfiguration.getProject(); final RunnerAndConfigurationSettings configuration = new RunnerAndConfigurationSettingsImpl( RunManagerImpl.getInstanceImpl(project), runConfiguration, false); boolean started = false; try { ProgramRunner runner = RunnerRegistry.getInstance().getRunner(executor.getId(), runConfiguration); if (runner == null) return; if (!checkRunConfiguration(executor, project, configuration)) return; runTriggers(executor, configuration); RunContentDescriptor runContentDescriptor = getRunContentDescriptor(runConfiguration, project); ExecutionEnvironment executionEnvironment = new ExecutionEnvironment( runner, DefaultExecutionTarget.INSTANCE, configuration, runContentDescriptor, project); runner.execute( executor, executionEnvironment, new ProgramRunner.Callback() { @SuppressWarnings("ConstantConditions") @Override public void processStarted(final RunContentDescriptor descriptor) { if (descriptor == null) { if (startOneByOne) { // start next configuration.. runConfigurations(executor, runConfigurations, index + 1); } return; } final ProcessHandler processHandler = descriptor.getProcessHandler(); if (processHandler != null) { processHandler.addProcessListener( new ProcessAdapter() { @SuppressWarnings("ConstantConditions") @Override public void startNotified(ProcessEvent processEvent) { Content content = descriptor.getAttachedContent(); if (content != null) { content.setIcon(descriptor.getIcon()); if (!stopRunningMultirunConfiguration .canContinueStartingConfigurations()) { // Multirun was stopped - destroy processes that are still starting up processHandler.destroyProcess(); if (!content.isPinned() && !startOneByOne) { // checks if not pinned, to avoid destroying already existed tab // checks if start one by one - no need to close the console tab, as // it's won't be shown // as other checks disallow starting it // content.getManager() can be null, if content is removed already as // part of destroy above if (content.getManager() != null) { content.getManager().removeContent(content, false); } } } else { // mark all current console tab as pinned content.setPinned(true); // mark running process tab with * content.setDisplayName(descriptor.getDisplayName() + "*"); } } } @Override public void processTerminated(final ProcessEvent processEvent) { onTermination(processEvent, true); } @Override public void processWillTerminate( ProcessEvent processEvent, boolean willBeDestroyed) { onTermination(processEvent, false); } private void onTermination( final ProcessEvent processEvent, final boolean terminated) { if (descriptor.getAttachedContent() == null) { return; } LaterInvocator.invokeLater( new Runnable() { @Override public void run() { final Content content = descriptor.getAttachedContent(); if (content == null) return; // exit code is 0 if the process completed successfully final boolean completedSuccessfully = (terminated && processEvent.getExitCode() == 0); if (hideSuccessProcess && completedSuccessfully) { // close the tab for the success process and exit - nothing else // could be done if (content.getManager() != null) { content.getManager().removeContent(content, false); return; } } if (!separateTabs && completedSuccessfully) { // un-pin the console tab if re-use is allowed and process // completed successfully, // so the tab could be re-used for other processes content.setPinned(false); } // remove the * used to identify running process content.setDisplayName(descriptor.getDisplayName()); // add the alert icon in case if process existed with non-0 status if (markFailedProcess && processEvent.getExitCode() != 0) { LaterInvocator.invokeLater( new Runnable() { @Override public void run() { content.setIcon( LayeredIcon.create( content.getIcon(), AllIcons.Nodes.TabAlert)); } }); } } }); } }); } stopRunningMultirunConfiguration.addProcess(project, processHandler); if (startOneByOne) { // start next configuration.. runConfigurations(executor, runConfigurations, index + 1); } } }); started = true; } catch (ExecutionException e) { ExecutionUtil.handleExecutionError( project, executor.getToolWindowId(), configuration.getConfiguration(), e); } finally { // start the next one if (!startOneByOne) { runConfigurations(executor, runConfigurations, index + 1); } else if (!started) { // failed to start current, means the chain is broken runConfigurations(executor, runConfigurations, index + 1); } } }
@Override public void startRunProfile( @NotNull final RunProfileStarter starter, @NotNull final RunProfileState state, @NotNull final ExecutionEnvironment environment) { final Project project = environment.getProject(); RunContentDescriptor reuseContent = getContentManager().getReuseContent(environment); if (reuseContent != null) { reuseContent.setExecutionId(environment.getExecutionId()); environment.setContentToReuse(reuseContent); } final Executor executor = environment.getExecutor(); project .getMessageBus() .syncPublisher(EXECUTION_TOPIC) .processStartScheduled(executor.getId(), environment); Runnable startRunnable; startRunnable = () -> { if (project.isDisposed()) { return; } RunProfile profile = environment.getRunProfile(); boolean started = false; try { project .getMessageBus() .syncPublisher(EXECUTION_TOPIC) .processStarting(executor.getId(), environment); final RunContentDescriptor descriptor = starter.execute(state, environment); if (descriptor != null) { final Trinity<RunContentDescriptor, RunnerAndConfigurationSettings, Executor> trinity = Trinity.create( descriptor, environment.getRunnerAndConfigurationSettings(), executor); myRunningConfigurations.add(trinity); Disposer.register(descriptor, () -> myRunningConfigurations.remove(trinity)); getContentManager() .showRunContent(executor, descriptor, environment.getContentToReuse()); final ProcessHandler processHandler = descriptor.getProcessHandler(); if (processHandler != null) { if (!processHandler.isStartNotified()) { processHandler.startNotify(); } project .getMessageBus() .syncPublisher(EXECUTION_TOPIC) .processStarted(executor.getId(), environment, processHandler); started = true; ProcessExecutionListener listener = new ProcessExecutionListener( project, executor.getId(), environment, processHandler, descriptor); processHandler.addProcessListener(listener); // Since we cannot guarantee that the listener is added before process handled is // start notified, // we have to make sure the process termination events are delivered to the clients. // Here we check the current process state and manually deliver events, while // the ProcessExecutionListener guarantees each such event is only delivered once // either by this code, or by the ProcessHandler. boolean terminating = processHandler.isProcessTerminating(); boolean terminated = processHandler.isProcessTerminated(); if (terminating || terminated) { listener.processWillTerminate( new ProcessEvent(processHandler), false /*doesn't matter*/); if (terminated) { //noinspection ConstantConditions int exitCode = processHandler.getExitCode(); listener.processTerminated(new ProcessEvent(processHandler, exitCode)); } } } environment.setContentToReuse(descriptor); } } catch (ProcessCanceledException e) { LOG.info(e); } catch (ExecutionException e) { ExecutionUtil.handleExecutionError(project, executor.getToolWindowId(), profile, e); LOG.info(e); } finally { if (!started) { project .getMessageBus() .syncPublisher(EXECUTION_TOPIC) .processNotStarted(executor.getId(), environment); } } }; if (ApplicationManager.getApplication().isUnitTestMode() && !myForceCompilationInTests) { startRunnable.run(); } else { compileAndRun( () -> TransactionGuard.submitTransaction(project, startRunnable), environment, state, () -> { if (!project.isDisposed()) { project .getMessageBus() .syncPublisher(EXECUTION_TOPIC) .processNotStarted(executor.getId(), environment); } }); } }
public static void executeConfiguration( @NotNull ExecutionEnvironment environment, boolean showSettings, boolean assignNewId) { if (ExecutorRegistry.getInstance().isStarting(environment)) { return; } RunnerAndConfigurationSettings runnerAndConfigurationSettings = environment.getRunnerAndConfigurationSettings(); if (runnerAndConfigurationSettings != null) { if (!ExecutionTargetManager.canRun(environment)) { ExecutionUtil.handleExecutionError( environment, new ExecutionException( StringUtil.escapeXml( "Cannot run '" + environment.getRunProfile().getName() + "' on '" + environment.getExecutionTarget().getDisplayName() + "'"))); return; } if (!RunManagerImpl.canRunConfiguration(environment) || (showSettings && runnerAndConfigurationSettings.isEditBeforeRun())) { if (!RunDialog.editConfiguration(environment, "Edit configuration")) { return; } while (!RunManagerImpl.canRunConfiguration(environment)) { if (Messages.YES == Messages.showYesNoDialog( environment.getProject(), "Configuration is still incorrect. Do you want to edit it again?", "Change Configuration Settings", "Edit", "Continue Anyway", Messages.getErrorIcon())) { if (!RunDialog.editConfiguration(environment, "Edit configuration")) { return; } } else { break; } } } ConfigurationType configurationType = runnerAndConfigurationSettings.getType(); if (configurationType != null) { UsageTrigger.trigger( "execute." + ConvertUsagesUtil.ensureProperKey(configurationType.getId()) + "." + environment.getExecutor().getId()); } } try { if (assignNewId) { environment.assignNewExecutionId(); } environment.getRunner().execute(environment); } catch (ExecutionException e) { String name = runnerAndConfigurationSettings != null ? runnerAndConfigurationSettings.getName() : null; if (name == null) { name = environment.getRunProfile().getName(); } if (name == null && environment.getContentToReuse() != null) { name = environment.getContentToReuse().getDisplayName(); } if (name == null) { name = "<Unknown>"; } ExecutionUtil.handleExecutionError( environment.getProject(), environment.getExecutor().getToolWindowId(), name, e); } }