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 } |