(command_with_args: &[&str], capture: bool)
| 94 | } |
| 95 | |
| 96 | fn exec_impl(command_with_args: &[&str], capture: bool) -> Result<String> { |
| 97 | let (command, args) = match command_with_args { |
| 98 | [head, tail @ ..] => (head, tail), |
| 99 | _ => return Err(err!("No command passed.")), |
| 100 | }; |
| 101 | |
| 102 | eprintln!("Starting '{}'...", command_with_args.join(" ")); |
| 103 | |
| 104 | let mut handle = process::Command::new(command); |
| 105 | |
| 106 | if capture { |
| 107 | handle |
| 108 | .stdout(Stdio::piped()) |
| 109 | .stderr(Stdio::piped()); |
| 110 | } |
| 111 | |
| 112 | let mut errs = |
| 113 | ErrorStash::new(|| format!("Failed to run {command_with_args:?}")); |
| 114 | |
| 115 | let process = try2!(handle |
| 116 | .args(args) |
| 117 | .spawn() |
| 118 | .or_wrap_with::<Stashable>(|| "Failed to start process") |
| 119 | .and_then(|process| process.wait_with_output().or_wrap()) |
| 120 | .or_stash(&mut errs)); |
| 121 | |
| 122 | match process.status.code() { |
| 123 | Some(0) => (), |
| 124 | Some(c) => { |
| 125 | errs.push(format!("Status code was {c}")); |
| 126 | } |
| 127 | None => { |
| 128 | errs.push("No status code (terminated by signal?)"); |
| 129 | } |
| 130 | }; |
| 131 | |
| 132 | let stdout = str_or_stash(&process.stdout, &mut errs); |
| 133 | let stderr = str_or_stash(&process.stderr, &mut errs); |
| 134 | |
| 135 | if !errs.is_empty() && capture { |
| 136 | if !stdout.is_empty() { |
| 137 | errs.push(format!("STDOUT:\n{stdout}")); |
| 138 | } |
| 139 | |
| 140 | if !stderr.is_empty() { |
| 141 | errs.push(format!("STDERR:\n{stderr}")); |
| 142 | } |
| 143 | } |
| 144 | |
| 145 | errs.into_result()?; |
| 146 | |
| 147 | Ok(stdout.to_owned()) |
| 148 | } |
| 149 | |
| 150 | fn str_or_stash<'a, F, M>( |
| 151 | bytes: &'a [u8], |
no test coverage detected