@@ -2,6 +2,7 @@ use crate::error::{Error, Result};
22use std:: ffi:: { OsStr , OsString } ;
33use std:: fmt:: Debug ;
44use std:: path:: PathBuf ;
5+ use std:: process:: Child ;
56use std:: time:: Duration ;
67use tracing:: debug;
78
@@ -140,32 +141,46 @@ impl CommandExecutor for std::process::Command {
140141 /// Execute the command and return the stdout and stderr
141142 fn execute ( & mut self ) -> Result < ( String , String ) > {
142143 debug ! ( "Executing command: {}" , self . to_command_string( ) ) ;
143- let output = self . output ( ) ?;
144-
145144 #[ cfg( not( target_os = "windows" ) ) ]
146- let stdout = String :: from_utf8_lossy ( & output. stdout ) . into_owned ( ) ;
147- #[ cfg( target_os = "windows" ) ]
148- let stdout = String :: new ( ) ;
145+ {
146+ let output = self . output ( ) ?;
147+ let stdout = String :: from_utf8_lossy ( & output. stdout ) . into_owned ( ) ;
148+ let stderr = String :: from_utf8_lossy ( & output. stderr ) . into_owned ( ) ;
149+
150+ debug ! (
151+ "Result: {}\n stdout: {}\n stderr: {}" ,
152+ output
153+ . status
154+ . code( )
155+ . map_or( "None" . to_string( ) , |c| c. to_string( ) ) ,
156+ stdout,
157+ stderr
158+ ) ;
159+
160+ if output. status . success ( ) {
161+ Ok ( ( stdout, stderr) )
162+ } else {
163+ Err ( Error :: CommandError { stdout, stderr } )
164+ }
165+ }
149166
150- #[ cfg( not( target_os = "windows" ) ) ]
151- let stderr = String :: from_utf8_lossy ( & output. stderr ) . into_owned ( ) ;
167+ // TODO: Processes can hang on Windows when attempting to get stdout/stderr using code
168+ // that works for Linux/MacOS; this implementation should be updated to retrieve the
169+ // values of stdout/stderr without hanging
152170 #[ cfg( target_os = "windows" ) ]
153- let stderr = String :: new ( ) ;
154-
155- debug ! (
156- "Result: {}\n stdout: {}\n stderr: {}" ,
157- output
158- . status
159- . code( )
160- . map_or( "None" . to_string( ) , |c| c. to_string( ) ) ,
161- stdout,
162- stderr
163- ) ;
164-
165- if output. status . success ( ) {
166- Ok ( ( stdout, stderr) )
167- } else {
168- Err ( Error :: CommandError { stdout, stderr } )
171+ {
172+ let mut process = self
173+ . stdout ( std:: process:: Stdio :: piped ( ) )
174+ . stderr ( std:: process:: Stdio :: piped ( ) )
175+ . spawn ( ) ?;
176+ let status = process. wait ( ) ?;
177+ let stdout = String :: new ( ) ;
178+ let stderr = String :: new ( ) ;
179+ if status. success ( ) {
180+ Ok ( ( stdout, stderr) )
181+ } else {
182+ Err ( Error :: CommandError { stdout, stderr } )
183+ }
169184 }
170185 }
171186}
@@ -183,11 +198,14 @@ impl AsyncCommandExecutor for tokio::process::Command {
183198
184199 #[ cfg( not( target_os = "windows" ) ) ]
185200 let stdout = String :: from_utf8_lossy ( & output. stdout ) . into_owned ( ) ;
186- #[ cfg( target_os = "windows" ) ]
187- let stdout = String :: new ( ) ;
188-
189201 #[ cfg( not( target_os = "windows" ) ) ]
190202 let stderr = String :: from_utf8_lossy ( & output. stderr ) . into_owned ( ) ;
203+
204+ // TODO: Processes can hang on Windows when attempting to get stdout/stderr using code
205+ // that works for Linux/MacOS; this implementation should be updated to retrieve the
206+ // values of stdout/stderr without hanging
207+ #[ cfg( target_os = "windows" ) ]
208+ let stdout = String :: new ( ) ;
191209 #[ cfg( target_os = "windows" ) ]
192210 let stderr = String :: new ( ) ;
193211
0 commit comments