From 084e9d4f5f012180cf9ed3a3f197fd7cc4d0c884 Mon Sep 17 00:00:00 2001 From: Konstantin Kolosovsky Date: Thu, 3 Apr 2014 22:49:01 +0400 Subject: [PATCH] svn: terminal: Implemented running svn commands using "cmd /c" and redirecting output to separate file for Windows (so we do not need separately process terminal escape sequences in process output) --- .../svn/commandLine/TerminalExecutor.java | 22 +++-- .../svn/commandLine/WinTerminalExecutor.java | 82 +++++++++++++++++++ .../WinTerminalProcessHandler.java | 5 ++ 3 files changed, 101 insertions(+), 8 deletions(-) diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/TerminalExecutor.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/TerminalExecutor.java index 259388ba6074..f23a9e092ff1 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/TerminalExecutor.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/TerminalExecutor.java @@ -18,10 +18,7 @@ package org.jetbrains.idea.svn.commandLine; import com.intellij.execution.CommandLineUtil; import com.intellij.execution.ExecutionException; import com.intellij.execution.process.OSProcessHandler; -import com.intellij.openapi.util.SystemInfo; -import com.intellij.openapi.util.text.StringUtil; import com.intellij.util.ArrayUtil; -import com.intellij.util.Function; import com.intellij.util.containers.ContainerUtil; import com.pty4j.PtyProcess; import org.jetbrains.annotations.NonNls; @@ -63,12 +60,21 @@ public class TerminalExecutor extends CommandExecutor { @NotNull @Override protected Process createProcess() throws ExecutionException { - List parameters = - escapeArguments(CommandLineUtil.toCommandLine(myCommandLine.getExePath(), myCommandLine.getParametersList().getList())); + List parameters = escapeArguments(buildParameters()); + return createProcess(parameters); + } + + @NotNull + protected List buildParameters() { + return CommandLineUtil.toCommandLine(myCommandLine.getExePath(), myCommandLine.getParametersList().getList()); + } + + @NotNull + protected Process createProcess(@NotNull List parameters) throws ExecutionException { try { - return PtyProcess - .exec(ArrayUtil.toStringArray(parameters), myCommandLine.getEnvironment(), myCommandLine.getWorkDirectory().getAbsolutePath()); + return PtyProcess.exec(ArrayUtil.toStringArray(parameters), myCommandLine.getEnvironment(), + myCommandLine.getWorkDirectory().getAbsolutePath()); } catch (IOException e) { throw new ExecutionException(e); @@ -79,7 +85,7 @@ public class TerminalExecutor extends CommandExecutor { public void logCommand() { super.logCommand(); - LOG.info("Terminal output " + ((TerminalProcessHandler) myHandler).getTerminalOutput()); + LOG.info("Terminal output " + ((TerminalProcessHandler)myHandler).getTerminalOutput()); } @NotNull diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/WinTerminalExecutor.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/WinTerminalExecutor.java index 817d1bc20809..c5002a2dd852 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/WinTerminalExecutor.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/WinTerminalExecutor.java @@ -15,14 +15,19 @@ */ package org.jetbrains.idea.svn.commandLine; +import com.intellij.execution.ExecutionException; import com.intellij.execution.process.OSProcessHandler; +import com.intellij.execution.process.ProcessWrapper; +import com.intellij.execution.util.ExecUtil; import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.util.text.StringUtil; import com.intellij.util.Function; import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import java.io.*; import java.util.List; /** @@ -42,6 +47,9 @@ public class WinTerminalExecutor extends TerminalExecutor { } } + @Nullable private File myRedirectFile; + @Nullable private FileInputStream myRedirectStream; + public WinTerminalExecutor(@NotNull @NonNls String exePath, @NotNull Command command) { super(exePath, command); } @@ -52,6 +60,80 @@ public class WinTerminalExecutor extends TerminalExecutor { return new WinTerminalProcessHandler(myProcess); } + @Override + protected void beforeCreateProcess() throws SvnBindException { + super.beforeCreateProcess(); + + createRedirectFile(); + } + + private void createRedirectFile() throws SvnBindException { + myRedirectFile = createTempFile("terminal-output", ""); + + try { + myRedirectStream = new FileInputStream(myRedirectFile); + } + catch (FileNotFoundException e) { + throw new SvnBindException(e); + } + } + + @Override + protected void cleanup() { + super.cleanup(); + + deleteRedirectFile(); + } + + private void deleteRedirectFile() { + if (myRedirectStream != null) { + try { + myRedirectStream.close(); + } + catch (IOException e) { + LOG.info(e); + } + } + + deleteTempFile(myRedirectFile); + } + + @NotNull + @Override + protected Process createProcess() throws ExecutionException { + checkRedirectFile(); + + List parameters = escapeArguments(buildParameters()); + parameters.add(0, ExecUtil.getWindowsShellName()); + parameters.add(1, "/c"); + parameters.add(">>"); + //noinspection ConstantConditions + parameters.add(quote(myRedirectFile.getAbsolutePath())); + + Process process = createProcess(parameters); + + return new ProcessWrapper(process) { + @Override + public InputStream getInputStream() { + return myRedirectStream; + } + + @Override + public InputStream getErrorStream() { + return getOriginalProcess().getInputStream(); + } + }; + } + + private void checkRedirectFile() { + if (myRedirectFile == null) { + throw new IllegalStateException("No redirect file found"); + } + if (myRedirectStream == null) { + throw new IllegalStateException("No redirect stream found"); + } + } + /** * TODO: Identify pty4j quoting requirements for Windows and implement accordingly */ diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/WinTerminalProcessHandler.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/WinTerminalProcessHandler.java index f9911a7a55b5..f7657023ff41 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/WinTerminalProcessHandler.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/WinTerminalProcessHandler.java @@ -31,6 +31,11 @@ public class WinTerminalProcessHandler extends TerminalProcessHandler { super(process); } + @Override + protected boolean processHasSeparateErrorStream() { + return true; + } + @NotNull @Override protected String filterCombinedText(@NotNull String currentLine) {