package com.wix.nodejs;
import com.google.common.base.Charsets;
import com.intellij.execution.ExecutionException;
import com.intellij.execution.configurations.GeneralCommandLine;
import com.intellij.execution.process.*;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.SystemInfo;
import org.jetbrains.annotations.NotNull;
import java.io.File;
import java.util.concurrent.TimeUnit;
public final class NodeRunner {
private NodeRunner() {
}
private static final Logger LOG = Logger.getInstance(NodeRunner.class);
private static final int TIME_OUT = (int) TimeUnit.SECONDS.toMillis(120L);
/**
* @param cwd working directory
* @param node node interpreter path
* @param exe node executable to run
* @return command line to execute
*/
@NotNull
public static GeneralCommandLine createCommandLine(@NotNull String cwd, String node, String exe) {
GeneralCommandLine commandLine = new GeneralCommandLine();
if (!new File(cwd).exists() || !new File(exe).exists()) {
throw new IllegalArgumentException("path doesn't exist");
}
commandLine.setWorkDirectory(cwd);
if (SystemInfo.isWindows) {
commandLine.setExePath(exe);
} else {
if (!new File(node).exists()) {
throw new IllegalArgumentException("path doesn't exist");
}
commandLine.setExePath(node);
commandLine.addParameter(exe);
}
return commandLine;
}
/**
* @param commandLine command line to execute
* @param timeoutInMilliseconds timeout
* @return process output
* @throws ExecutionException
*/
@NotNull
public static ProcessOutput execute(@NotNull GeneralCommandLine commandLine, int timeoutInMilliseconds) throws ExecutionException {
LOG.info("Running node command: " + commandLine.getCommandLineString());
Process process = commandLine.createProcess();
OSProcessHandler processHandler = new ColoredProcessHandler(process, commandLine.getCommandLineString(), Charsets.UTF_8);
final ProcessOutput output = new ProcessOutput();
processHandler.addProcessListener(new ProcessAdapter() {
public void onTextAvailable(ProcessEvent event, Key outputType) {
if (outputType.equals(ProcessOutputTypes.STDERR)) {
output.appendStderr(event.getText());
} else if (!outputType.equals(ProcessOutputTypes.SYSTEM)) {
output.appendStdout(event.getText());
}
}
});
processHandler.startNotify();
if (processHandler.waitFor(timeoutInMilliseconds)) {
output.setExitCode(process.exitValue());
} else {
processHandler.destroyProcess();
output.setTimeout();
}
if (output.isTimeout()) {
throw new ExecutionException("Command '" + commandLine.getCommandLineString() + "' is timed out.");
}
return output;
}
}