Mercurial > hg4j
comparison test/org/tmatesoft/hg/test/ExecHelper.java @ 413:7f27122011c3
Support and respect for symbolic links and executable flag, with /bin/ls backed implementation to discover these
| author | Artem Tikhomirov <tikhomirov.artem@gmail.com> |
|---|---|
| date | Wed, 21 Mar 2012 20:40:28 +0100 |
| parents | b015f3918120 |
| children | 36853bb80a35 |
comparison
equal
deleted
inserted
replaced
| 406:d56ea1a2537a | 413:7f27122011c3 |
|---|---|
| 16 */ | 16 */ |
| 17 package org.tmatesoft.hg.test; | 17 package org.tmatesoft.hg.test; |
| 18 | 18 |
| 19 import java.io.File; | 19 import java.io.File; |
| 20 import java.io.IOException; | 20 import java.io.IOException; |
| 21 import java.io.InputStreamReader; | |
| 22 import java.nio.CharBuffer; | |
| 23 import java.util.ArrayList; | 21 import java.util.ArrayList; |
| 24 import java.util.Arrays; | 22 import java.util.List; |
| 25 import java.util.LinkedList; | |
| 26 import java.util.StringTokenizer; | 23 import java.util.StringTokenizer; |
| 24 | |
| 25 import org.tmatesoft.hg.internal.ProcessExecHelper; | |
| 27 | 26 |
| 28 /** | 27 /** |
| 29 * | 28 * |
| 30 * @author Artem Tikhomirov | 29 * @author Artem Tikhomirov |
| 31 * @author TMate Software Ltd. | 30 * @author TMate Software Ltd. |
| 32 */ | 31 */ |
| 33 public class ExecHelper { | 32 public class ExecHelper extends ProcessExecHelper { |
| 34 | 33 |
| 35 private final OutputParser parser; | 34 private final OutputParser parser; |
| 36 private File dir; | |
| 37 private int exitValue; | |
| 38 | 35 |
| 39 public ExecHelper(OutputParser outParser, File workingDir) { | 36 public ExecHelper(OutputParser outParser, File workingDir) { |
| 40 parser = outParser; | 37 parser = outParser; |
| 41 dir = workingDir; | 38 super.cwd(workingDir); |
| 42 } | 39 } |
| 43 | 40 |
| 44 public void run(String... cmd) throws IOException, InterruptedException { | 41 @Override |
| 45 ProcessBuilder pb = null; | 42 protected List<String> prepareCommand(List<String> cmd) { |
| 43 String commandName = cmd.get(0); | |
| 46 if (System.getProperty("os.name").startsWith("Windows")) { | 44 if (System.getProperty("os.name").startsWith("Windows")) { |
| 47 StringTokenizer st = new StringTokenizer(System.getenv("PATH"), ";"); | 45 StringTokenizer st = new StringTokenizer(System.getenv("PATH"), ";"); |
| 48 while (st.hasMoreTokens()) { | 46 while (st.hasMoreTokens()) { |
| 49 File pe = new File(st.nextToken()); | 47 File pe = new File(st.nextToken()); |
| 50 if (new File(pe, cmd[0] + ".exe").exists()) { | 48 if (new File(pe, commandName + ".exe").exists()) { |
| 51 break; | 49 return cmd; |
| 52 } | 50 } |
| 53 // PATHEXT controls precedence of .exe, .bat and .cmd files, usually .exe wins | 51 // PATHEXT controls precedence of .exe, .bat and .cmd files, usually .exe wins |
| 54 if (new File(pe, cmd[0] + ".bat").exists() || new File(pe, cmd[0] + ".cmd").exists()) { | 52 if (new File(pe, commandName + ".bat").exists() || new File(pe, commandName + ".cmd").exists()) { |
| 55 ArrayList<String> command = new ArrayList<String>(); | 53 ArrayList<String> command = new ArrayList<String>(); |
| 56 command.add("cmd.exe"); | 54 command.add("cmd.exe"); |
| 57 command.add("/C"); | 55 command.add("/C"); |
| 58 command.addAll(Arrays.asList(cmd)); | 56 command.addAll(cmd); |
| 59 pb = new ProcessBuilder(command); | 57 return command; |
| 60 break; | |
| 61 } | 58 } |
| 62 } | 59 } |
| 63 } | 60 } |
| 64 if (pb == null) { | 61 return super.prepareCommand(cmd); |
| 65 pb = new ProcessBuilder(cmd); | 62 } |
| 66 } | 63 |
| 67 Process p = pb.directory(dir).redirectErrorStream(true).start(); | 64 public void run(String... cmd) throws IOException, InterruptedException { |
| 68 InputStreamReader stdOut = new InputStreamReader(p.getInputStream()); | 65 CharSequence res = super.exec(cmd); |
| 69 LinkedList<CharBuffer> l = new LinkedList<CharBuffer>(); | |
| 70 int r = -1; | |
| 71 CharBuffer b = null; | |
| 72 do { | |
| 73 if (b == null || b.remaining() < b.capacity() / 3) { | |
| 74 b = CharBuffer.allocate(512); | |
| 75 l.add(b); | |
| 76 } | |
| 77 r = stdOut.read(b); | |
| 78 } while (r != -1); | |
| 79 int total = 0; | |
| 80 for (CharBuffer cb : l) { | |
| 81 total += cb.position(); | |
| 82 cb.flip(); | |
| 83 } | |
| 84 CharBuffer res = CharBuffer.allocate(total); | |
| 85 for (CharBuffer cb : l) { | |
| 86 res.put(cb); | |
| 87 } | |
| 88 res.flip(); | |
| 89 p.waitFor(); | |
| 90 exitValue = p.exitValue(); | |
| 91 parser.parse(res); | 66 parser.parse(res); |
| 92 } | 67 } |
| 93 | 68 |
| 94 public int getExitValue() { | 69 public int getExitValue() { |
| 95 return exitValue; | 70 return super.exitValue(); |
| 96 } | |
| 97 | |
| 98 public void cwd(File wd) { | |
| 99 dir = wd; | |
| 100 } | 71 } |
| 101 } | 72 } |
