Skip to content

Commit ef4cf34

Browse files
committed
capture cmd stdout and stderr as well
1 parent 26ca805 commit ef4cf34

2 files changed

Lines changed: 50 additions & 22 deletions

File tree

src/api/cmd.rs

Lines changed: 44 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
1+
use crate::stdfiles;
12

2-
use super::{RhaiResult, io_err};
3+
use super::{io_err, RhaiResult};
34

45
use std::process::{Command, Stdio};
56
use std::sync::mpsc;
67
use std::thread;
78

89
use rhai::{Array, Engine, Module};
910

10-
1111
#[derive(Debug, Clone)]
1212
struct Cmd {
1313
args: Vec<String>,
1414
envs: Vec<(String, String)>,
1515
env_clear: bool,
16-
dir: Option<String>
16+
dir: Option<String>,
1717
}
1818

1919
impl Cmd {
@@ -22,7 +22,7 @@ impl Cmd {
2222
args: vec![s.into()],
2323
envs: vec![],
2424
env_clear: false,
25-
dir: None
25+
dir: None,
2626
}
2727
}
2828

@@ -36,7 +36,7 @@ impl Cmd {
3636
args,
3737
envs: vec![],
3838
env_clear: false,
39-
dir: None
39+
dir: None,
4040
})
4141
}
4242

@@ -69,8 +69,7 @@ impl Cmd {
6969
cmd.args(self.args.iter().skip(1));
7070

7171
if let Some(dir) = &self.dir {
72-
let abs_dir = dunce::canonicalize(dir)
73-
.map_err(io_err)?;
72+
let abs_dir = dunce::canonicalize(dir).map_err(io_err)?;
7473
cmd.current_dir(abs_dir);
7574
}
7675

@@ -90,6 +89,13 @@ impl Cmd {
9089
Ok(cmd)
9190
}
9291

92+
/*
93+
stdfiles::is_enabled()
94+
95+
stdfiles::STDOUT_FILE.lock().write_all(<bytes>)
96+
stdfiles::STDERR_FILE.lock().write_all(<bytes>)
97+
*/
98+
9399
pub fn execute(&mut self) -> RhaiResult<()> {
94100
let cmd_str = self.args.join(" ");
95101
if let Some(dir) = &self.dir {
@@ -100,8 +106,20 @@ impl Cmd {
100106

101107
let mut cmd = self.create_cmd()?;
102108

103-
let status = cmd.status()
104-
.expect("failed to execute");
109+
// If stdfiles enabled, pipe stdout and stderr so we can capture them
110+
let status = if stdfiles::is_enabled() {
111+
cmd.stdout(Stdio::piped());
112+
cmd.stderr(Stdio::piped());
113+
let output = cmd.output().expect("failed to execute");
114+
115+
// Write the captured stdout/stderr to our stdfiles
116+
stdfiles::STDOUT_FILE.write(&output.stdout);
117+
stdfiles::STDERR_FILE.write(&output.stderr);
118+
119+
output.status
120+
} else {
121+
cmd.status().expect("failed to execute")
122+
};
105123

106124
if status.success() {
107125
paint_ok!("execution {:?} successful", cmd_str);
@@ -118,13 +136,18 @@ impl Cmd {
118136

119137
let mut cmd = self.create_cmd()?;
120138
cmd.stdin(Stdio::inherit());
121-
cmd.stderr(Stdio::inherit());
139+
if !stdfiles::is_enabled() {
140+
cmd.stderr(Stdio::inherit());
141+
}
122142

123-
let output = cmd.output()
124-
.expect("failed to execute");
143+
let output = cmd.output().expect("failed to execute");
125144

126-
let out_str = String::from_utf8(output.stdout)
127-
.expect("output is not valid utf8");
145+
if stdfiles::is_enabled() {
146+
stdfiles::STDERR_FILE.write(&output.stderr);
147+
}
148+
149+
let out_str =
150+
String::from_utf8(output.stdout).expect("output is not valid utf8");
128151

129152
if output.status.success() {
130153
paint_ok!("execution {:?} successful", cmd_str);
@@ -139,8 +162,8 @@ impl Cmd {
139162
let mut cmds = Vec::with_capacity(cmds_input.len());
140163

141164
for cmd in cmds_input {
142-
let cmd: Self = cmd.try_cast()
143-
.ok_or(err!("only command struct allowed"))?;
165+
let cmd: Self =
166+
cmd.try_cast().ok_or(err!("only command struct allowed"))?;
144167
cmds.push(cmd);
145168
}
146169

@@ -153,17 +176,17 @@ impl Cmd {
153176
thread::spawn(move || {
154177
// spawn command
155178
let handle = thread::spawn(move || {
156-
cmd.execute()
157-
.expect("cmd failed");
179+
cmd.execute().expect("cmd failed");
158180
});
159181
sender.send(handle.join()).expect("sending failed");
160182
});
161183
}
162184

163185
for _ in 0..cmds_count {
164-
let r = recv.recv().expect("failed to receive message from threads");
186+
let r =
187+
recv.recv().expect("failed to receive message from threads");
165188
if let Err(e) = r {
166-
return Err(err!("Some command failed {:?}", e))
189+
return Err(err!("Some command failed {:?}", e));
167190
}
168191
}
169192

@@ -186,4 +209,4 @@ pub fn add(engine: &mut Engine) {
186209
.register_fn("execute", Cmd::execute)
187210
.register_fn("output", Cmd::output)
188211
.register_static_module("cmd", cmd_mod.into());
189-
}
212+
}

src/stdfiles.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use std::{
2-
io::Cursor,
2+
io::{Cursor, Write},
33
sync::{
44
atomic::{AtomicBool, Ordering},
55
Mutex, MutexGuard,
@@ -48,6 +48,11 @@ impl StdFile {
4848
std::mem::swap(&mut buf, &mut file.get_mut());
4949
buf
5050
}
51+
52+
pub fn write(&self, buf: &[u8]) {
53+
let mut file = self.file.lock().unwrap();
54+
file.write_all(buf).unwrap();
55+
}
5156
}
5257

5358
#[macro_export]

0 commit comments

Comments
 (0)