@@ -169,7 +169,12 @@ pub fn run_command(cmd: &mut Command) -> anyhow::Result<()> {
169
169
Ok ( ( ) )
170
170
}
171
171
172
- fn run_command_with_output ( cmd : & mut Command ) -> anyhow:: Result < process:: Output > {
172
+ /// If `stream_output` is true, stdout/stderr of `cmd` should be streamed to stdout/stderr of the
173
+ /// current process, in addition to being captured.
174
+ fn run_command_with_output (
175
+ cmd : & mut Command ,
176
+ stream_output : bool ,
177
+ ) -> anyhow:: Result < process:: Output > {
173
178
use anyhow:: Context ;
174
179
use utils:: read2;
175
180
let mut child = cmd
@@ -178,27 +183,28 @@ fn run_command_with_output(cmd: &mut Command) -> anyhow::Result<process::Output>
178
183
. spawn ( )
179
184
. with_context ( || format ! ( "failed to spawn process for cmd: {cmd:?}" ) ) ?;
180
185
181
- let mut stdout = Vec :: new ( ) ;
182
- let mut stderr = Vec :: new ( ) ;
183
- let mut stdout_writer = std:: io:: LineWriter :: new ( std:: io:: stdout ( ) ) ;
184
- let mut stderr_writer = std:: io:: LineWriter :: new ( std:: io:: stderr ( ) ) ;
185
- read2:: read2 (
186
+ let mut stdout_writer = std:: io:: LineWriter :: new ( std:: io:: stdout ( ) . lock ( ) ) ;
187
+ let mut stderr_writer = std:: io:: LineWriter :: new ( std:: io:: stderr ( ) . lock ( ) ) ;
188
+
189
+ let mut stdout_written = 0 ;
190
+ let mut stderr_written = 0 ;
191
+ let ( stdout, stderr) = read2:: read2 (
186
192
child. stdout . take ( ) . unwrap ( ) ,
187
193
child. stderr . take ( ) . unwrap ( ) ,
188
194
& mut |is_stdout, buffer, _is_done| {
189
195
// Send output if trace logging is enabled
190
- if log:: log_enabled!( target: "raw_cargo_messages" , log:: Level :: Trace ) {
196
+ if stream_output || log:: log_enabled!( target: "raw_cargo_messages" , log:: Level :: Trace ) {
191
197
use std:: io:: Write ;
192
198
if is_stdout {
193
- stdout_writer. write_all ( & buffer[ stdout . len ( ) ..] ) . unwrap ( ) ;
199
+ stdout_writer. write_all ( & buffer[ stdout_written ..] ) . unwrap ( ) ;
194
200
} else {
195
- stderr_writer. write_all ( & buffer[ stderr . len ( ) ..] ) . unwrap ( ) ;
201
+ stderr_writer. write_all ( & buffer[ stderr_written ..] ) . unwrap ( ) ;
196
202
}
197
203
}
198
204
if is_stdout {
199
- stdout = buffer. clone ( ) ;
205
+ stdout_written = buffer. len ( ) ;
200
206
} else {
201
- stderr = buffer. clone ( ) ;
207
+ stderr_written = buffer. len ( ) ;
202
208
}
203
209
} ,
204
210
) ?;
@@ -215,42 +221,47 @@ fn run_command_with_output(cmd: &mut Command) -> anyhow::Result<process::Output>
215
221
}
216
222
217
223
pub fn command_output ( cmd : & mut Command ) -> anyhow:: Result < process:: Output > {
218
- let output = run_command_with_output ( cmd) ?;
224
+ let output = run_command_with_output ( cmd, false ) ?;
225
+ check_command_output ( & output) ?;
226
+ Ok ( output)
227
+ }
219
228
229
+ pub fn command_output_stream ( cmd : & mut Command ) -> anyhow:: Result < process:: Output > {
230
+ let output = run_command_with_output ( cmd, true ) ?;
231
+ check_command_output ( & output) ?;
232
+ Ok ( output)
233
+ }
234
+
235
+ fn check_command_output ( output : & process:: Output ) -> anyhow:: Result < ( ) > {
220
236
if !output. status . success ( ) {
221
- return Err ( anyhow:: anyhow!(
237
+ Err ( anyhow:: anyhow!(
222
238
"expected success, got {}\n \n stderr={}\n \n stdout={}\n " ,
223
239
output. status,
224
240
String :: from_utf8_lossy( & output. stderr) ,
225
241
String :: from_utf8_lossy( & output. stdout)
226
- ) ) ;
242
+ ) )
243
+ } else {
244
+ Ok ( ( ) )
227
245
}
228
-
229
- Ok ( output)
230
246
}
231
247
232
248
pub async fn async_command_output (
233
249
mut cmd : tokio:: process:: Command ,
234
250
) -> anyhow:: Result < process:: Output > {
235
251
use anyhow:: Context ;
236
252
253
+ log:: debug!( "Executing {:?}" , cmd) ;
254
+
237
255
let start = Instant :: now ( ) ;
238
256
let child = cmd
239
257
. stdout ( Stdio :: piped ( ) )
240
258
. stderr ( Stdio :: piped ( ) )
241
259
. spawn ( )
242
260
. with_context ( || format ! ( "failed to spawn process for cmd: {cmd:?}" ) ) ?;
243
261
let output = child. wait_with_output ( ) . await ?;
244
- log:: trace!( "command {cmd:?} took {} ms" , start. elapsed( ) . as_millis( ) ) ;
262
+ log:: trace!( "Command took {} ms" , start. elapsed( ) . as_millis( ) ) ;
245
263
246
- if !output. status . success ( ) {
247
- return Err ( anyhow:: anyhow!(
248
- "expected success, got {}\n \n stderr={}\n \n stdout={}\n " ,
249
- output. status,
250
- String :: from_utf8_lossy( & output. stderr) ,
251
- String :: from_utf8_lossy( & output. stdout)
252
- ) ) ;
253
- }
264
+ check_command_output ( & output) ?;
254
265
255
266
Ok ( output)
256
267
}
0 commit comments