Skip to content

Commit 2edffe4

Browse files
committed
get rid of CmdInternal
1 parent dd1e0d4 commit 2edffe4

File tree

5 files changed

+289
-260
lines changed

5 files changed

+289
-260
lines changed

crates/roc_command/src/lib.rs

Lines changed: 73 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
3675
impl 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
133158
pub 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+
// }

examples/command.roc

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,23 +7,23 @@ import pf.Cmd
77

88
main! = |_args| {
99
# Simplest way to execute a command (prints to your terminal).
10-
Cmd.exec!("echo", ["Hello"])?
10+
#Cmd.exec!("echo", ["Hello"])?
1111

1212
# To execute and capture the output (stdout and stderr) without inheriting your terminal.
13-
cmd_output =
14-
Cmd.new("echo")
15-
.args(["Hi"])
16-
.exec_output!()?
13+
#cmd_output =
14+
# Cmd.new("echo")
15+
# .args(["Hi"])
16+
# .exec_output!()?
1717

18-
Stdout.line!("${Str.inspect(cmd_output)}")?
18+
#Stdout.line!("${Str.inspect(cmd_output)}")?
1919

2020
# To run a command with environment variables.
21-
Cmd.new("env")
22-
.clear_envs() # You probably don't need to clear all other environment variables, this is just an example.
23-
.env("FOO", "BAR")
24-
.envs([("BAZ", "DUCK"), ("XYZ", "ABC")]) # Set multiple environment variables at once with `envs`
25-
.args(["-v"])
26-
.exec_cmd!()?
21+
#Cmd.new("env")
22+
# .clear_envs() # You probably don't need to clear all other environment variables, this is just an example.
23+
# .env("FOO", "BAR")
24+
# .envs([("BAZ", "DUCK"), ("XYZ", "ABC")]) # Set multiple environment variables at once with `envs`
25+
# .args(["-v"])
26+
# .exec_cmd!()?
2727

2828
# To execute and just get the exit code (prints to your terminal).
2929
# Prefer using `exec!` or `exec_cmd!`.

0 commit comments

Comments
 (0)