@@ -169,7 +169,12 @@ pub fn run_command(cmd: &mut Command) -> anyhow::Result<()> {
169169 Ok ( ( ) )
170170}
171171
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 > {
173178 use anyhow:: Context ;
174179 use utils:: read2;
175180 let mut child = cmd
@@ -178,27 +183,28 @@ fn run_command_with_output(cmd: &mut Command) -> anyhow::Result<process::Output>
178183 . spawn ( )
179184 . with_context ( || format ! ( "failed to spawn process for cmd: {cmd:?}" ) ) ?;
180185
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 (
186192 child. stdout . take ( ) . unwrap ( ) ,
187193 child. stderr . take ( ) . unwrap ( ) ,
188194 & mut |is_stdout, buffer, _is_done| {
189195 // 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 ) {
191197 use std:: io:: Write ;
192198 if is_stdout {
193- stdout_writer. write_all ( & buffer[ stdout . len ( ) ..] ) . unwrap ( ) ;
199+ stdout_writer. write_all ( & buffer[ stdout_written ..] ) . unwrap ( ) ;
194200 } else {
195- stderr_writer. write_all ( & buffer[ stderr . len ( ) ..] ) . unwrap ( ) ;
201+ stderr_writer. write_all ( & buffer[ stderr_written ..] ) . unwrap ( ) ;
196202 }
197203 }
198204 if is_stdout {
199- stdout = buffer. clone ( ) ;
205+ stdout_written = buffer. len ( ) ;
200206 } else {
201- stderr = buffer. clone ( ) ;
207+ stderr_written = buffer. len ( ) ;
202208 }
203209 } ,
204210 ) ?;
@@ -215,42 +221,47 @@ fn run_command_with_output(cmd: &mut Command) -> anyhow::Result<process::Output>
215221}
216222
217223pub 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+ }
219228
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 < ( ) > {
220236 if !output. status . success ( ) {
221- return Err ( anyhow:: anyhow!(
237+ Err ( anyhow:: anyhow!(
222238 "expected success, got {}\n \n stderr={}\n \n stdout={}\n " ,
223239 output. status,
224240 String :: from_utf8_lossy( & output. stderr) ,
225241 String :: from_utf8_lossy( & output. stdout)
226- ) ) ;
242+ ) )
243+ } else {
244+ Ok ( ( ) )
227245 }
228-
229- Ok ( output)
230246}
231247
232248pub async fn async_command_output (
233249 mut cmd : tokio:: process:: Command ,
234250) -> anyhow:: Result < process:: Output > {
235251 use anyhow:: Context ;
236252
253+ log:: debug!( "Executing {:?}" , cmd) ;
254+
237255 let start = Instant :: now ( ) ;
238256 let child = cmd
239257 . stdout ( Stdio :: piped ( ) )
240258 . stderr ( Stdio :: piped ( ) )
241259 . spawn ( )
242260 . with_context ( || format ! ( "failed to spawn process for cmd: {cmd:?}" ) ) ?;
243261 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( ) ) ;
245263
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) ?;
254265
255266 Ok ( output)
256267}
0 commit comments