@@ -33,6 +33,45 @@ impl RocRefcounted for Command {
3333 }
3434}
3535
36+ impl std:: fmt:: Display for Command {
37+ fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
38+ let args_str = self
39+ . args
40+ . iter ( )
41+ . map ( |a| a. as_str ( ) )
42+ . collect :: < Vec < _ > > ( )
43+ . join ( " " ) ;
44+
45+ let envs_slice = self . envs . as_slice ( ) ;
46+ let envs_str = envs_slice
47+ . chunks ( 2 )
48+ . filter ( |c| c. len ( ) == 2 )
49+ . map ( |c| format ! ( "{}={}" , c[ 0 ] . as_str( ) , c[ 1 ] . as_str( ) ) )
50+ . collect :: < Vec < _ > > ( )
51+ . join ( " " ) ;
52+ let envs_part = if envs_str. is_empty ( ) {
53+ String :: new ( )
54+ } else {
55+ format ! ( ", envs: {envs_str}" )
56+ } ;
57+
58+ let clear_envs_part = if self . clear_envs != 0 {
59+ ", clear_envs: true"
60+ } else {
61+ ""
62+ } ;
63+
64+ write ! (
65+ f,
66+ "{{ cmd: {}, args: {}{}{} }}" ,
67+ self . program. as_str( ) ,
68+ args_str,
69+ envs_part,
70+ clear_envs_part,
71+ )
72+ }
73+ }
74+
3675impl Command {
3776 /// Convert to std::process::Command
3877 pub fn to_std_command ( & self ) -> std:: process:: Command {
@@ -86,26 +125,22 @@ impl RocRefcounted for CommandOutputSuccess {
86125 }
87126}
88127
89- /// Output when command fails (non-zero exit code)
90- /// Roc type: { exit_code : I32, stdout_utf8_lossy : Str, stderr_utf8_lossy : Str }
128+ /// Represents the record inside the Roc tag `FailedToGetExitCode({ command : Str, err : IOErr })`
91129/// Memory layout: Fields sorted by size descending, then alphabetically.
92- /// RocStr (24 bytes) > I32 (4 bytes), so: stderr_utf8_lossy (24), stdout_utf8_lossy (24), exit_code (4 )
130+ /// RocStr (24 bytes) > IOErr (??? bytes)
93131#[ derive( Clone , Debug ) ]
94132#[ repr( C ) ]
95- pub struct CommandOutputFailure {
96- pub stderr_utf8_lossy : RocStr , // offset 0 (24 bytes)
97- pub stdout_utf8_lossy : RocStr , // offset 24 (24 bytes)
98- pub exit_code : i32 , // offset 48 (4 bytes + padding)
133+ pub struct FailedToGetExitCodeContent {
134+ pub command : RocStr , // offset 0 (24 bytes)
135+ pub err : roc_io_error:: IOErr , // offset 24 (??? bytes)
99136}
100137
101- impl RocRefcounted for CommandOutputFailure {
138+ impl RocRefcounted for FailedToGetExitCodeContent {
102139 fn inc ( & mut self ) {
103- self . stderr_utf8_lossy . inc ( ) ;
104- self . stdout_utf8_lossy . inc ( ) ;
140+ self . command . inc ( ) ;
105141 }
106142 fn dec ( & mut self ) {
107- self . stderr_utf8_lossy . dec ( ) ;
108- self . stdout_utf8_lossy . dec ( ) ;
143+ self . command . dec ( ) ;
109144 }
110145 fn is_refcounted ( ) -> bool {
111146 true
@@ -119,16 +154,6 @@ fn bytes_to_roc_str_lossy(bytes: &[u8], roc_ops: &RocOps) -> RocStr {
119154 RocStr :: from_str ( s. as_ref ( ) , roc_ops)
120155}
121156
122- /// Result of executing a command for output
123- pub enum CommandOutputResult {
124- /// Command succeeded with exit code 0
125- Success ( CommandOutputSuccess ) ,
126- /// Command failed with non-zero exit code
127- NonZeroExit ( CommandOutputFailure ) ,
128- /// Command failed to execute
129- Error ( IOErr ) ,
130- }
131-
132157/// Execute command and return exit code
133158pub fn command_exec_exit_code ( cmd : & Command , roc_ops : & RocOps ) -> Result < i32 , IOErr > {
134159 match cmd. to_std_command ( ) . status ( ) {
@@ -140,29 +165,29 @@ pub fn command_exec_exit_code(cmd: &Command, roc_ops: &RocOps) -> Result<i32, IO
140165 }
141166}
142167
143- /// Execute command and capture stdout/stderr as UTF-8 strings.
144- /// Invalid UTF-8 sequences are replaced with the Unicode replacement character.
145- pub fn command_exec_output ( cmd : & Command , roc_ops : & RocOps ) -> CommandOutputResult {
146- match cmd. to_std_command ( ) . output ( ) {
147- Ok ( output) => {
148- let stdout_utf8 = bytes_to_roc_str_lossy ( & output. stdout , roc_ops) ;
149- let stderr_utf8_lossy = bytes_to_roc_str_lossy ( & output. stderr , roc_ops) ;
150-
151- match output. status . code ( ) {
152- Some ( 0 ) => CommandOutputResult :: Success ( CommandOutputSuccess {
153- stderr_utf8_lossy,
154- stdout_utf8,
155- } ) ,
156- Some ( exit_code) => CommandOutputResult :: NonZeroExit ( CommandOutputFailure {
157- stderr_utf8_lossy,
158- stdout_utf8_lossy : stdout_utf8,
159- exit_code,
160- } ) ,
161- None => CommandOutputResult :: Error (
162- IOErr :: new_other ( "Process was killed by signal" , roc_ops)
163- ) ,
164- }
165- }
166- Err ( e) => CommandOutputResult :: Error ( IOErr :: from_io_error ( & e, roc_ops) ) ,
167- }
168- }
168+ // // / Execute command and capture stdout/stderr as UTF-8 strings.
169+ // // / Invalid UTF-8 sequences are replaced with the Unicode replacement character.
170+ // pub fn command_exec_output(cmd: &Command, roc_ops: &RocOps) -> CommandOutputResult {
171+ // match cmd.to_std_command().output() {
172+ // Ok(output) => {
173+ // let stdout_utf8 = bytes_to_roc_str_lossy(&output.stdout, roc_ops);
174+ // let stderr_utf8_lossy = bytes_to_roc_str_lossy(&output.stderr, roc_ops);
175+
176+ // match output.status.code() {
177+ // Some(0) => CommandOutputResult::Success(CommandOutputSuccess {
178+ // stderr_utf8_lossy,
179+ // stdout_utf8,
180+ // }),
181+ // Some(exit_code) => CommandOutputResult::NonZeroExit(CommandOutputFailure {
182+ // stderr_utf8_lossy,
183+ // stdout_utf8_lossy: stdout_utf8,
184+ // exit_code,
185+ // }),
186+ // None => CommandOutputResult::Error(
187+ // IOErr::new_other("Process was killed by signal", roc_ops)
188+ // ),
189+ // }
190+ // }
191+ // Err(e) => CommandOutputResult::Error(IOErr::from_io_error(&e, roc_ops)),
192+ // }
193+ // }
0 commit comments