package org.dlangplugin.run;
import com.intellij.execution.ExecutionException;
import com.intellij.execution.ExecutionResult;
import com.intellij.execution.Executor;
import com.intellij.execution.configurations.CommandLineState;
import com.intellij.execution.configurations.CommandLineTokenizer;
import com.intellij.execution.configurations.GeneralCommandLine;
import com.intellij.execution.filters.TextConsoleBuilder;
import com.intellij.execution.filters.TextConsoleBuilderImpl;
import com.intellij.execution.process.OSProcessHandler;
import com.intellij.execution.process.ProcessHandler;
import com.intellij.execution.runners.ExecutionEnvironment;
import com.intellij.execution.runners.ProgramRunner;
import com.intellij.notification.Notification;
import com.intellij.notification.NotificationType;
import com.intellij.notification.Notifications;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import org.dlangplugin.config.DLangGeneralSettings;
import org.dlangplugin.run.exception.ModuleNotFoundException;
import org.dlangplugin.run.exception.NoDubExecutableException;
import org.jetbrains.annotations.NotNull;
import java.util.LinkedList;
import java.util.List;
public class DLangRunDubState extends CommandLineState {
private DLangRunDubConfiguration config;
private Executor executor;
protected DLangRunDubState(@NotNull ExecutionEnvironment environment, @NotNull DLangRunDubConfiguration config) {
super(environment);
this.config = config;
}
@NotNull
@Override
public ExecutionResult execute(@NotNull Executor executor, @NotNull ProgramRunner runner) throws ExecutionException {
TextConsoleBuilder consoleBuilder = new TextConsoleBuilderImpl(config.getProject());
setConsoleBuilder(consoleBuilder);
this.executor = executor;
return super.execute(executor, runner);
}
@NotNull
@Override
protected ProcessHandler startProcess() throws ExecutionException {
try {
GeneralCommandLine dubCommandLine = getExecutableCommandLine(config);
return new OSProcessHandler(dubCommandLine.createProcess(), dubCommandLine.getCommandLineString());
}
catch (ModuleNotFoundException e) {
throw new ExecutionException("Run configuration has no module selected.");
}
catch (NoDubExecutableException e) {
throw new ExecutionException("DUB executable is not specified.<a href='configure'>Configure</a> DUB settings");
}
catch (ExecutionException e) {
String message = e.getMessage();
boolean isEmpty = message.equals("Executable is not specified");
boolean notCorrect = message.startsWith("Cannot run program");
if (isEmpty || notCorrect) {
Notifications.Bus.notify(
new Notification("DUB run configuration", "DUB settings",
"DUB executable path is " + (isEmpty ? "empty" : "not specified correctly") +
"<br/><a href='configure'>Configure</a> output folder",
NotificationType.ERROR), config.getProject());
}
throw e;
}
}
/* Build command line to start DUB executable
*/
private GeneralCommandLine getExecutableCommandLine(DLangRunDubConfiguration config)
throws ModuleNotFoundException, NoDubExecutableException
{
Module module = config.getConfigurationModule().getModule();
if(module == null) {
throw new ModuleNotFoundException();
}
DLangGeneralSettings generalSettings = DLangGeneralSettings.getInstance(config.getProject());
if( StringUtil.isEmptyOrSpaces(generalSettings.getDubExecutablePath())) {
throw new NoDubExecutableException();
}
VirtualFile sourcesRoot = getSourceRoot(module);
GeneralCommandLine commandLine = new GeneralCommandLine();
commandLine.setExePath(generalSettings.getDubExecutablePath());
if( !StringUtil.isEmptyOrSpaces( config.getWorkingDir()) ) {
commandLine.withWorkDirectory(config.getWorkingDir());
}
else {
commandLine.withWorkDirectory(config.getProject().getBasePath());
}
//Add command line parameters
if( !config.isRunAfterBuild() ) {
commandLine.addParameter("build");
}
if( config.isQuiet() ) {
commandLine.addParameter("-q");
}
if( config.isVerbose() ) {
commandLine.addParameter("-v");
}
if( StringUtil.isEmptyOrSpaces(config.getAdditionalParams()) ) {
commandLine.addParameters(splitArguments(config.getAdditionalParams()));
}
return commandLine;
}
private String[] splitArguments(String arguments) {
if( StringUtil.isEmptyOrSpaces(arguments)) {
return new String[0];
}
List<String> argsLst = new LinkedList<String>();
CommandLineTokenizer tokenizer = new CommandLineTokenizer(arguments);
while(tokenizer.hasMoreTokens()) {
argsLst.add(tokenizer.nextToken());
}
if(argsLst.size()>0) {
return (String[]) argsLst.toArray();
}
else {
return new String[0];
}
}
private VirtualFile getSourceRoot(Module module) {
if (module != null) {
VirtualFile[] sourcesRoots = ModuleRootManager.getInstance(module).getSourceRoots();
if (sourcesRoots.length >= 1) {
return sourcesRoots[0];
}
}
return null;
}
}