20
20
import com .android .tools .build .bundletool .model .exceptions .CommandExecutionException ;
21
21
import com .android .tools .build .bundletool .model .utils .files .BufferedIo ;
22
22
import com .google .common .collect .ImmutableList ;
23
- import com .google .common .io .CharStreams ;
23
+ import com .google .common .io .LineReader ;
24
24
import java .io .BufferedReader ;
25
25
import java .io .IOException ;
26
+ import java .io .InputStream ;
27
+ import java .io .PrintStream ;
26
28
import java .io .UncheckedIOException ;
29
+ import java .lang .ProcessBuilder .Redirect ;
30
+ import java .util .ArrayList ;
31
+ import java .util .List ;
27
32
28
33
/** Helper to execute native commands. */
29
34
public final class DefaultCommandExecutor implements CommandExecutor {
30
35
31
36
@ Override
32
37
public void execute (ImmutableList <String > command , CommandOptions options ) {
33
- executeImpl (command , options );
38
+ ImmutableList <String > capturedOutput = executeImpl (command , options );
39
+ printOutput (capturedOutput , System .out );
34
40
}
35
41
36
42
@ Override
37
43
public ImmutableList <String > executeAndCapture (
38
44
ImmutableList <String > command , CommandOptions options ) {
39
- return captureOutput ( executeImpl (command , options ) );
45
+ return executeImpl (command , options );
40
46
}
41
47
42
- private static Process executeImpl (ImmutableList <String > command , CommandOptions options ) {
48
+ private static ImmutableList <String > executeImpl (
49
+ ImmutableList <String > command , CommandOptions options ) {
43
50
try {
44
- Process process = new ProcessBuilder (command ).redirectErrorStream (true ).start ();
51
+ Process process =
52
+ new ProcessBuilder (command )
53
+ .redirectOutput (Redirect .PIPE )
54
+ .redirectErrorStream (true )
55
+ .start ();
56
+
57
+ OutputCapturer outputCapturer = OutputCapturer .startCapture (process .getInputStream ());
58
+
45
59
if (!process .waitFor (options .getTimeout ().toMillis (), MILLISECONDS )) {
46
- printOutput (process );
60
+ printOutput (outputCapturer . getOutput ( /* interrupt= */ true ), System . err );
47
61
throw CommandExecutionException .builder ()
48
62
.withInternalMessage ("Command timed out: %s" , command )
49
63
.build ();
50
64
}
51
65
if (process .exitValue () != 0 ) {
52
- printOutput (process );
66
+ printOutput (outputCapturer . getOutput ( /* interrupt= */ true ), System . err );
53
67
throw CommandExecutionException .builder ()
54
68
.withInternalMessage (
55
69
"Command '%s' didn't terminate successfully (exit code: %d). Check the logs." ,
56
70
command , process .exitValue ())
57
71
.build ();
58
72
}
59
- return process ;
73
+ return outputCapturer . getOutput ( /* interrupt= */ false ) ;
60
74
} catch (IOException | InterruptedException e ) {
61
75
throw CommandExecutionException .builder ()
62
76
.withInternalMessage ("Error when executing command: %s" , command )
@@ -65,22 +79,48 @@ private static Process executeImpl(ImmutableList<String> command, CommandOptions
65
79
}
66
80
}
67
81
68
- private static ImmutableList <String > captureOutput (Process process ) {
69
- try (BufferedReader outputReader = BufferedIo .reader (process .getInputStream ())) {
70
- return ImmutableList .copyOf (CharStreams .readLines (outputReader ));
71
- } catch (IOException e ) {
72
- throw new UncheckedIOException (e );
82
+ static class OutputCapturer {
83
+ private final Thread thread ;
84
+ private final List <String > output ;
85
+ private final InputStream stream ;
86
+
87
+ private OutputCapturer (Thread thread , List <String > output , InputStream stream ) {
88
+ this .thread = thread ;
89
+ this .output = output ;
90
+ this .stream = stream ;
73
91
}
74
- }
75
92
76
- private static void printOutput (Process process ) {
77
- try (BufferedReader outputReader = BufferedIo .reader (process .getInputStream ())) {
78
- String line ;
79
- while ((line = outputReader .readLine ()) != null ) {
80
- System .err .println (line );
93
+ static OutputCapturer startCapture (InputStream stream ) {
94
+ List <String > output = new ArrayList <>();
95
+ Thread thread =
96
+ new Thread (
97
+ () -> {
98
+ try (BufferedReader reader = BufferedIo .reader (stream )) {
99
+ LineReader lineReader = new LineReader (reader );
100
+ String line ;
101
+ while ((line = lineReader .readLine ()) != null ) {
102
+ output .add (line );
103
+ }
104
+ } catch (IOException e ) {
105
+ throw new UncheckedIOException (e );
106
+ }
107
+ });
108
+ thread .start ();
109
+ return new OutputCapturer (thread , output , stream );
110
+ }
111
+
112
+ ImmutableList <String > getOutput (boolean interrupt ) throws InterruptedException , IOException {
113
+ if (interrupt ) {
114
+ stream .close ();
81
115
}
82
- } catch (IOException e ) {
83
- System .err .println ("Error when printing output of command:" + e .getMessage ());
116
+ thread .join ();
117
+ return ImmutableList .copyOf (output );
118
+ }
119
+ }
120
+
121
+ private static void printOutput (List <String > output , PrintStream stream ) {
122
+ for (String line : output ) {
123
+ stream .println (line );
84
124
}
85
125
}
86
126
}
0 commit comments