Skip to content

Commit 8d70952

Browse files
authored
add piping extension to commands (#21)
1 parent c020c2f commit 8d70952

File tree

1 file changed

+72
-0
lines changed

1 file changed

+72
-0
lines changed

src/cmd.rs

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,16 @@ pub trait CommandBuilder {
206206

207207
/// Akin to [`Command::current_dir`].
208208
fn with_current_dir<P: AsRef<Path>>(self, path: P) -> Self;
209+
210+
/// Pipe `stdout` of _this_ into `next` command.
211+
fn pipe(self, next: Command) -> Result<Self>
212+
where
213+
Self: Sized;
214+
215+
/// Pipe `stderr` of _this_ into `next` command.
216+
fn pipe_stderr(self, next: Command) -> Result<Self>
217+
where
218+
Self: Sized;
209219
}
210220

211221
impl CommandBuilder for Command {
@@ -227,6 +237,32 @@ impl CommandBuilder for Command {
227237
self.current_dir(dir);
228238
self
229239
}
240+
241+
fn pipe(mut self, mut next: Command) -> Result<Self> {
242+
let cmd = self
243+
.stdout(Stdio::piped())
244+
.spawn()
245+
.map_err(|e| miette!("encountered error with command {}: {e}", self.cmd_str()))?;
246+
247+
let out = cmd.stdout.expect("piped so should exist");
248+
let stdin = Stdio::from(out);
249+
250+
next.stdin(stdin);
251+
Ok(next)
252+
}
253+
254+
fn pipe_stderr(mut self, mut next: Command) -> Result<Self> {
255+
let cmd = self
256+
.stderr(Stdio::piped())
257+
.spawn()
258+
.map_err(|e| miette!("encountered error with command {}: {e}", self.cmd_str()))?;
259+
260+
let out = cmd.stderr.expect("piped so should exist");
261+
let stdin = Stdio::from(out);
262+
263+
next.stdin(stdin);
264+
Ok(next)
265+
}
230266
}
231267

232268
/// Output [`Command`] as a text string, useful for debugging.
@@ -325,6 +361,7 @@ mod tests {
325361
let x = cmd!(watcmd: "foo").execute_str(Verbose).unwrap_err();
326362
assert_snapshot!("unknown-cmd", pretty_print_err(x));
327363
}
364+
328365
#[test]
329366
fn cmd_naming_with_env() {
330367
let x = cmd!(ls).with_env("YO", "zog").cmd_str();
@@ -338,4 +375,39 @@ mod tests {
338375
.cmd_str();
339376
assert_eq!(&x, "ls foo bar");
340377
}
378+
379+
#[test]
380+
fn cmd_piping() {
381+
let x = cmd!(ls)
382+
.pipe(cmd!(grep: Cargo.*))
383+
.unwrap()
384+
.execute_str(Quiet)
385+
.unwrap();
386+
let mut x = x.trim().split('\n').collect::<Vec<_>>();
387+
x.sort();
388+
389+
assert_eq!(&x, &["Cargo.lock", "Cargo.toml",]);
390+
391+
let x = cmd!(ls)
392+
.pipe(cmd!(grep: Cargo.*))
393+
.unwrap()
394+
.pipe(cmd!(grep: toml))
395+
.unwrap()
396+
.execute_str(Quiet)
397+
.unwrap();
398+
let mut x = x.trim().split('\n').collect::<Vec<_>>();
399+
x.sort();
400+
401+
assert_eq!(&x, &["Cargo.toml",]);
402+
403+
let x = cmd!(ls: foo)
404+
.pipe_stderr(cmd!(grep: foo))
405+
.unwrap()
406+
.execute_str(Quiet)
407+
.unwrap();
408+
let mut x = x.trim().split('\n').collect::<Vec<_>>();
409+
x.sort();
410+
411+
assert_eq!(&x, &["ls: cannot access 'foo': No such file or directory",]);
412+
}
341413
}

0 commit comments

Comments
 (0)