Skip to content

Commit e6579a3

Browse files
authoredFeb 2, 2018
Merge pull request #50 from ralfgrossklaus/MultiThreadedOutput
Added InputStreamCollector
2 parents 2a06f6e + 5a693d8 commit e6579a3

File tree

2 files changed

+90
-28
lines changed

2 files changed

+90
-28
lines changed
 

‎src/main/java/com/diffplug/gradle/CmdLine.java

+17-28
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,13 @@
1515
*/
1616
package com.diffplug.gradle;
1717

18-
import java.io.BufferedReader;
1918
import java.io.File;
2019
import java.io.IOException;
21-
import java.io.InputStreamReader;
22-
import java.nio.charset.Charset;
2320
import java.util.Arrays;
2421
import java.util.List;
2522

23+
import javax.management.RuntimeErrorException;
24+
2625
import org.apache.commons.io.FileUtils;
2726

2827
import com.diffplug.common.base.Throwing;
@@ -143,42 +142,32 @@ public static Result runCmd(File directory, String cmd, boolean echoCmd, boolean
143142
Process process = builder.start();
144143

145144
// wrap the process' input and output
146-
try (
147-
BufferedReader stdInput = new BufferedReader(new InputStreamReader(process.getInputStream(), Charset.defaultCharset()));
148-
BufferedReader stdError = new BufferedReader(new InputStreamReader(process.getErrorStream(), Charset.defaultCharset()));) {
149-
145+
try {
150146
if (echoCmd) {
151147
System.out.println("cmd>" + cmd);
152148
}
153149

154-
// dump the output
155-
ImmutableList.Builder<String> output = ImmutableList.builder();
156-
ImmutableList.Builder<String> error = ImmutableList.builder();
157-
158-
String line = null;
159-
while ((line = stdInput.readLine()) != null) {
160-
output.add(line);
161-
if (echoOutput) {
162-
System.out.println(line);
163-
}
164-
}
165-
166-
// dump the input
167-
while ((line = stdError.readLine()) != null) {
168-
error.add(line);
169-
if (echoOutput) {
170-
System.err.println(line);
171-
}
172-
}
150+
InputStreamCollector stdInputThread = new InputStreamCollector(process.getInputStream(), echoOutput ? System.out : null, null);
151+
stdInputThread.start();
152+
InputStreamCollector stdErrorThread = new InputStreamCollector(process.getErrorStream(), echoOutput ? System.err : null, null);
153+
stdErrorThread.start();
173154

174155
// check that the process exited correctly
175156
int exitValue = process.waitFor();
176-
if (exitValue != EXIT_VALUE_SUCCESS) {
157+
// then wait for threads collecting the output of thread
158+
stdInputThread.join();
159+
stdErrorThread.join();
160+
161+
if (stdInputThread.getException() != null) {
162+
throw new RuntimeException(stdInputThread.getException());
163+
} else if (stdErrorThread.getException() != null) {
164+
throw new RuntimeException(stdErrorThread.getException());
165+
} else if (exitValue != EXIT_VALUE_SUCCESS) {
177166
throw new RuntimeException("'" + cmd + "' exited with " + exitValue);
178167
}
179168

180169
// returns the result of this successful execution
181-
return new Result(directory, cmd, output.build(), error.build());
170+
return new Result(directory, cmd, stdInputThread.getOutput(), stdErrorThread.getOutput());
182171
} catch (InterruptedException e) {
183172
// this isn't expected, but it's possible
184173
throw new RuntimeException(e);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
/*
2+
* Copyright 2016 DiffPlug
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package com.diffplug.gradle;
17+
18+
import java.io.BufferedReader;
19+
import java.io.IOException;
20+
import java.io.InputStream;
21+
import java.io.InputStreamReader;
22+
import java.io.PrintStream;
23+
import java.nio.charset.Charset;
24+
import java.util.Objects;
25+
26+
import javax.annotation.Nonnull;
27+
import javax.annotation.Nullable;
28+
29+
import com.diffplug.common.collect.ImmutableList;
30+
31+
public class InputStreamCollector extends Thread {
32+
33+
private final InputStream iStream;
34+
35+
private final PrintStream pStream;
36+
37+
private final Charset charset;
38+
39+
private final ImmutableList.Builder<String> output;
40+
41+
private volatile IOException exception;
42+
43+
public InputStreamCollector(InputStream is, @Nullable PrintStream ps, @Nullable Charset cs) {
44+
this.iStream = Objects.requireNonNull(is);
45+
this.pStream = ps;
46+
this.charset = cs != null ? cs : Charset.defaultCharset();
47+
this.output = ImmutableList.builder();
48+
}
49+
50+
@Override
51+
public void run() {
52+
try (BufferedReader reader = new BufferedReader(new InputStreamReader(iStream, charset))) {
53+
String line = null;
54+
while ((line = reader.readLine()) != null) {
55+
output.add(line);
56+
if (pStream != null) {
57+
pStream.println(line);
58+
}
59+
}
60+
} catch (IOException ex) {
61+
this.exception = ex;
62+
}
63+
}
64+
65+
public ImmutableList<String> getOutput() {
66+
return output.build();
67+
}
68+
69+
public IOException getException() {
70+
return exception;
71+
}
72+
73+
}

0 commit comments

Comments
 (0)